| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Java Does USB is a Java library for working with USB devices. It allows you to query the connected USB devices and to communicate with them using custom / vendor-specific protocols. It is not intended for communication with standard types of USB devices such as mass storage devices, keyboards etc.
The library uses the Foreign Function and Memory API to access native APIs of the underlying operating system. It is written entirely in Java and does not use JNI or any native third-party library. The Foreign Function and Memory API has been introduced with Java 22.
The library is available at Maven Central. To use it, just add it to your Maven or Gradle project.
If you are using Maven, add the below dependency to your pom.xml:
<dependency>
<groupId>net.codecrete.usb</groupId>
<artifactId>java-does-usb</artifactId>
<version>1.3.0</version>
</dependency>If you are using Gradle, add the below dependency to your build.gradle file:
compile group: 'net.codecrete.usb', name: 'java-does-usb', version: '1.3.0'package net.codecrete.usb.sample;
import net.codecrete.usb.Usb;
public class EnumerateDevices {
public static void main(String[] args) {
for (var device : Usb.getDevices()) {
System.out.println(device);
}
}
}No special considerations apply. Using this library, a Java application can connect to any USB device and claim any interface that isn't claimed by an operating system driver or another application. Standard operating system drivers can be unloaded if the application is run with root privileges. It runs both on Macs with Apple Silicon and Intel processors.
libudev is used to discover and monitor USB devices. It is closely tied to systemd. So the library runs on Linux distributions with systemd and the related libraries. The majority of Linux distributions suitable for desktop computing (as opposed to distributions optimized for containers) fulfill this requirement. It runs on both Intel/AMD and ARM processors.
Similar to macOS, a Java application can connect to any USB device and claim any interface that isn't claimed by an operating system driver or another application. Standard operating system drivers can be unloaded (without the need for root privileges).
Most Linux distributions set up user accounts without permissions to access USB devices. The udev system daemon is responsible for assigning permissions to USB devices. It can be configured to assign specific permissions or ownership:
Create a file called /etc/udev/rules.d/80-javadoesusb-udev.rules with the below content:
SUBSYSTEM=="usb", ATTRS{idVendor}=="cafe", MODE="0666"
This adds the rule to assign permission mode 0666 to all USB devices with vendor ID 0xCAFE. This unregistered vendor ID is used by the test devices.
Without the udev rule, it is still possible to enumerate and query all USB devices.
The Windows driver model is rather rigid. It's not possible to open a USB device unless it uses the WinUSB driver. This even applies to devices with no installed driver. Enumerating and querying USB devices is possible independent of the driver.
USB devices can implement special control requests to instruct Windows to automatically install the WinUSB driver (search for WCID or Microsoft OS Compatibility Descriptors). The WinUSB driver can also be manually installed or replaced using a tool called Zadig.
The test devices implement the required control requests. So the driver is installed automatically.
The implementation runs on both Windows for Intel/AMD and ARM processors.
To build from source, run the following command:
cd java-does-usb mvn clean install -DskipTests
The tests are skipped as they require that a special test device is connected to the computer. See the next section for more information.
In order to run the unit tests, a special test device must be connected to the computer, which can be easily created from very inexpensive microcontroller boards. Two variants exist:
The test device with the loopback-stm32 code supports all tests. If the test device with the composite-stm32 code is connected, some tests are skipped, but the correct handling of composite devices is verified instead.
Tests can be run from the command line:
cd java-does-usb mvn clean test
If they are run from an IDE (such as IntelliJ IDEA), you will likely need to configure VM options to allow native access:
--enable-native-access=net.codecrete.usb
Or (if modules are ignored):
--enable-native-access=ALL-UNNAMED
Many bindings for the native APIs have been generated with jextract. See the jextract subdirectory for more information. For functions that need to retain the error state (errno on Linux, GetLastError() on Windows), the bindings have been manually written as jextract does not support it.
Since the code can only be generated for the current operating system, it must be generated on separate computers for Linux, Windows and macOS. Thus, the generated code is included in the repository. The generated code is compilable on all operating systems.
| Back | FazBrowse Home | New Git URL |