通过 JNI 从 Applet 调用 DLL [英] Calling a DLL from an Applet via JNI

查看:34
本文介绍了通过 JNI 从 Applet 调用 DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a "proof of concept" piece of work that crosses over into some unfamiliar territory. I'm tasked with connecting an EFTPOS machine to an application running as an applet in a browser on our intranet.

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

I've ignored the EFTPOS dll for the moment and created a simple JNI decorated DLL in my language of choice (Delphi) that just logs a string to a text file in c:\ and I can call it successfully from a local Java application.

然而,当我创建一个小程序来做同样的事情时,将它编译成一个.JAR,签署JAR &尝试在失败的网页上通过 Javascript 调用小程序中的方法.

However, when I create an applet to do the same thing, compile it into a .JAR, sign the JAR & try to call the method in the applet via Javascript on a web page it fails.

与我一起工作的一位高级 Java 人员认为这不可能让它工作,因为允许小程序这样做本质上是邪恶的".

A senior Java guy I'm working with doesn't think it will be possible to get this to work because it's inherently "evil" to allow an applet to do this.

您可以在 java.policy 文件中放入一个条目以允许 loadLibrary.以及 allPermission &我已经尝试了所有这些方面的变化,但都无济于事,在 Java 控制台中产生以下错误跟踪:

There is an entry you can put in a java.policy file to allow loadLibrary. as well as allPermission & I've tried a whole host of variations along those lines all to no avail producing the following error trace in the Java Console:

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 获得此类权限.

The key line seems to be "Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.DLoggerImpl)" which implies a permissions problem. It could be that I'm getting the policy file wrong - or the signing wrong - or stuff like that or it could be that Java is hardwired to not allow those sort of permissions for an Applet because of the security risk.

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

My question is am I wasting my time? Can it be done & if so, how?

期待中的感谢

迈克

推荐答案

你绝对可以做到这一点.我在生产中有一个工作小程序,它就是这样做的.即使您的小程序已签名,您仍然需要使用访问控制器来访问dll,您不能只调用loadlibrary".您可以将其添加到 Java 策略文件中,但不建议这样做,因为 1. 您可能无权访问用户的 java 配置.2. 即使这是供您自己的公司使用,管理策略文件也很痛苦,因为用户会下载一些 JRE,而您的策略文件要么被覆盖,要么被忽略.

You can definitely accomplish this. I have a working applet in production that does exactly this. Even if your applet is signed, you still need to use the Access Controller to access the dll, you cannot just call "loadlibrary". You can add this to the Java policy file however this is not recommended due to 1. You probably do not have access to the users java configuration. 2. Even if this is for your own company use, managing the policy file is a pain as users will download some JRE and your policy file is either overwritten or ignored.

您最好的办法是对您的 jar 进行签名,确保将您的加载库代码包装在像这样的特权代码块中.

You best bet is to sign your jar, making sure to wrap your load library code in a privileged block of code like this.

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 文件夹,以便小程序可以找到它.

You can Also use System.loadlibrary(mydll.dll) but you have to have the dll folder on the path in windows so the applet can find it.

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

If you need some source samples for calling the JNI functions let me know I can grab that as well.

这篇关于通过 JNI 从 Applet 调用 DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆