2009-11-11 3 views
7

У меня есть «доказательство концепции» работы, которая пересекает какую-то незнакомую территорию. Мне поручено подключить машину EFTPOS к приложению, запущенному как апплет в браузере в нашей интрасети.Вызов DLL из апплета через JNI

Я проигнорировал dll EFTPOS на данный момент и создал простую JNI-декорированную DLL на моем выбранном языке (Delphi), который просто записывает строку в текстовый файл в c: \, и я могу успешно ее вызвать из локальное приложение Java.

Однако, когда я создаю апплет, чтобы сделать то же самое, скомпилируйте его в .JAR, подпишите JAR & попробуйте вызвать метод в апплете через Javascript на веб-странице, с которой он не работает.

Старший Java-парень, с которым я работаю, не думает, что это возможно, чтобы заставить его работать, потому что по своей сути «зло» позволяет апплету это делать.

В файл java.policy можно вставить запись, чтобы разрешить loadLibrary. а также allPermission & Я пробовал целый ряд вариаций вдоль этих линий все безрезультатно, производящих следующий след ошибки в Java Console:

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) 

Ключ линии, кажется, «Вызванной: Java. security.AccessControlException: доступ запрещен (java.lang.RuntimePermission loadLibrary.DLoggerImpl) ", что подразумевает проблему с разрешениями. Возможно, я ошибаюсь в неправильном файле политики или неправильном подписи, или что-то вроде этого, или может быть, что Java жестко не разрешает подобные разрешения для апплета из-за угрозы безопасности.

Мой вопрос: я трачу свое время? Это можно сделать & если да, то как?

Благодаря в ожидании

Майк

+0

Я думаю, что стоит упомянуть, что с помощью нашего java-аплета, который загружает библиотеки DLL, большой процент (95%) клиентов может без проблем запускать апплет. Поэтому должно быть какое-то другое объяснение этого поведения, какая-то комбинация браузера/JVM/OS, которая вызывает этот эффект. – davidecr

ответ

14

Вы можете определенно выполнить это. У меня есть рабочий апплет в производстве, который делает именно это. Даже если ваш апплет подписан, вам все равно нужно использовать Access Controller для доступа к DLL, вы не можете просто вызвать «loadlibrary». Вы можете добавить это в файл политики Java, однако это не рекомендуется из-за 1. Вероятно, у вас нет доступа к конфигурации java для пользователей. 2. Даже если это используется для вашей собственной компании, управление файлом политики - это боль, поскольку пользователи загружают некоторую JRE, а файл политики либо перезаписывается, либо игнорируется.

Лучше всего подписать свою банку, убедившись, что вы упаковали свой код библиотеки загрузки в привилегированный блок кода, подобный этому.

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

Вы можете также использовать System.loadLibrary (MyDLL.dll), но вы должны иметь папку DLL на пути в окнах, так что апплет может найти его.

Если вам нужны некоторые исходные образцы для вызова функций JNI, дайте мне знать, что я тоже могу это ухватить.

0

Единственное, что я могу предложить взглянуть на исходный код для этой области и пытается расшифровать, если она не позволяет из-за отсутствия разрешения или потому, что вообще не допускается. К сожалению, у вас нет номеров строк, поэтому это немного сложнее.

+0

Я иду - желаю удачи – mcottle

0

Я уверен, что вы не можете загрузить собственную библиотеку из Applet, если она не «подписана», а затем пользователь получит диалоговое окно подтверждения, чтобы разрешить или запретить. То есть, предполагая, что вы можете делать JNI вообще в апплете ... никогда не пробовал это.

Удачи.

+1

Апплет подписан. Проблема сводится к 1) я неправильно написал разрешения. 2) Это где-то на Java, где это невозможно сделать. – mcottle

Смежные вопросы