通过JNI从Applet调用DLL

mco*_*tle 8 java java-native-interface applet

我有一个"概念证明"的作品,跨越了一些不熟悉的领域.我的任务是将EFTPOS计算机连接到在我们的Intranet上的浏览器中作为applet运行的应用程序.

我暂时忽略了EFTPOS dll并用我选择的语言(Delphi)创建了一个简单的JNI修饰DLL,它只是将字符串记录到c:\中的文本文件中,我可以从本地Java应用程序成功调用它.

但是,当我创建一个applet来做同样的事情时,将其编译成.JAR,签署JAR并尝试通过Javascript在applet中调用该方法失败.

我正在使用的一个高级Java人员并不认为有可能让它工作,因为允许applet执行此操作本身就是"邪恶的".

您可以在java.policy文件中放入一个条目以允许loadLibrary.以及allPermission&我已经尝试了这些行中的大量变体,但无法在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)
Run Code Online (Sandbox Code Playgroud)

关键线似乎是"引起:java.security.AccessControlException:访问被拒绝(java.lang.RuntimePermission loadLibrary.DLoggerImpl)"这意味着权限问题.可能是我得到的策略文件错误 - 或签名错误 - 或类似的东西,或者由于安全风险,Java可能是硬连线不允许Applet的那种权限.

我的问题是我在浪费时间吗?可以这样做,如果是,怎么做?

谢谢你的期待

麦克风

Kei*_*osh 15

你绝对可以做到这一点.我有一个正在生产的工作小程序正是这样做的.即使您的applet已签名,您仍然需要使用Access Controller来访问dll,您不能只调用"loadlibrary".您可以将其添加到Java策略文件中,但由于1,建议不要这样做.您可能无权访问用户java配置.2.即使这是为了您自己的公司使用,管理策略文件也很痛苦,因为用户将下载一些JRE并且您的策略文件被覆盖或被忽略.

最好的办法是签署你的jar,确保将你的加载库代码包装在这样的特权代码块中.

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");
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用System.loadlibrary(mydll.dll),但您必须在Windows中的路径上有dll文件夹,以便applet可以找到它.

如果你需要一些源代码来调用JNI函数,请告诉我我也可以抓住它.