使用dll和java jni4net时,不满意的链接错误异常 [英] UnsatisfiedLinkError exception while working with dll and java jni4net
问题描述
我的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屋!