2009-11-11 8 views
7

Ich habe eine "Proof of Concept" Arbeit, die in ein unbekanntes Gebiet übergeht. Ich habe die Aufgabe, einen EFTPOS-Computer mit einer Anwendung zu verbinden, die als Applet in einem Browser in unserem Intranet ausgeführt wird.Aufruf einer DLL von einem Applet über JNI

Ich habe die EFTPOS DLL für den Moment ignoriert und eine einfache JNI verzierte DLL in meiner Sprache der Wahl (Delphi) erstellt, die nur eine Zeichenfolge in eine Textdatei in c: \ protokolliert und ich kann sie erfolgreich von a aufrufen lokale Java-Anwendung.

Wenn ich jedoch ein Applet erstellen, um die gleiche Sache zu tun, kompilieren Sie es in .JAR, signieren Sie die JAR & versuchen, die Methode im Applet über Javascript auf einer Webseite aufzurufen es schlägt fehl.

Ein älterer Java-Typ, mit dem ich arbeite, glaubt nicht, dass es möglich sein wird, dies zum Laufen zu bringen, weil es von Natur aus "böse" ist, einem Applet dies zu ermöglichen.

Es gibt einen Eintrag, den Sie in eine java.policy-Datei einfügen können, um loadLibrary zuzulassen. sowie AllPermission & Ich habe alles ohne Erfolg in diese Richtung eine ganze Reihe von Variationen versucht, die folgenden Fehler Spur in der Java-Konsole produzieren:

java.lang.ExceptionInInitializerError 
    at app.TestApplet.LogAString(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.plugin.javascript.JSInvoke.invoke(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source) 
    at sun.plugin.com.MethodDispatcher.invoke(Unknown Source) 
    at sun.plugin.com.DispatchImpl.invokeImpl(Unknown Source) 
    at sun.plugin.com.DispatchImpl$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.plugin.com.DispatchImpl.invoke(Unknown Source) 
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.DLoggerImpl) 
    at java.security.AccessControlContext.checkPermission(Unknown Source) 
    at java.security.AccessController.checkPermission(Unknown Source) 
    at java.lang.SecurityManager.checkPermission(Unknown Source) 
    at java.lang.SecurityManager.checkLink(Unknown Source) 
    at java.lang.Runtime.loadLibrary0(Unknown Source) 
    at java.lang.System.loadLibrary(Unknown Source) 
    at app.DLogger.<clinit>(Unknown Source) 
    ... 16 more 
java.lang.Exception: java.lang.ExceptionInInitializerError 
    at sun.plugin.com.DispatchImpl.invokeImpl(Unknown Source) 
    at sun.plugin.com.DispatchImpl$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.plugin.com.DispatchImpl.invoke(Unknown Source) 

Der Schlüssel Linie scheint „von verursacht werden: java. security.AccessControlException: Zugriff verweigert (java.lang.RuntimePermission loadLibrary.DLoggerImpl) "was ein Berechtigungsproblem impliziert. Es könnte sein, dass ich die Policy-Datei falsch - oder die Signierung falsch - oder ähnliches bekomme, oder es könnte sein, dass Java fest damit verbunden ist, solche Berechtigungen für ein Applet wegen des Sicherheitsrisikos nicht zuzulassen.

Meine Frage ist verschwende ich meine Zeit? Kann es getan werden & wenn ja, wie?

Dank im Vorgriff

Mike

+0

Ich denke, es war erwähnenswert, dass mit unserem Java-Applet, das DLLs lädt, ein großer Prozentsatz (95%) der Clients das Applet ohne Probleme ausführen kann. Es muss also eine andere Erklärung für dieses Verhalten geben, eine Art Browser/JVM/OS-Kombination, die diesen Effekt verursacht. – davidecr

Antwort

14

Sie können dies auf jeden Fall erreichen. Ich habe ein funktionierendes Applet in der Produktion, das genau das tut. Selbst wenn Ihr Applet signiert ist, müssen Sie immer noch den Access Controller verwenden, um auf die DLL zuzugreifen. Sie können nicht einfach "loadlibrary" aufrufen. Sie können dies der Java-Richtliniendatei hinzufügen, dies wird jedoch aufgrund von 1 nicht empfohlen. Sie haben wahrscheinlich keinen Zugriff auf die Java-Konfiguration des Benutzers. 2. Auch wenn dies für Ihr eigenes Unternehmen ist, ist die Verwaltung der Richtliniendatei ein Problem, da Benutzer JRE herunterladen und Ihre Richtliniendatei entweder überschrieben oder ignoriert wird.

Am besten signieren Sie Ihr Glas und stellen Sie sicher, dass Sie den Code Ihrer Ladebibliothek in einen privilegierten Codeblock wie diesen einbetten.

try 
{ 
    AccessController.doPrivileged(new PrivilegedAction() 
    { 
     public Object run() 
     { 
      try 
      { 
       // privileged code goes here, for example: 
       System.load("C:/Program Files/.../Mydll.dll"); 
       return null; // nothing to return 
      } 
      catch (Exception e) 
      { 
       System.out.println("Unable to load Mydll"); 
       return null; 
      } 
     } 
    }); 
} 
catch (Exception e) 
{ 
    System.out.println("Unable to load Mydll"); 
} 

Sie können auch verwenden System.loadLibrary (mydll.dll), aber sie haben die DLL-Ordner auf dem Weg in den Fenstern haben, so das Applet es finden kann.

Wenn Sie einige Quellproben für den Aufruf der JNI-Funktionen benötigen, lassen Sie mich wissen, dass ich das auch greifen kann.

0

Das einzige, was ich auf den Quellcode nimmt für diesen Bereich einen Blick vorschlagen können, und versuchen zu entschlüsseln, wenn es nicht wegen des Mangels an Genehmigung erlaubt oder weil das ist überhaupt nicht erlaubt. Sie haben leider keine Zeilennummern, das macht es etwas komplizierter.

+0

Ich gehe rein - wünsche mir Glück – mcottle

0

Ich bin ziemlich sicher, dass Sie eine native Bibliothek von einem Applet nicht laden können, wenn es "signiert" ist, und dann wird der Benutzer einen Akzeptanzdialog erhalten, um zu erlauben oder zu verbieten. Das heißt, vorausgesetzt, Sie können JNI überhaupt in einem Applet ausführen ... habe das nie versucht.

Viel Glück.

+1

Das Applet ist signiert. Das Problem läuft entweder auf 1) Ich habe die Berechtigungen nicht korrekt geschrieben. 2) Es ist irgendwo in Java festgeschrieben, dass es nicht möglich ist. – mcottle

Verwandte Themen