2009-11-11 5 views
7

J'ai une «preuve de concept» qui traverse un territoire que je ne connais pas. Je suis chargé de connecter une machine EFTPOS à une application exécutée en tant qu'applet dans un navigateur sur notre intranet. J'ai ignoré la DLL EFTPOS pour le moment et créé une simple DLL décorée JNI dans la langue de mon choix (Delphi) qui enregistre simplement une chaîne dans un fichier texte dans c: \ et je peux l'appeler avec succès à partir d'un application Java locale.Appel d'une DLL à partir d'une applet via JNI

Cependant, lorsque je crée une applet pour faire la même chose, compilez-la en .JAR, signez le JAR & essayez d'appeler la méthode dans l'applet via Javascript sur une page web où elle échoue.

Un type Java senior avec lequel je travaille ne pense pas qu'il sera possible de faire fonctionner cela parce que c'est intrinsèquement "maléfique" de permettre à une applet de le faire.

Il existe une entrée que vous pouvez placer dans un fichier java.policy pour autoriser loadLibrary. ainsi que allPermission & J'ai essayé tout un tas de variations le long de ces lignes en vain produire la trace d'erreur suivant dans la console Java:

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) 

La ligne clé semble être « Causé par: java. security.AccessControlException: accès refusé (java.lang.RuntimePermission loadLibrary.DLoggerImpl) "ce qui implique un problème d'autorisations. Il se peut que le fichier de stratégie soit incorrect - ou que la signature ne soit pas correcte - ou qu'il se peut que Java soit câblé pour ne pas autoriser ce type d'autorisation pour une applet en raison du risque de sécurité.

Ma question est de savoir si je perds mon temps? Peut-il être fait & si oui, comment?

Merci d'avance

Mike

+0

Je pense qu'il était utile de mentionner qu'avec notre applet java qui charge les DLL, un grand pourcentage (95%) des clients peut exécuter l'applet sans aucun problème. Il doit donc y avoir une autre explication pour ce comportement, une sorte de combinaison navigateur/JVM/OS qui provoque cet effet. – davidecr

Répondre

14

Vous pouvez certainement accomplir ceci. J'ai une applet de travail en production qui fait exactement cela. Même si votre applet est signée, vous devez toujours utiliser Access Controller pour accéder à la DLL, vous ne pouvez pas simplement appeler "loadlibrary". Vous pouvez l'ajouter au fichier de stratégie Java, mais ce n'est pas recommandé en raison de 1. Vous n'avez probablement pas accès à la configuration java des utilisateurs. 2. Même si c'est pour votre propre utilisation de l'entreprise, la gestion du fichier de stratégie est pénible car les utilisateurs vont télécharger certains JRE et votre fichier de politique est écrasé ou ignoré. Le meilleur moyen est de signer votre jar, en veillant à envelopper votre code de la bibliothèque de chargement dans un bloc de code privilégié comme celui-ci.

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

Vous pouvez également utiliser System.loadLibrary (mydll.dll), mais vous devez avoir le dossier dll sur le chemin dans les fenêtres de sorte l'applet peut le trouver.

Si vous avez besoin d'exemples de sources pour appeler les fonctions JNI, faites-le moi savoir.

0

La seule chose que je peux suggérer, est un regard sur le code source pour cette région et à essayer de déchiffrer si elle ne permet pas à cause de l'absence d'autorisation ou parce que n'est pas autorisé du tout. Vous n'avez malheureusement pas de numéros de ligne, ce qui le rend un peu plus compliqué.

+0

J'y vais - bonne chance – mcottle

0

Je suis sûr que vous ne pouvez pas charger une bibliothèque native à partir d'une applet, sauf si elle est "signée", puis l'utilisateur recevra une boîte de dialogue d'acceptation pour autoriser ou interdire. Autrement dit, en supposant que vous pouvez faire JNI du tout dans une applet ... jamais essayé cela.

Bonne chance.

+1

L'applet est signée. Le problème se résume à 1) Je n'ai pas écrit les permissions correctement. 2) Il est câblé dans Java quelque part que cela ne peut pas être fait. – mcottle

Questions connexes