Unlock using newer Java language features for engine development (Java 17)

The plan is to set the source compatibility level to Java 17 to be able to use newer java language features in engine development.

Note, however as stated this only includes using new language features.

API Features like HttpClient, Foreign Function & Memory API, and Virtual Threads,… can not be used because Android does not support them.
(however, there is some good news Android 14 Brings Partial Support for OpenJDK 17, Improved Privacy and Security, and More)

Let us know your opinion on this.

10 Likes

You know Android better than me, but if it will not break Android development for earlier versions, then its fine. But if it gonna break something on earlier versions, we might want wait a little with it.

I seen the note, just making sure.

1 Like

Yeah, I was able to run newer java language features like lambda, records, instances of pattern matching, text blocks, and switch expression which are added through java 8 to 17, in android 7.

Android dexer (D8) + ASM seems to do this compiler magic.

2 Likes

Nice! Well its kind of maintenance work, but always worth to make, to not get engine dusted :slight_smile:

btw. thanks for all work you do

1 Like

I think this would be great.
At some point it would be awesome if we had Java modules as well.

2 Likes

I think it’s okay to start using the new language features, if it were me who takes control, I would enable them only on the very surface development, I mean not on jme3-core API packages, not all developers should really know these features to deal with the Engine and if we want to refactor the whole Engine, it should be gradual.

As for virtual threads, HttpClient, and the new jdk APIs, well my opinion is they could be restricted to non-cross-platform or platform-specific modules (for example jme3-desktop, jme3-lwjgl, jme3-lwjgl3,…), that if we do need them really.

The new jdk APIs could also be utilized through CompatibilityCheck classes, in which you check for the presence of a specific feature (for example, VirtualThread) via reflection (try to instantiate and check for null pointers) or by simply checking the java.version or java.vm.name (will print you Dalvik in case of android) and modifying the code dynamically to disable/enable these features.

Maybe a good start is to consider using the new language features in the ‘jme3-examples’ and ‘jme3-desktop’ modules, in which there are minimal chances to break the core.

2 Likes

I’m trying to parse what you mean, and I’m a little puzzled. When you say “Deal with” the engine, do you mean developers who are trying to use JME? If so, none of the language features being discussed here, with the possible exception of Records, should impact the API surface at all. (Record is just a more concise way to implement immutable data-transfer-thingys.) It shouldn’t matter if these features are being used inside core code, if they are the clearest/cleanest way to implement something.


Is there a simple - or at least straightforward - way of linting against certain API usages while allowing language features? (If JME was using Module, the HTTPClient, at least, could just be excluded from the “Depends on Modules” list.)


I’ve said this before, but think it bears repeating: JME is pretty much already organised into modules, just not using the formal Module markouts. I don’t think that making it jigsaw-compatible would be a huge project.

1 Like

I mean, IMO we should not use them on jme3-core for now, and we may consider them for implementations of the core, for example, the jme3-examples.

I don’t wish to derail this thread, so further discussion of java modules should probably be in its own thread. With that said, I did quite a bit of work on a local branch a couple years ago to see just how painful it would be, and it was becoming quite painful. Due to how JME is organized at first glance it looks easy to implement modules, but several key architectural designs will require some key thought on the matter:
Rules JME Breaks for Java Modules:

  1. No two modules can contain the same classpath. This will be the largest issue to face.
    1.5. Because two modules cannot share the same classpath, a protected class within a module cannot be accessed by another module.
  2. No two jars may be the same module: This will be a tricky one that could be worked around. But would require some thought for modules like jme-lwjgl vs jme-lwjgl3.
  3. Many gradle projects that are multi-module place modules in a directory (usually called modules) and not at the root of the project. This has to do with how jdk tools handles passing module source code as command line arguments. IIRC, I think this is no longer an issue, but I don’t recal if the javadoc generator ever got its’ command line arguments fixed for this.

As stated, further discussion for java modules should get moved elsewhere. @sailsman63 if you are interested in implementing modules, I can be a resource for you, as I have implemented them for several other open source projects and many closed source projects for my company. Unfortunately, I do not have the bandwidth to propose a PR myself, but I am more than happy to answer questions and help whoever wants to try and tackle this. Just note, whoever does try to tackle this will probably be faced with technical issues that need to be resolved (that require breaking changes).

2 Likes