【问题标题】:Calling a DLL from an Applet via JNI通过 JNI 从 Applet 调用 DLL
【发布时间】:2009-11-11 06:20:55
【问题描述】:

我有一个“概念证明”的工作,它跨越了一些不熟悉的领域。 我的任务是将 EFTPOS 机器连接到在我们内部网的浏览器中作为小程序运行的应用程序。

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

但是,当我创建一个小程序来执行相同的操作时,将其编译为 .JAR,签署 JAR 并尝试通过网页上的 Javascript 调用小程序中的方法,但失败了。

与我一起工作的一位高级 Java 人员认为这不可能实现,因为允许小程序执行此操作本质上是“邪恶的”。

您可以在 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)

关键行似乎是“Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.DLoggerImpl)”,这意味着权限问题。可能是我弄错了策略文件 - 或签名错误 - 或类似的东西,或者可能是因为安全风险,Java 硬连线不允许 Applet 的此类权限。

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

感谢期待

迈克

【问题讨论】:

  • 我认为值得一提的是,使用我们加载 DLL 的 java 小程序,很大一部分 (95%) 的客户端可以毫无问题地执行该小程序。因此,这种行为肯定有其他解释,某种浏览器/JVM/OS 组合会导致这种效果。

标签: java applet java-native-interface


【解决方案1】:

你绝对可以做到这一点。我有一个生产中的工作小程序可以做到这一点。即使您的小程序已签名,您仍然需要使用访问控制器访问 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");
}

您也可以使用 System.loadlibrary(mydll.dll) 但您必须在 windows 的路径上拥有 dll 文件夹,以便小程序可以找到它。

如果您需要一些源示例来调用 JNI 函数,请告诉我,我也可以获取。

【讨论】:

    【解决方案2】:

    我唯一能建议的是查看该区域的源代码,并尝试破译它是否因为缺乏许可或根本不允许而不允许。不幸的是,你没有行号,所以这有点棘手。

    【讨论】:

      【解决方案3】:

      我很确定您不能从 Applet 加载本机库,除非它被“签名”,然后用户将获得一个接受对话框来允许或禁止。也就是说,假设您可以在一个小程序中执行 JNI……从未尝试过。

      祝你好运。

      【讨论】:

      • 小程序已签名。问题归结为 1)我没有正确编写权限。 2) 它被硬连线到 Java 中无法完成的地方。
      猜你喜欢
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      相关资源
      最近更新 更多