Java does USB

Manuel Bleichenbacher manuel.bleichenbacher at gmail.com
Sun Aug 21 20:43:40 UTC 2022


When I reported the issue related to GetLastError(), I was working on a
library for communicating with USB devices from Java. The library has made
good progress and the current result is available on GitHub:
https://github.com/manuelbl/JavaDoesUSB. It runs on Windows, macOS and
Linux, both on Intel and ARM processors (I haven't tested ARM on Windows
yet) and does not require any additional libraries to be installed.

The main use case for project Panama seems to be to make third-party
libraries accessible to Java. This library is different: it makes native
operating system APIs accessible.

My experience with project Panama so far:

Except for the GetLastError() issue, it just works. The VM never crashed
because of a bug. And in most cases where I made a mistake with native data
structures or function calls, it was caught with a run-time exception. In a
few cases, I managed to pass invalid data to API calls, which then crashed
the VM.

The USB APIs on Windows, macOS and Linux are fundamentally different. So
there was hardly any synergies between them. But the code for the Intel and
ARM variants on each platform is identical. I guess these two 64-bit
architectures have similar concepts for passing arguments and aligning
data. But project Panama also seems to take care of some of the differences.

I've written all the code for the native function calls and native data
structures manually. I've tested jextract but found it frustrating
(difficult to build, mixup of system headers, excessive number of files and
code, strange class and filenames, missing constants/defines etc.). It
might work better for a well-written third-party library. But for all the
crust that has accumulated in a 40 year old operating system, manual work
turned out to be a better option.

The documentation is clearly insufficient. I had to learn from hitting
exception, guessing the causes and experimenting with solutions. And with
Google you find a lot of outdated documents. The documentation doesn't seem
to explain how members in a StructLayout are aligned, why you can't pass a
memory segment created with MemorySegment.ofArray() to a native function
etc. And if it does, it is so distributed that I didn't find it.

Translating C code into Java, I would have expected that this C structure,
which requires 4 bytes of padding between timeout and data:

struct usbdevfs_ctrltransfer {
    __u8 bRequestType;
    __u8 bRequest;
    __u16 wValue;
    __u16 wIndex;
    __u16 wLength;
    __u32 timeout;  /* in milliseconds */
    void *data;
};

simply translates to:

public static final GroupLayout ctrltransfer$Struct = structLayout(
        JAVA_BYTE.withName("bRequestType"),
        JAVA_BYTE.withName("bRequest"),
        JAVA_SHORT.withName("wValue"),
        JAVA_SHORT.withName("wIndex"),
        JAVA_SHORT.withName("wLength"),
        JAVA_INT.withName("timeout"),
        ADDRESS.withName("data")
);

After all, ADDRESS has an alignment of 64 bits / 8 bytes. So the padding
could be added automatically. But it just throws an error when used.
Instead the padding must be specified manually. Very surprising. And even
if it needs to be specified manually, I'd rather specify that 'data' needs
an 8 byte alignment instead of calculating the padding and adding
paddingLayout(32).

A single time, I hit an implementation limitation: The macOS function
CFUUIDGetConstantUUIDWithBytes cannot be implemented (
https://developer.apple.com/documentation/corefoundation/1542189-cfuuidgetconstantuuidwithbytes).
I found a workaround.

Overall, I like project Panama and hope that it will leave preview phase
soon (including a fix for the GetLastError() issue).

My USB library has still a way to go. The next step will be technically
challenging: notification about USD devices being plugged in or removed. It
will require a run loop and Mach ports on macOS, message handling with
message-only windows on Windows and non-blocking I/O with select() on Linux.

Regards
Manuel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20220821/7fa68d5c/attachment.htm>


More information about the panama-dev mailing list