我有一个使用另一个包(“com.elsten.bliss.platform
”)的包(“net.contentobjects.jnotify
”)。 net.contentobjects.jnotify
加载本机库来完成其工作,这些库由片段提供。本机代码加载到net.contentobjects.jnotify
包中的类内的静态类初始化器中:
static
{
System.loadLibrary("jnotify");
int res = nativeInit();
if (res != 0)
{
throw new RuntimeException("Error initializing fshook_inotify library. linux error code #" + res + ", man errno for more info");
}
init();
}
我可以开始和停止com.elsten.bliss.platform
,它似乎工作正常。更新com.elsten.bliss.platform
时会出现问题。当我更新时,我得到:
2013-04-04 11:58:20,356 [ERROR] Couldn't initialise JNotify: java.lang.UnsatisfiedLinkError: Native Library /home/gravelld/eclipse-workspaces/bliss/net.contentobjects.jnotify.linux.amd64/lib/libjnotify.so already loaded in another classloader (JnotifyFileSystemObserver.java:53, thread platformExecutor)
java.lang.UnsatisfiedLinkError: Native Library /home/gravelld/eclipse-workspaces/bliss/net.contentobjects.jnotify.linux.amd64/lib/libjnotify.so already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at net.contentobjects.jnotify.linux.JNotify_linux.<clinit>(JNotify_linux.java:48)
at net.contentobjects.jnotify.linux.JNotifyAdapterLinux.<init>(JNotifyAdapterLinux.java:76)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at java.lang.Class.newInstance0(Class.java:374)
at java.lang.Class.newInstance(Class.java:327)
at net.contentobjects.jnotify.JNotify.<clinit>(JNotify.java:75)
at com.elsten.bliss.platform.storage.file.JnotifyFileSystemObserver.startWatching(JnotifyFileSystemObserver.java:43)
at com.elsten.bliss.platform.storage.file.NotifyFilesAtStartFileSystemObserver.start(NotifyFilesAtStartFileSystemObserver.java:117)
at com.elsten.bliss.platform2.PlumbedStorageSubsystem.start(PlumbedStorageSubsystem.java:69)
at com.elsten.bliss.client.impl.ConfigurationClientImpl$3.doRun(ConfigurationClientImpl.java:337)
at com.elsten.util.CatchThrowableRunnable.run(CatchThrowableRunnable.java:23)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:679)
好的,所以我知道你只能由一个类加载器加载任何一个本机库。但在这种情况下,为什么有多个类加载器呢? net.contentobjects.jnotify
未更新,因此我认为现有的类应继续使用并由JnotifyFileSystemObserver.startWatching
使用 - 看来此方法正在重新加载类。
我该如何避免这种情况?
答案 0 :(得分:1)
有趣的是,如果两次调用该代码不应该引发异常; java.lang.Runtime#loadLibrary()
的javadoc表示
如果使用相同的库名称多次调用此方法,则忽略第二次和后续调用。
所以,可能会有更多。您是否尝试在MANIFEST.MF的Bundle-SymbolicName条目中设置singleton属性?