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函数,请告诉我我也可以抓住它.