It is a Java API that allows direct USB-level access to the system's USB devices. It's composed of a collection of interfaces and base classes, and a class that loads an implementation. It is standardized and was created through the Java Community Process (JCP) Java Specification Request number 80 (JSR80).
Currently there are two certified implementations. One is the "Reference Implementation" (RI) that is implemented on Linux. The other is an implementation created by Ricoh on the BSD platform.
For more information on the Reference Implementation for Linux, see here.
The JCP process requires all JSRs to create a Test Compliance Kit (TCK) that can ensure API compliance of all implementations. A "certified" implementation is one that has passed the javax.usb TCK. Any given implementation may work correctly, but we will not refer to it as "certified" (in the official sense) until it passes the TCK test suite.
IBM was the specification lead for JSR80. IBM also remains the maintenance lead for the now-approved JSR80. Dan Streetman (at IBM) wrote the majority of the API, common implementation, and Linux implementation, with assistance from Brian Weischedel, Roger Lindsjo, and Boris Dainson, and other people from the original JSR80 expert group and current javax.usb mailing list. The original API (which has been almost completely replaced) was written primarily by Michael Maximilien.
The API, common implementation, and Linux implementation are maintained primarily by Dan Streetman in his "free time", although since he works for IBM, his contributions are still owned by IBM. Dan Streetman and Roger Lindsjo are currently the only project developers with CVS access.
All questions should be sent to the project's mailing list. To prevent spam from being posted to the mailing list, you must be subscribed to the mailing list before posting to the list. Please use the mailing list instead of emailing developers directly.
The USB 1.1 specification is the latest supported by the current javax.usb API. However, USB 2.0 devices should work with javax.usb since control of the device speed is done by the OS, not javax.usb.
Since the USB 2.0 specification is not supported yet by javax.usb, any USB 2.0 constants or structures/descriptors are missing from the javax.usb API. For example, UsbDevice.getSpeed() will return UsbConst.DEVICE_SPEED_UNKNOWN since there is no javax.usb API constant for highspeed, until the USB 2.0 specification support is added.
The USB specification is available from usb.org. They should be downloadable from the Documents page. The specfication you should get for now is the USB 1.1 specification, although the USB 2.0 specification is the latest.
Note that the current javax.usb API does not support the USB 2.0 specification.
HID is a protocol layered on top of USB, so you can use any HID device with javax.usb. However you will need to implement USB<->HID translation on top of javax.usb. You will need to be familiar with the HID specification to do this. Please feel free to write a complete HID layer on top of javax.usb, so others can use it.
Like HID, Mass Storage is a protocol layered on USB. To talk to a USB Mass Storage device, you must implement USB<->Mass Storage translation on top of javax.usb. This is going to be much harder than HID<->USB translation. Additionally, the device stores its filesystem like any other storage device, by using a partition table and filesystem(s). So you will have to implement code to handle partition tables and filesystems (probably the standard MSDOS partition table and FAT32 filesystem, although storage devices can use anything). All those layers are very complex and each OS has very complex drivers to handle all the layers, so implementing them on top of javax.usb would be extremely difficult, but it is possible (good luck!).
It should be mentioned that all OSes already have USB Mass Storage support and will make the USB device available through standard storage access mechanisms (i.e. standard I/O). In almost all cases you should be able to access USB Mass Storage devices through normal disc I/O, such as those provided in the standard java.io package.
The USB protocol is only a data transfer protocol. It does not define how to actually make any devices do anything. So, all USB devices have their own protocol, either proprietary or based on another standard protocol that is layered on top of USB (e.g. HID, Mass Storage, etc.). You need to understand your device's protocol to be able to talk to it. Some people on the mailing list may be able to help you understand your device's protocol if it is based on a standard (or if they have experience with the same device). But for most USB devices with proprietary protocols, you must either get the specification from the manufacturer or reverse engineer the protocol by sniffing the driver provided by the manufacturer.
Here is a list of programs that use javax.usb:mailing list.
Unfortunately, the USB specification does not define a standard way to reset a USB device. Some devices have proprietary ("vendor") reset commands, if you know that your device has one then use it. If not, the only way to reset a device is to disable/reset the port that the device is connected to. The only way to do that is to send a port disable command to the hub that owns the port. Since all OSes are required to have a hub driver that manages all USB hubs, you will not be able to send a port disable command to any hub (in almost all cases), or if you can, it will probably interfere with the system's hub driver with unexpected results.
Some OSes provide a implementation-specific device reset command, however it is usually not safe to use such a mechanism. For example, Linux provides a "reset device" ioctl as part of the usbfs filesystem (which javax.usb uses), however this ioctl is not safe to use at all kernel levels for any device.
Due to the lack of a standardized way of resetting devices, and the probability that most OSes would not be able to safely implement such an interface, there is no way to reset a USB device using the javax.usb API (besides directly resetting the port, if possible).
The most common reason that claiming an interface fails is because the interface is currently being driven by the system's normal driver. For example, if you are trying to claim an interface that reports it is a HID-class interface (in its interface descriptor), then it will almost certainly fail since the system's normal HID driver is most likely driving it. On systems where interface claiming (or something similar) is implemented, you will not be able to claim or communicate with the interface. Note that the USB specification does not explicitly define any interface claiming, but most systems implement some level of interface and/or device claiming. To claim an interface in use by a system driver, see forceClaim.
In order to claim an interface that is already claimed by a system driver, you must use an instance of the UsbInterfacePolicy interface. You must create the instance, either with an explicit class or inner class. The implementing class should return true for the method forceClaim. Note that since the UsbInterface being claimed is passed as a parameter, the method can use that UsbInterface to determine if the interface should be "forceClaim"ed or not. When you claim the interface, use the claim method with a UsbInterfacePolicy parameter.
Since the USB specification does not define interface claiming, the implementation of "forceClaim"ing is platform-specific. As described in the JavaDoc for "forceClaim", the implementation will try everything possible to claim the interface, which may involve forcibly removing the existing driver from the interface. Since the interface being claimed will no longer be driven by the normal system driver, extreme care should be taken when using "forceClaim". For example, using "forceClaim" to claim a USB hub's interface will almost certainly result in a non-functional hub.
The connectivity of a USB device is managed by the USB hub that the device is connected to (or directly to the USB host controller, which is effectively the same as a USB hub for this explanation). All USB hubs have a "status change" endpoint that is an interrupt-type endpoint. Since USB devices define their own poll rates for interrupt-type endpoints, the rate can be anything, but typically hubs define their status change endpoint's poll rate to be high, usually every 255ms. A faster poll rate would only waste USB bandwidth, since USB device connections and disconnections happen so infrequently.
When a device is disconnected, the USB subsystem does not know about the disconnection until the USB hub (or host controller) tells it that the device was disconnected. Since the USB hub is only polled for a status change infrequently (e.g. every 255ms), there can be many failed transfers to the now-nonexistent device before the USB hub notifies the USB hub driver that the device is gone, and the USB subsystem processes the disconnection. All those transfers that happen after the physical device disconnection, but before the USB subsystem realizes the device is gone, will result in strange errors. Typically, the errors will be protocol errors, since there will be absolutely no response to any packets sent to a nonexistent device, although from a javax.usb API perspective the errors will probably be UsbPlatformExceptions.
Usually, the errors will be encountered for periodic endpoints (i.e. interrupt or isochronous) with a faster poll rate than the USB hub's status change endpoint's poll rate, since those are the most likely to occur in the above-described "window" before the disconnection is detected.
The specification is provided in the form of JavaDoc. The source code to the entire API is available.
Compiling the API creates a JAR file called jsr80.jar. You must add this to your CLASSPATH. If you are using a binary package with an installer it will be added to your CLASSPATH automatically.
You need a javax.usb implementation; the file is provided by all javax.usb implementations.
The API is licensed under the Common Public License.
The "common" implementation is a partial implementation that is 100% Java. It implements almost all of the API, and has a small internal API. A platform implementation must provide the remaining code to connect the common implementation to the OS's USB interface.
An implementation of javax.usb does not need to use the common implementation, but using it will make an implementation much easier.
Compiling the common implementation creates a JAR file called jsr80_ri.jar. You must add this to your CLASSPATH. If you are using a binary package with an installer it will be added to your CLASSPATH automatically.
No, the common implementation will not work by itself. It requires a lower-level implementation that connects it with the Operating System's USB interface.
The common implementation is licensed under the Common Public License.
The Linux implementation connects the common implementation to Linux's "usbfs" interface, which is the userspace USB interface on Linux.
To use the Linux implementation, you need the javax.usb API, common implementation, and Linux implementation.
Compiling the Linux implementation creates a JAR file called jsr80_linux.jar and a native JNI library called libJavaxUsb.so. You must add the JAR file to your CLASSPATH. You also must add the native JNI library to your Linux "ld" loader path, which you can do by either putting the library in a directory listed in /etc/ld.so.conf (e.g. /usr/lib), or by adding the directory containing the JNI library to your LD_LIBRARY_PATH environment variable, or by putting the library in your JRE's native JNI library directory, which is specific to your JRE. Finally, you must add the directory containing the Linux implementation's javax.usb.properties to your CLASSPATH.
Yes. The Linux implementation uses the usbfs filesystem to access USB devices directly. So, you at least need to be able to access this filesystem. This means you must have Linux kernel support for the usbfs filesystem, and it must be mounted (at /proc/bus/usb). To check if the filesystem is mounted, run mount and it should be listed. To see if there are USB devices available via the usbfs filesystem, run cat /proc/bus/usb/devices, and it should show some entries.
You also have to have read-write access to the device nodes of the usbfs filesystem. By default, only root has read/write access to these. Those nodes are /proc/bus/usb/NNN/NNN where "NNN" is a 3-digit number. Run ls -l /proc/bus/usb/???/??? to see the current permissions. For details on the filesystem and its options, see the Linux kernel source Documentation/usb/proc_usb_info.txt file. If you do not care about security, you can allow access to all USB devices by anyone by setting the filesystem devmode to 0666, e.g. mount -o devmode=0666 usbfs /proc/bus/usb or mount -o remount,devmode=0666 usbfs /proc/bus/usb depending on whether the filesystem is currently mounted or not. You can also add the parameter to the usbfs entry in your /etc/fstab file. Keep in mind that on any multi-user system you may not want to allow everyone complete, direct access to all USB devices. You should set the device node owner and/or group according to who needs access, and only give read/write access to the user or group that needs it.
Make sure you have done the system setup needed in Linux. Assuming your Linux setup is correct, your problem may be the shell initialization files that the RPM installers use. The RPMs install bash and csh scripts in /etc/profile.d/ that add the appropriate JAR files and directories to your CLASSPATH. However, the conventions for these files are not consistent in different distributions. The provided files are mode 644, while some distributions require 755. Also the files don't invoke a shell (i.e. they do not start with #!/bin/bash or #!/bin/csh), and some distributions require them to. Note the disadvantage of making them invoke a shell is that creates a hard dependency of the RPMs to both /bin/bash and /bin/csh, so the RPMs would fail to install on systems without both shells installed (by RPM) if the provided scripts were real scripts.
Check the other shell initialization scripts in your /etc/profile.d/ directory and adjust the javax-usb* initialization scripts as needed.
If it still doesn't work, see these suggestions.
You could have one of several problems. First, check to make sure you have read/write access to the usbfs device nodes as described in the Linux setup section. If you do have access, make sure the usbfs /proc/bus/usb/devices file contains entries for the USB devices you have connected. Then, make sure you have the javax.usb.properties file provided with your Linux implementation in your CLASSPATH. If none of those help you, turn on the Linux implementation's JNI tracing to see if it tells you what the problem is. If you still can't figure it out, ask for help on the mailing list.
Yes, it provides a javax.usb.properties file, as is required by the javax.usb API. The file is located in the lib/ directory of the source code package. You must add that directory to your CLASSPATH. If you installed the javax-usb-ri-linux RPM, the file is located at /opt/javax-usb/etc/javax.usb.properties and is (or should be) automatically added to your CLASSPATH for you by a shell initialization file located in /etc/profile.d/.
There is rather extensive tracing included in the Linux implementation's JNI code, mainly because JNI code is difficult to write and even more difficult to debug. However it also provides a relatively good trace of all the javax.usb interaction with the system and USB devices. To enable and configure the tracing, see the javax.usb.properties file, which contains the settings and documentation of how to configure them.
The Linux implementation is licensed under the Common Public License.
There is no certified implementation for Windows.
There is a proprietary implementation created by IBM, but it is not currently available. This implementation is not certified and may not be complete or correct.
Finally, there is an alpha-level implementation written directly to the Windows USB API, but this implementation is missing a required kernel driver. It cannot actually communicate with devices yet, it can only show the USB topology. There is currently no work being done on this implementation. This implementation is not certified and is not complete.
The TCK is a test suite written in Java using JUnit. It has some hardware requirements in order to perform the tests, including a Cypress USB development board. For details on the TCK, download the TCK package and read the documentation.
Please send all TCK questions to the TCK mailing list. To prevent spam from being posted to the mailing list, you must be subscribed to the mailing list before posting to the list. Please use the mailing list instead of emailing developers directly.