使用dll和java jni4net时,不满意的链接错误异常 [英] UnsatisfiedLinkError exception while working with dll and java jni4net

查看:269
本文介绍了使用dll和java jni4net时,不满意的链接错误异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在从java通过jni4net和核心java读取c#(dll)函数,我已经成功地从dll函数中获取了值,但是现在我创建了一个动态Web项目,并试图在servlet中使用相同的功能。但是现在只有dll文件被成功加载,该函数不会被成功地调用。以下是我迄今为止所尝试的:



我的Servlet:

  public class LoginProcess extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {

try {

Bridge.setVerbose(true);
Bridge.init();
Console.WriteLine(Hello .NET world!\\\
);

Bridge.LoadAndRegisterAssemblyFrom(new File(C:/Users/ashish.it/workspace/FinalJniWeb/WebContent/WEB-INF/lib/ADHelper.j4n.dll));

} catch(IOException e){
e.printStackTrace();
}
枚举输出;
output = ADHelper.Login(user,pass);
System.out.println(output);
}
}

我在核心java中做到这一点的唯一区别是我没有使用完整的路径,而是我只使用lib / ADHelper.j4n.dll路径,但不知何故在servlet中不工作,所以我将其更改为完整的路径。无论如何,dll文件已成功加载。



ADHelper.generated.cs

 命名空间ADHelper {
public partial class ADHelper_ {

methods.Add(global :: net.sf.jni4net.jni.JNINativeMethod.Create(@__ type ,Login,Login2,(Ljava / lang / String; Ljava / lang / String;)Lsystem / Enum;));

private static global :: net.sf.jni4net.utils.JniHandle Login2(global :: System.IntPtr @__envp,global :: net.sf.jni4net.utils.JniLocalHandle @__class,global: :net.sf.jni4net.utils.JniLocalHandle UserName,global :: net.sf.jni4net.utils.JniLocalHandle Password){
//(Ljava / lang / String; Ljava / lang / String;)Lsystem /枚举;
//(LSystem / String; LSystem / String;)LADHelper / ADHelper + LoginResult;
global :: net.sf.jni4net.jni.JNIEnv @__env = global :: net.sf.jni4net.jni.JNIEnv.Wrap(@__ envp);
global :: net.sf.jni4net.utils.JniHandle @__return = default(global :: net.sf.jni4net.utils.JniHandle);
try {
@__return = global :: net.sf.jni4net.utils.Convertor.StrongC2Jp< global :: ADHelper.ADHelper.LoginResult>(@__ env,global :: ADHelper.ADHelper.Login( global :: net.sf.jni4net.utils.Convertor.StrongJ2CString(@__ env,UserName),global :: net.sf.jni4net.utils.Convertor.StrongJ2CString(@__ env,Password)));
} catch(global :: System.Exception __ex){@__ env.ThrowExisting(__ ex);}
return @__return;
}
}

当我的名字ADHelper类时,underdscore被混合在一起运行proxygen命令。在dll文件中有两个类名为 ADHelper和ADHelper



函数Login()也更改为Login2(),但Login2生成的Java类 ADHelper.java

  package adhelper; 

@ net.sf.jni4net.attributes.ClrType
public class ADHelper extends system.Object {

private static system.Type staticType;

protected ADHelper(net.sf.jni4net.inj.INJEnv __env,long __handle){
super(__ env,__handle);


@ net.sf.jni4net.attributes.ClrConstructor(()V)
public ADHelper(){
super(((net.sf .jni4net.inj.INJEnv)(null)),0);
adhelper.ADHelper .__ ctorADHelper0(this);
}

@ net.sf.jni4net.attributes.ClrMethod((LSystem / String; LSystem / String;)LADHelper / ADHelper + LoginResult;)
public native static system.Enum Login(java.lang.String UserName,java.lang.String Password);

public static system.Type typeof(){
return adhelper.ADHelper.staticType;
}

private static void InitJNI(net.sf.jni4net.inj.INJEnv env,system.Type staticType){
adhelper.ADHelper.staticType = staticType;
}
}

所有的映射是正确的,但我的Login函数给出unsatisfiedLinkError。感谢您阅读时有耐心,请解决我的问题。



控制台之后出现以下错误:

  *所有Dll文件加载消息* 
2015年6月3日10:56:39 org.apache.catalina.core.StandardWrapperValve调用
SEVERE:Servlet.service()for servlet LoginProcess throws
java.lang.UnsatisfiedLinkError:adhelper.ADHelper.Login(Ljava / lang / String; Ljava / lang / String;)Lsystem / Enum;
at adhelper.ADHelper.Login(Native Method)
at com.karvy.login.LoginProcess.doGet(LoginProcess.java:62)
at javax.servlet.http.HttpServlet.service( HttpServlet.java:617)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
在org.apache .catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
在org.apache.catalina.connector .CoyoteAdapter。 service(CoyoteAdapter.java:293)
在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
在org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process( Http11Protocol.java:606)
在org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java: 662)


解决方案

我认为它是类加载器问题当我稍后禁止我的文件从同一个类加载器加载时,不是。



进一步的检查显示,我给出的路径是目录中文件的直接路径,在servlet上下文范围中没有指向与文件相同的方向。为此,我必须创建 servlet上下文对象,之后调用 getResuorce 方法,以便我可以将我的文件上传并准备使用。



这是从servlet上下文范围获取文件的代码:

  ServletContext context = getServletContext(); 
String realPath = context.getRealPath(/ WEB-INF / lib / ADHelper.j4n.dll);
文件文件= new File(realPath);

谢谢@ surabhi-rai为您的支持。我已经发布了这个asnwer,如果将来有人得到这个问题可以来这里。谢谢并欢迎。 ☻


I have been working on reading c#(dll) function from java through jni4net and in core java I have succeeded in getting the value from the dll function but now I have created one Dynamic Web Project and tried to use same functionality in servlet. But now only the dll file is loaded succesfully, the function is not called succesfuly. Below is what I tried till now:

My Servlet:

public class LoginProcess extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        try {

            Bridge.setVerbose(true);
            Bridge.init();
            Console.WriteLine("Hello .NET world!\n");

            Bridge.LoadAndRegisterAssemblyFrom(new File("C:/Users/ashish.it/workspace/FinalJniWeb/WebContent/WEB-INF/lib/ADHelper.j4n.dll"));

        } catch (IOException e) {
            e.printStackTrace();
        }
        Enum output;
        output=ADHelper.Login("user", "pass");
        System.out.println(output);
    }
}

The only difference when I made this in core java was that I didn't used complete path instead I used only "lib/ADHelper.j4n.dll" for path but somehow it was not working in servlet so I changed it to complete path. Anyways the dll file is loaded succesfully.

ADHelper.generated.cs

namespace ADHelper {
    public partial class ADHelper_ {

methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "Login", "Login2", "(Ljava/lang/String;Ljava/lang/String;)Lsystem/Enum;"));

  private static global::net.sf.jni4net.utils.JniHandle Login2(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__class, global::net.sf.jni4net.utils.JniLocalHandle UserName, global::net.sf.jni4net.utils.JniLocalHandle Password) {
            // (Ljava/lang/String;Ljava/lang/String;)Lsystem/Enum;
            // (LSystem/String;LSystem/String;)LADHelper/ADHelper+LoginResult;
            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
            global::net.sf.jni4net.utils.JniHandle @__return = default(global::net.sf.jni4net.utils.JniHandle);
            try {
            @__return = global::net.sf.jni4net.utils.Convertor.StrongC2Jp<global::ADHelper.ADHelper.LoginResult>(@__env, global::ADHelper.ADHelper.Login(global::net.sf.jni4net.utils.Convertor.StrongJ2CString(@__env, UserName), global::net.sf.jni4net.utils.Convertor.StrongJ2CString(@__env, Password)));
            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
            return @__return;
        }
}

The underdscore was mingled to the name ADHelper class when I ran proxygen command. in dll file there are two classes named ADHelper and ADHelper

The function Login() was also changed to Login2() but Login2() is not recognized by my servlet whereas Login() is recognized.

Generated Java class ADHelper.java

package adhelper;

@net.sf.jni4net.attributes.ClrType
public class ADHelper extends system.Object { 

private static system.Type staticType;

    protected ADHelper(net.sf.jni4net.inj.INJEnv __env, long __handle) {
            super(__env, __handle);
    }

    @net.sf.jni4net.attributes.ClrConstructor("()V")
    public ADHelper() {
            super(((net.sf.jni4net.inj.INJEnv)(null)), 0);
        adhelper.ADHelper.__ctorADHelper0(this);
    }

@net.sf.jni4net.attributes.ClrMethod("(LSystem/String;LSystem/String;)LADHelper/ADHelper+LoginResult;")
    public native static system.Enum Login(java.lang.String UserName, java.lang.String Password);

 public static system.Type typeof() {
        return adhelper.ADHelper.staticType;
    }

 private static void InitJNI(net.sf.jni4net.inj.INJEnv env, system.Type staticType) {
        adhelper.ADHelper.staticType = staticType;
    }
}

All the mapping is correct but my Login function is giving unsatisfiedLinkError. Thanks for having patience while reading, please give solution to my problem.

Following error is coming on console:

*All Dll file loaded message*
Jun 3, 2015 10:56:39 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet LoginProcess threw exception
java.lang.UnsatisfiedLinkError: adhelper.ADHelper.Login(Ljava/lang/String;Ljava/lang/String;)Lsystem/Enum;
    at adhelper.ADHelper.Login(Native Method)
    at com.karvy.login.LoginProcess.doGet(LoginProcess.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

解决方案

I considered it to be the classloader problem which it was not when I later suppressed my files to load from same classloader.

Further examination shown that the path I was giving was direct path to the file in the directory, and was not pointing to the same direction as of file in servlet context scope. For that I had to create servlet context object and after that getResuorce method was called so that I can get my file up and ready to be used.

Here is code to get file from servlet context scope:

ServletContext context = getServletContext();
String realPath = context.getRealPath("/WEB-INF/lib/ADHelper.j4n.dll");
File file = new File(realPath);

Thank you @surabhi-rai for your support. I have posted this asnwer for if in future anyone gets this problem can come here. Thank you and welcome. ☻

这篇关于使用dll和java jni4net时,不满意的链接错误异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆