Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reliable configuration in Java 9

Tags:

java

java-9

One of the main goals of project Jigsaw in Java 9 is the reliable configuration. That is, Java 9 promises to address the classpath mechanism flaw that allows the java launcher to run a program without making sure that all necessary classes will be available to load in runtime, which used to result in java.lang.NoClassDefFoundErrors.

This is done by declaring module dependencies in module-info.java and by the brand new --module-path option. The module graph is analyzed before launching a Java application.

However, I can still do the following.

  1. Lets say I have two modules com.spacey.explorer and com.spacey.rocket. com.spacey.explorer uses a class com.spacey.rocket.RocketZ defined and exported by com.spacey.rocket module. After compiling and JARing both modules everything runs correctly.
  2. Now I remove the com.spacey.rocket.RocketZ type from com.spacey.rocket module and recompile and re-JAR only this one module.
  3. I run the previously compiled com.spacey.explorer module with newly compiled com.spacey.rocket module.
  4. I get ... java.lang.NoClassDefFoundError, which is possible after like 4 hours of application uptime.

Is there a way to really make sure that when running Java application not only the module graph (module path) completeness is verified but also a comprehensive check of the actual type accessibility is done ?

like image 815
malloc4k Avatar asked Jan 30 '23 12:01

malloc4k


2 Answers

Is there a way to really make sure that when running Java application not only the module graph (module path) completeness is verified but also a comprehensive check of the actual type accessibility is done?

Not within the JVM, no. The module system operates on the level of artifacts and is happy if an artifact claiming to be the right module is present. Beyond that, no further checks are performed.

That said, JDeps should be able to help you out. It analyzes your project and its dependencies and operates on the level of individual classes. It will point out dependencies that could not be found.

In your example:

$ jdeps -R --module-path jars-dir -m com.spacey.explorer

> com.spacey.explorer    -> com.spacey.rocket    not found
like image 160
Nicolai Parlog Avatar answered Feb 02 '23 10:02

Nicolai Parlog


I think the other answer helps on the technical aspect, but beyond that, I think you got the reliable part a bit wrong.

This talks about brittle classpaths:

All of these are the results of a brittle classpath. What that means is that ClassLoaders don’t have a good mechanism for distinguishing one loaded class from another class of the same name, or for isolating classes loaded by one ClassLoader from classes loaded by another.

And the answer that modules offer to this:

Java Modules will provide reliable configuration and strong encapsulation. If you have incompatibilities, you will discover these at build time instead of some indeterminate time after your application has started running in production.

In other words: I think it is a misconception on your end to assume that modules were designed to prevent all kinds of LinkageError (the mother of all No..FoundError thingies). Modules make it easier for you to build things. You found a nice example that this doesn't necessarily translate into a perfect safety net regarding runtime issues.

In other words: your interpretation of "reliable modules" is not in sync with the promise of "reliable modules" that project Jigsaw is actually trying to provide.

like image 26
GhostCat Avatar answered Feb 02 '23 10:02

GhostCat