I\'ve implemented a Java package with functionality to operate a POS printer and cash drawer connected to the workstation via USB. I\'ve also implemented an applet to utili
I received feedback from the Star Micronics team that their '...javapos drivers do not support web browser printing.'
BTW, System.setSecurityManager(null) turned out to be a great way to disambiguate any issues I was having that seemed to be related to security. Thanks Andrew.
I am not sure of the answer to your question, but have an experiment that should shed further light on the matter.
In the opening lines of the Applet.init()
call System.setSecurityManager(null)
. Then try to connect to the USB.
setSecurityManager(null)
will succeed, and remove the last remnants of the SecurityManager
. (Yes, even trusted applets have a security manager, it is just much less restrictive that the security manager for sand-boxed apps.)Note that I am not suggesting putting code like this into production. If your applet is running in the same JRE as other applets, nullifying the SM could also elevate the privileges of the other applets.
I had a similar problem with an Epson TM-H6000III on XP and Win7 32bit using JRE 1.6. Administrators could use the device, but "Users" could not. Java console was reporting:
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.
It appears the JRE installation had permission issues. Reinstalling JRE quickly cleared the problem.
Do signed java applets have access to USB peripherals when run in the browser sandbox?
To address this specific question (and avoid the specific technologies involved in the comments following), yes Signed Java Applets have access to USB Peripherals. The "sandbox" is what you have capability to "break out of" when you run a signed applet.
But for security reasons, simply signing the applet does not automatically give access to items outside of the sandbox.
PrivelegedAction
seems to be the preferred method for accessing privileged system components, such as the printer. More about these privileged actions is provided by Oracle here: http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html
In addition, there are several consideration when doing something like this from a web browser as Java cares where the action originates from.
public function writeFile() {
...
FileWriter fw = new FileWriter(...);
...
}
public void init() {
writeFile();
}
For example, if you were to write a file to the filesystem (i.e. $HOME/Desktop/text.txt
) using the FileWriter
class in the applet init() method, a Signed Applet would generally allow it. Wrapping this into a PrivilegedAction
would be better, and checking permission first using AccessController.checkPermission(...)
would be ideal.
However, FileWriter
gets blocked when it's called directly from JavaScript (instead of from init()):
var myapplet = document.getElementById('myapplet');
myapplet.writeFile(); // Blocked by Security Framework
To circumvent this issue, some chose to use PrivelegedAction
, however if the action takes a long time, you'll notice it blocks the UI, which is very bad practice in a web page (and can deadlock the browser).
public void init() {
...
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
writeFile();
return null;
}
});
...
}
Furthermore, your question asks specifically about accessing a USB peripheral, which is generally done by iterating through the Human Interface Devices. HID is not something Java directly supports natively (yet, as of writing this/JRE7). So yes, a signed applet CAN talk to your USB peripherals, but you would need to use some form of Java Native Interfacing (JNI) to properly "access" them. JNI can be a mess to support cross-platform (i.e. distributing DLLs and SOs with your JAR) so...
What most Java Applets do is access the locally installed printers and use the standard Java Printing libraries. This is how we do it over at the qz-print project and you're free to review our source code here: https://github.com/qzindustries/qz-print/tree/master/qz-print/src/qz which uses threads fired by init() and boolean flags to fire all privileged functions.