【问题标题】:Cannot call JNI methods when library loaded by Common classloader公共类加载器加载库时无法调用 JNI 方法
【发布时间】:2015-04-17 09:21:10
【问题描述】:

我正在尝试将使用 JNI 库的 Web 服务部署到 Windows 上的 Tomcat 6,并且在 Tomcat 管理器中重新启动应用程序时遇到了不受欢迎的 UnsatisfiedLinkError 问题(已加载到另一个类加载器中)。

我认为解决此问题的最佳实践是从另一个类加载 JNI 库,在 jar 文件中指定并放入 $(TOMCAT_HOME)/lib。当我这样做时,我无法调用任何 JNI 方法,但我可以看到 JNI 库已加载。

这个 sn-p 有效:

package com.mywebservice;

import javax.jws.WebService;
import javax.annotation.PostConstruct;

@WebService
class MyWebServiceImpl implements MyWebService {

    static {
        System.loadLibrary ("MyJNILibrary");
    }

    @PostConstruct
    public native void Start ();
}

Start 函数在 JNI 库中定义为 Java_com_mywebservice_MyWebServiceImpl_Start 并被调用。

下面的代码对我不起作用。首先,作为 MyLoader.jar 进入 $(TOMCAT_HOME)/lib 的加载器类。

package com.myloader;

public class MyLoader {

    static {
        System.loadLibrary ("MyJNILibrary");
        System.out.println ("Library loaded");
    }

    public static void main(String[] args) {}
}

二、修改后的web服务通过loader加载库,仍然是webapps下的war文件:

package com.mywebservice;

import javax.jws.WebService;
import javax.annotation.PostConstruct;

@WebService
class MyWebServiceImpl implements MyWebService {

    static {

        try {
            Class.forName ("com.myloader.MyLoader");
            System.out.println ("Class found");
        }

        catch (ClassNotFoundException e) {
            System.out.println ("Class not found");
        }
    }

    @PostConstruct
    public native void Start ();
}

使用此代码,我在尝试调用 Start 方法时看到错误:

Caused by: java.lang.UnsatisfiedLinkError: com.mywebservice.MyWebServiceImpl.Start()V

使用诊断我可以看到 MyLoader 类已找到并且 JNI 库已加载(并锁定)。所以我很困惑为什么这不起作用。

在 Windows 2003 Server、JDK 6u45、Eclipse Kepler 上使用 Tomcat 6.0.43。

这是它应该如何工作而我只是错过了一些东西吗?如果是这样,这个项目有什么意义:https://code.google.com/p/static-dll-bootstrapper/,它只是加载属性文件中指定的 DLL?

【问题讨论】:

  • 也尝试使用 Tomcat 8、Windows 8.1、JDK 8u45。同样的问题。库已加载,但未找到 JNI 函数。

标签: java c++ tomcat


【解决方案1】:

包含本机方法的类应加载其自己的库。其他任何事情都会引发这个问题。没有充分的理由将这个函数分开。

【讨论】:

  • 是的,但是如果我这样做了,如果我只想重新启动我的 Web 服务,我必须重新启动整个 Tomcat 服务,因为我的 JNI 库被多个类加载器加载。因此,为什么我需要将库加载分离到一个单独的类中。
猜你喜欢
  • 2013-11-22
  • 2011-11-13
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多