我有一个“概念验证”的作品,它跨越了一些不熟悉的领域。
我的任务是将 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:访问被拒绝(java.lang.RuntimePermission loadLibrary.DLoggerImpl)”,这意味着权限问题。可能是我的策略文件错误,或者签名错误,或者类似的情况,也可能是 Java 硬连线不允许 Applet 拥有此类权限,因为存在安全风险。
我的问题是我在浪费时间吗?可以吗?如果可以,怎么做?
感谢期待
Mike
你绝对可以做到这一点。我在生产中有一个正在运行的小程序,它正是这样做的。即使你的小程序已签名,你仍然需要使用访问控制器来访问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 函数的源示例,请告诉我,我也可以获取。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)