我已经实现了一个Java软件包,其功能是通过USB连接到工作站的POS打印机和现金抽屉。我还实现了一个applet来利用这个软件包的功能,希望能够通过POS网站调用它。
当从Eclipse中运行applet时,一切顺利。当applet在浏览器中运行时,我的软件包似乎无法访问通过USB连接的外围设备。我收到来自第三方(JavaPOS)代码的错误说明:
jpos.JposException:设备 沟通渠道不可能 打开,检查设备并重试。
小程序使用自我证书进行签名。我发布了一些代码,但错误是从埋在制造商专用驱动程序中的某个地方抛出的,用于正在使用的POS打印机。
我假设问题是,在浏览器沙箱中,applet无法访问通过USB连接的外围设备。
可能是这种情况吗?如果是这样,无论如何都要从已签名的Applet中访问USB外围设备?
如果applet无法访问USB外围设备,那么网站如何调用可以使用的代码?
答案 0 :(得分:2)
我不确定你问题的答案,但有一个实验可以进一步阐明这个问题。
Applet.init()
来电System.setSecurityManager(null)
的开头行。然后尝试连接USB。
setSecurityManager(null)
的调用将成功,并删除SecurityManager
的最后一个残余。 (是的,即使是受信任的applet也有安全管理器,它对沙盒应用程序的安全管理器的限制要小得多。)请注意我不建议将此类代码投入生产。如果您的applet与其他applet在同一个JRE中运行,则使SM无效也可以提升其他applet的权限。
答案 1 :(得分:2)
在浏览器沙箱中运行时,已签名的Java小程序是否可以访问USB外围设备?
要解决此特定问题(并避免以下评论中涉及的特定技术),是签名Java小程序可以访问USB外设。当您运行已签名的小程序时,“沙箱”就是您“脱离”的能力。
但出于安全原因,只需签署小程序就不会自动授予对沙箱外部项目的访问权限。
PrivelegedAction
似乎是访问特权系统组件(如打印机)的首选方法。 Oracle提供了有关这些特权操作的更多信息:http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html
此外,在Web浏览器中执行此类操作时需要考虑几个因素,因为Java会关注操作的来源。
public function writeFile() {
...
FileWriter fw = new FileWriter(...);
...
}
public void init() {
writeFile();
}
例如,如果您要使用applet init()方法中的$HOME/Desktop/text.txt
类将文件写入文件系统(即FileWriter
),则签名小程序通常 允许它。将其整合到PrivilegedAction
会更好,首先使用AccessController.checkPermission(...)
检查权限是理想的。
但是,当FileWriter
直接从JavaScript(而不是从init())调用时,var myapplet = document.getElementById('myapplet');
myapplet.writeFile(); // Blocked by Security Framework
会被阻止:
PrivelegedAction
为了避免这个问题,有些人选择使用public void init() {
...
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
writeFile();
return null;
}
});
...
}
,但是如果操作需要很长时间,你会注意到它会阻止UI,这在网页中是非常糟糕的做法(并且会使浏览器)。
{{1}}
此外,您的问题具体涉及访问USB外围设备,这通常通过迭代人机接口设备来完成。 HID不是Java本身直接支持的东西(但是,在写这个/ JRE7时)。所以,是的,签名的小程序可以与您的USB外围设备进行通信,但您需要使用某种形式的Java Native Interfacing(JNI)来正确“访问”它们。 JNI可能是一个混乱,以支持跨平台(即与您的JAR分发DLL和SO)所以......
大多数Java Applet所做的是访问本地安装的打印机并使用标准的Java Printing库。这是我们在qz-print项目中执行此操作的方法,您可以在此处查看我们的源代码:https://github.com/qzindustries/qz-print/tree/master/qz-print/src/qz,它使用由init()触发的线程和布尔标志来触发所有特权函数。
答案 2 :(得分:1)
我在XP上使用Epson TM-H6000III和使用JRE 1.6在Win7 32bit上遇到了类似的问题。管理员可以使用该设备,但“用户”不能。 Java控制台正在报告:
Sep 23, 2011 3:38:47 PM com.xxxx.printer.epson.EpsonPrinter findPrinter
INFO: Error opening PrinterIII: jpos.JposException:
Could not connect to service with logicalName =
PrinterIII: Exception.message=Property or stream open error.
JRE安装似乎有权限问题。重新安装JRE很快就解决了问题。
答案 3 :(得分:0)
我收到了Star Micronics团队的反馈,他们的...... javapos驱动程序不支持网络浏览器打印。'
BTW,System.setSecurityManager(null)被证明是消除我所遇到的与安全相关的任何问题的好方法。谢谢安德鲁。