【问题标题】:UnsatisfiedLinkError in non-updated bundle when updating a client bundle更新客户端捆绑包时未更新捆绑包中的 UnsatisfiedLinkError
【发布时间】:2013-04-04 11:17:31
【问题描述】:

我有一个使用另一个包 ("net.contentobjects.jnotify") 的包 ("com.elsten.bliss.platform")。 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 使用 - 看来这个方法正在重新加载类。

如何避免这种情况?

【问题讨论】:

    标签: java osgi


    【解决方案1】:

    有趣的是,该代码如果被调用两次应该不会引发异常; java.lang.Runtime#loadLibrary() 的 javadoc 声明

    如果使用相同的库名多次调用此方法,则忽略第二次和后续调用。

    所以,可能还有更多。您是否尝试在 MANIFEST.MF 的 Bundle-SymbolicName 条目中设置单例属性?

    【讨论】:

    • 刚刚尝试过...这似乎可以正常工作,因为没有错误消息。我的文件通知仍然不起作用,但我认为这一定是一个不同的问题。除了wiki.osgi.org/wiki/Bundle-SymbolicName 之外,关于该指令的作用还有更多指导吗?
    • 默认情况下,可以在 OSGi 系统/框架/容器中安装和运行捆绑包的多个实例,例如如果一个有多个版本。这个属性表明一个bundle是一个单例,即任何时候只能有一个active。可以安装其他的,但只能安装一个。
    • 我假设该库将通过其绝对文件系统名称或类似名称来标识...因此不同的版本将具有不同的路径,并且多个文件将作为本机库加载。也许这只是 libx.so 的名称?
    • 这实际上是依赖于实现的。但是,它可能会尝试从两个不同的文件加载相同的名称,因此出现此错误...
    猜你喜欢
    • 2013-07-02
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多