Java does USB

Sundararajan Athijegannathan sundararajan.athijegannathan at oracle.com
Mon Aug 22 01:37:04 UTC 2022


  *   difficult to build

jextract prebuilt builds are available here https://jdk.java.net/jextract/
Jextract Early-Access Builds - Oracle<https://jdk.java.net/jextract/>
Notes. These builds are based on an incomplete version of JDK 19.; If you are using macOS Catalina or later you may need to remove the quarantine attribute from the bits before you can use the jextract binaries.. To do this, run the following: $ sudo xattr -r -d com.apple.quarantine path/to/jextract/folder/
jdk.java.net


  *   "mixup of system headers, excessive number of files and code"

     --include- options can be used to filter unwanted stuff from headers. You may want to check clang.symbols files in the repo (which filters unwanted symbols from clang's Index.h for bootstrapping jextract)


  *   strange class and filenames

      Without those $ names, generated java identifiers would clash with C identifier names. Also there are C identifiers that are Java keywords/reserved words.

  *   , missing constants/defines etc.).

      Do you have specific constant/define that was not generated? Please note that function-like macros are not supported. But other #defines, enum constants are supported and constant getter methods are generated. But if you found any specific case, please do send us the details.

As for API changes, please note that panama API is still in preview-mode (as of jdk19). It was incubator API in the previously. Some API evolution is expected till it becomes a standard API.

-Sundar

________________________________
From: panama-dev <panama-dev-retn at openjdk.org> on behalf of Manuel Bleichenbacher <manuel.bleichenbacher at gmail.com>
Sent: 22 August 2022 02:13
To: panama-dev at openjdk.org <panama-dev at openjdk.org>
Subject: Java does USB

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/20220822/5a2583f6/attachment-0001.htm>


More information about the panama-dev mailing list