2013-04-04 117 views
1

我有一個使用另一個軟件包(「net.contentobjects.jnotify」)的軟件包(「com.elsten.bliss.platform」)。 net.contentobjects.jnotify加載本地庫來完成它的工作,這是由碎片提供的。本機代碼加載到靜態類初始化類內部net.contentobjects.jnotify包內:更新客戶端軟件包時未更新的軟件包中出現UnsatisfiedLinkError

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使用 - 看來這種方法重新加載類。

我該如何避免這種情況?

回答

1

有趣的是,如果調用兩次該代碼不應引發異常;爲java.lang.Runtime#loadLibrary()的Javadoc指出

如果這種方法被稱爲比同庫名一次,第二次和後續調用將被忽略。

所以,可能還有更多。你有沒有嘗試在MANIFEST.MF的Bundle-SymbolicName條目中設置singleton屬性?

+0

剛剛嘗試過...似乎在工作,沒有錯誤信息。我的文件通知仍然無法正常工作,但我認爲這肯定是一個不同的問題。關於此指令除http://wiki.osgi.org/wiki/Bundle-SymbolicName之外還有什麼更多指導? – 2013-04-04 14:23:49

+0

默認情況下,可以在OSGi系統/框架/容器f.e中安裝並運行一個軟件包的多個實例。如果有一個版本的多個。這個屬性表明一個bundle是一個singleton,即任何時候只能有一個* active *。可以安裝其他人,但只能有一個活動。 – 2013-04-04 14:40:35

+0

我認爲這個庫可以通過其絕對文件系統名稱或類似名稱來識別......所以不同的版本會有不同的路徑,並且多個文件將作爲本地庫加載。也許這只是libx.so的名字? – 2013-04-04 14:43:13