2009-11-11 22 views
7

Tengo una pieza de trabajo de "prueba de concepto" que se cruza en un territorio desconocido. Tengo la tarea de conectar una máquina EFTPOS a una aplicación que se ejecuta como un applet en un navegador en nuestra intranet.Llamar a un archivo DLL desde un applet a través de JNI

He ignorado el DLL de EFTPOS por el momento y he creado una DLL decorada con JNI simple en mi lenguaje de elección (Delphi) que simplemente registra una cadena en un archivo de texto en c: \ y puedo invocarlo con éxito desde aplicación local de Java.

Sin embargo, cuando creo un applet para hacer lo mismo, compilarlo en .JAR, firmar el JAR & intente llamar al método en el applet a través de Javascript en una página web que falla.

Un chico senior de Java con el que estoy trabajando no cree que sea posible hacer que esto funcione porque es intrínsecamente "malo" permitir que un applet lo haga.

Hay una entrada que puede colocar en un archivo java.policy para permitir loadLibrary. así como AllPermission & He intentado toda una serie de variaciones a lo largo de esas líneas todo fue en la producción de la siguiente traza de error en la consola de Java vano:

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 línea clave parece ser "Causado por: java. security.AccessControlException: acceso denegado (java.lang.RuntimePermission loadLibrary.DLoggerImpl) "que implica un problema de permisos. Podría ser que estoy obteniendo el archivo de política incorrecto - o la firma incorrecta - o cosas así o podría ser que Java está cableado para no permitir ese tipo de permisos para un Applet debido al riesgo de seguridad.

Mi pregunta es ¿estoy perdiendo el tiempo? ¿Se puede hacer & si es así, cómo?

Gracias en la anticipación

Mike

+0

Creo que vale la pena mencionar que con nuestro applet java que carga archivos DLL, un gran porcentaje (95%) de los clientes puede ejecutar el applet sin ningún problema. Entonces debe haber alguna otra explicación para este comportamiento, algún tipo de combinación de navegador/JVM/OS que cause este efecto. – davidecr

Respuesta

14

Definitivamente puede lograr esto. Tengo un applet en producción que hace exactamente esto. Incluso si su applet está firmado, aún necesita usar el controlador de acceso para acceder al dll, no puede simplemente llamar a "loadlibrary". Puede agregar esto al archivo de políticas de Java; sin embargo, esto no se recomienda debido a 1. Probablemente no tenga acceso a la configuración java de los usuarios. 2. Incluso si esto es para el uso de su propia empresa, administrar el archivo de política es un problema ya que los usuarios descargarán algunos JRE y su archivo de política se sobrescribirá o se ignorará.

Lo mejor es que firme su jar, asegurándose de ajustar el código de su biblioteca de carga en un bloque de código privilegiado como este.

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

Puede también utilizar System.loadLibrary (mydll.dll), pero hay que tener la carpeta DLL en el camino en las ventanas por lo que el applet puede encontrarlo.

Si necesita algunas muestras de fuentes para llamar a las funciones de JNI, avísenme que también puedo tomar eso.

0

La única cosa que puedo sugerir es echar un vistazo al código fuente para esa zona y tratando de descifrar si no está permitiendo que debido a la falta de permiso o porque no está permitido en absoluto. Desafortunadamente, no tiene números de línea, por lo que es un poco más complicado.

+0

Voy a entrar - Deséenme suerte – mcottle

0

Estoy bastante seguro de que no puede cargar una biblioteca nativa desde un Applet a menos que esté "firmada", y luego el usuario obtendrá un diálogo de aceptación para permitir o rechazar. Es decir, suponiendo que puedas hacer JNI en un applet ... nunca lo intenté.

Buena suerte.

+1

El applet está firmado. El problema se reduce a 1) No he escrito los permisos correctamente. 2) Está cableado en Java en algún lugar que no se puede hacer. – mcottle

Cuestiones relacionadas