Rob Spoor

+ Follow
since Oct 27, 2005
Rob likes ...
Eclipse IDE Spring VI Editor Chrome Java Windows
Merit badge: grant badges
Forum Moderator
Rob Spoor currently moderates these forums:
For More
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads

Recent posts by Rob Spoor

Java 22 (and 21 with preview features enabled) allows you to do this:

By assigning it to a variable it becomes an expression. But _ (disallowed since Java 9, reallowed since Java 22) is an unnamed variable - it cannot be used anywhere, but serves as recipient of a value you discard. You won't get a warning that the variable is never used.
5 days ago

Piet Souris wrote:Fair enough, but I was concentrating on the 'MyInterface'. So the full story would then become

That can be done a bit simpler using a method reference:

You don't even need an existing interface for that:

(Of course all of this is a lot more complex than just myList.forEach(a -> System.out.println(a)) or myList.forEach(System.out::println))
5 days ago

Stephan van Hulst wrote:People may say Java is compiled to Java bytecode, but that doesn't prevent me from writing an interpreter that executes Java statements without compiling them first.

That already exists. It's called "java", see JEP 330: Launch Single-File Source-Code Programs (since Java 11) and JEP 458: Launch Multi-File Source-Code Programs (Java 22?).

As a preview feature in Java 21 and 22, you can even simply run a file like this without having to compile anything:
(JEP 445: Unnamed Classes and Instance Main Methods (Preview) and JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview))
2 weeks ago

Tim Holloway wrote:MOST interesting.

However, this class appears to be part of the glue that would connect native binary APIs to Java code. So a couple of consideraations might apply.

1. The canonical layouts for data types don't necessary have to be the same as what's internal to the JVM storage itself, only (as I see it) in the passing of primitives to/from ABIs.

2. Although Linkers are discussed in terms of OS/hardware, I have previously noted somewhere that for the Commodore Amiga there were 2 different binary models available: 16-bit for Aztec C and 32-bit for Lattice and Green Hills C. So the canonical map might look different on such a platform, though the actual primitive data lengths  would be the same for ABIs regardless (since 16-bit/32-bit was not a mode-switching change, only a code generation change.

Meaning, for best results, follow the instructions precisely and assume nothing.

Isn't all of FFM meant to be little more (or perhaps not even that) than a way to interact with ABIs?

The way I understood it, the canonical map is a runtime thing that uses the actual sizes (using sizeof) a set of well-known types. So with the same Java code, the layout for a size_t could be 4 on one machine and 8 on another - without any changes to the compiled Java code. As a developer you just need to use the layout returned and not for instance ValueLayout.JAVA_LONG. And this again is something that only matters when you're calling ABIs, e.g. the Linux stdlib or Windows API.
2 weeks ago
I found the following method in Java 22's Linker class: canonicalLayouts(). This gives access to the layouts (and therefore the sizes) of some of the native types:

All native linker implementations are guaranteed to provide canonical layouts for the following set of types:

  • bool
  • char
  • short
  • int
  • long
  • long long
  • float
  • double
  • size_t
  • wchar_t
  • void*

  • On my Windows machine this returns ValueLayout.JAVA_CHAR for wchar_t and ValueLayout.JAVA_LONG for size_t.
    3 weeks ago
    I mean users (developers)  creating custom bean classes or provider methods.

    The application properties allow you to tweak the auto-configuration, but custom beans allow you to let them not even be created (in those cases where @ConditionalOnMissingBean is used).
    4 weeks ago
    Spring Boot comes with a lot of auto-configuration classes. What most of these have in common is that they create beans conditionally. One such condition is @ConditionalOnMissingBean(SomeBeanClass.class). The auto-configuration only creates these beans when you (or some other dependency) doesn't create a bean. I've used that in my own Spring Boot starters as well, to allow users to easily override the defaults I provide.
    1 month ago

    Tim Holloway wrote:What does "OOTB" mean???

    Probably out-of-the-box.

    1 month ago

    Neil Barton wrote:I have followed the instructions @ and put a dependency in my POM.XML for slf4j-nop.jar (I've tried slf4j-simple.jar too!) but that makes no difference. How can I get rid of these warnings?

    Make sure you use the right version. Versions 1.x and 2.x of SLF4J are incompatible because the way implementations (providers) are loaded has changed.
    1 month ago
    You need to read the data from the request, using either the BufferedReader returned by getReader or the ServletInputStream returned by getInputStream().
    1 month ago
    I'm quite aware about the number of bytes any character can take up in a String. It used to be at least 2 (a String had a char[]) but possibly more; now with compact strings it's at least 1 (a String now has a byte[]). I think that for native API's it's defined more like it used to be for Strings. But that's where the issue lies, as you've correctly stated - the value of sizeof(wchar_t) is machine-dependent. My experiments have shown that it's 2 on my machine, but those last 3 words are very, very dangerous. I was just hoping that FFM would have something for that, but I'm not sure that Oracle has worked with actual native strings before.

    As for numeric types, fortunately that's pretty well defined in the Windows API: a WORD is 2 bytes (so effectively a short), a DWORD is 4 bytes (so effectively an int), and a QWORD is 8 bytes (so effectively a long). There are some endian possibilities there but the MemoryLayout API supports setting it.

    Anyway, I've come quite far with my refactoring with the assumption that sizeof(wchar_t) is 2, and it seems to work with some manual testing (I haven't come around to running the Dockerized integration tests yet). Unit testing is now killing me though. Any Mockito verify call that uses anything based on MemorySegment fails because the Arena that created it has already been closed. I can refactor away the allocation to inside the Windows API wrapper implementation, thereby abstracting away MemorySegment even more, but that comes at a price I'm not sure I'm willing to pay - any data that's needed outside the Windows API wrapper (so in my own code) needs to be copied, instead of just reading from the MemorySegment. I could move from confined / shared Arenas to one or more garbage collector managed ("auto") Arena, but that means having to give up freeing memory just for testing.
    1 month ago
    I have a project that currently uses JNA to interact with the Windows API. Now Java 21 has been released with a version of the FFM API that's almost as stable as it's going to get, I started working on rewriting the project to use FFM instead. There are some questions I have though, and I was hoping someone could help me answer those.

    1. In JNA, I could just create instances of handle references, structures, etc., and JNA would handle the memory cleanup for those. Now I can probably use MemorySegment.toArray to get something similar, but those create memorySegment instances on the heap. I have already written some code to use Arena, but that requires creating a new (mostly confined, but there are some shared exceptions) Arena for every public call of my API. That sounds like a lot of overhead, but is this something that can be avoided?

    2. The Windows API has the concept of either ASCII or wide strings, with API calls ending with A or W. With ASCII it's pretty straightforward to convert strings to bytes, but for wide strings this depends on sizeof(wchar_t). That's something that JNA can provide (Native.WCHAR_SIZE), but how can I get this value with FFM? Or can I assume that, since Java 21 only runs on 64 bit, it's always 2?

    3. The conversion of byte[] to String and vice versa was done automatically by JNA using the Native class. I found that FFM doesn't provide anything similar; all the to and from UTF-8 conversion just uses String.getBytes(Charset) and new String(byte[], Charset). That's not compatible with wide strings. Can I assume that wide strings consists of chars where each char takes up 2 bytes? Or is this again dependent on the result of sizeof(wchar_t)? In the latter case I would probably run into issues if that's not 2.
    1 month ago
    I'm not really familiar with Python's patch options, but perhaps Mockito's equivalent is a spy. You take a normal object, and Mockito wraps it for you. Unless you tell Mockito to replace method calls it will call the actual methods. And a bonus is that you can verify that calls were made afterwards - even for non-mocked methods.
    1 month ago
    For anyone manually creating new arrays, it's a lot easier these days:

    You still need the right type, but you can let the list (or any collection) create the array for you.
    2 months ago

    Mikalai Zaikin wrote:Spring Boot 3.0 is the first version of Spring Boot that makes use of Jakarta EE 9 APIs ( jakarta.* ) instead of EE 8 ( javax.* ).

    And for the non-boot Spring Framework version, that's 6.x.
    2 months ago