通过JNI从Applet调用DLL

我有一个“概念certificate”的作品,跨越了一些不熟悉的领域。 我的任务是将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.(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可能是硬连线不允许Applet的那种权限。

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

谢谢你的期待

麦克风

你绝对可以做到这一点。 我有一个正在生产的工作小程序正是这样做的。 即使您的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"); } 

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

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

我唯一可以建议的是查看该区域的源代码,并尝试解密,如果由于缺乏权限而不允许或因为根本不允许这样做。 不幸的是,你没有行号,这使它变得有点棘手。

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

祝你好运。