java - 通过 JNI 从 Applet 调用 DLL

标签 java applet java-native-interface

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

我暂时忽略了 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)

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

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

感谢期待

迈克

最佳答案

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

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

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

关于java - 通过 JNI 从 Applet 调用 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1713403/

相关文章:

java - 基于 Apache CXF 的应用程序中的长期对象

java - 一次插入数据库的多个表

java - 是否可以将 ANTLR 语法配置为使用具有相同结构的两个标记?

java - ImageJ 嵌入网站

java - 如何为小程序配置新的安全对话框?

android - --target native-lib 不是一个目录

android - 根据我的需要减少编译后的 ffmpeg 库大小

java - Android Java 中的 BBCODE 到 HTML

java applet 将 jar 文件导出为独立的可执行文件

java - 是否可以在 Java 中加载同一个 DLL 的不同版本?