2015-06-03 11 views
5

Ich habe gearbeitet zu lesen C# (dll) -Funktion von Java über jni4net und in Core Java Ich habe es geschafft, den Wert von der DLL-Funktion, aber jetzt habe ich ein Dynamic Web erstellt Projekt und versuchte die gleiche Funktionalität in Servlet zu verwenden. Aber jetzt wird nur die DLL-Datei erfolgreich geladen, die Funktion wird nicht erfolgreich aufgerufen. Im Folgenden finden Sie, was habe ich versucht, bis jetzt:UnzufriedeneLinkError Ausnahme während der Arbeit mit dll und java jni4net

Mein Servlets:

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); 
    } 
} 

Der einzige Unterschied, wenn ich machte dies in Kern Java war, dass ich nicht vollständigen Pfad verwendet hat stattdessen benutzte ich nur „lib/ADHelper.j4n.dll "für Pfad, aber irgendwie funktionierte es nicht in Servlet, also habe ich es in den vollständigen Pfad geändert. Anyways die DLL-Datei wird erfolgreich geladen.

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; 
     } 
} 

Die underdscore wurde auf den Namen ADHelper Klasse mischte sich, wenn ich proxygen Befehl ausgeführt wurde. in DLL-Datei gibt es zwei ADHelper und ADHelper namens Klassen

Die Funktion Login() wurde ebenfalls auf Login2 geändert(), aber Login2() von meinem Servlet während Anmeldung nicht erkannt wird() erkannt wird.

generiert Java-Klasse 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; 
    } 
} 

die All-Mapping ist richtig, aber meine Anmeldung Funktion UnsatisfiedLinkError gibt. Vielen Dank für Ihre Geduld beim Lesen, bitte geben Sie eine Lösung für mein Problem.

Nach Fehlern kommen auf Konsole:

*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) 

Antwort

1

Ich betrachtete es als das Classloader-Problem, das es nicht war, als ich später meine Dateien zum Laden von demselben Classloader unterdrückte.

Weitere Untersuchung ergab, dass der Pfad, den ich gab, der direkte Pfad zur Datei im Verzeichnis war und nicht in dieselbe Richtung wie die Datei im Servlet-Kontextbereich zeigte. Dafür musste ich servlet context object erstellen und danach wurde getResuorce Methode aufgerufen, so dass ich meine Datei abrufen kann und bereit ist, verwendet zu werden.

Hier ist Code-Datei aus Servletkontext Umfang zu erhalten:

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

Thank you @ surabhi-rai für Ihre Unterstützung. Ich habe dieses asnwer gepostet, wenn in Zukunft jemand dieses Problem bekommen kann. Danke ihnen und willkommen. ☻

2

Vielleicht können Sie testen, für Klasse-loader Dateien aus verschiedenen Klassenlader in anderem Kontext zu laden.

+1

Ich erzwinge die DLL aus dem Webkontext Classloader laden, aber keine Änderung ist da. –

1

Rufen Sie Ihre Dateireferenz über das Objekt servlet context ab und rufen Sie dann getResource auf.

Jetzt gerade zeigen Sie auf lokale dir, die nicht in Servlet Kontextbereich ist.