-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Background
Java Platform Module System was introduced in JDK 9 and it allowed to include module-info.java at the root of each module. The major benefits it offers is it limits access to internal APIs. You can always access them using reflection. But modules require you to explicitly allow that.
module-info.class classfile format
One fundamental module is java.base which contains all the core APIs and is implicitly required by all Java modules. Even an empty module.info.java:
module com.example.hello { }is compiled to
Last modified Oct 15, 2025; size 161 bytes
SHA-256 checksum 21203d6840fc24d7143f5ff84e8b9d0291006163892e7168090fd2874faf32dd
Compiled from "module-info.java"
module com.example.hello
minor version: 0
major version: 69
flags: (0x8000) ACC_MODULE
this_class: #1 // module-info
super_class: #0
interfaces: 0, fields: 0, methods: 0, attributes: 2
Constant pool:
#1 = Class #2 // "module-info"
#2 = Utf8 module-info
#3 = Utf8 SourceFile
#4 = Utf8 module-info.java
#5 = Utf8 Module
#6 = Unknown #7 // "com.example.hello"
#7 = Utf8 com.example.hello
#8 = Unknown #9 // "java.base"
#9 = Utf8 java.base
#10 = Utf8 25
{
}
SourceFile: "module-info.java"
Module:
#6,0 // "com.example.hello"
#0
1 // requires
#8,8000 // "java.base" ACC_MANDATED
#10 // 25
0 // exports
0 // opens
0 // uses
0 // provides
1 module is required which is java.base
Based on the Java 11 spec, requires will have three types of information
- requires_index - index into the constant pool UTF8 entry which is the name of the module;
#8 Java.basein the above example - requires_flags - #8000 in our case which means it was implicitly declared
- requires_version_index - version information about the current module
Where to infer from?
We are interested to look for requires_version_index in module-info.class. If the Java application is modularized (module-info.class) is present, we will most likely have version information.
I am not sure what version you will get if you compile with jlink.
Example from experiment
While reproducing maven,jakarta.el:jakarta.el-api,6.0.1,jakarta.el-api-6.0.1.jar, we get the following difference:
│ ├── javap -verbose -constants -s -l -private {}
│ │ @@ -1,8 +1,8 @@
│ │ - SHA-256 checksum 295a27ff84922d360fbd3260f469bce75a6d5c89bc1103eaa5cf6abb5fdb07d0
│ │ + SHA-256 checksum 696e2c2cf9be72a87fbb95acc90839eca4d65ba9f69adcee009454dd0059ffd2
│ │ Compiled from "module-info.java"
│ │ module jakarta.el@6.0.1
│ │ minor version: 0
│ │ major version: 61
│ │ flags: (0x8000) ACC_MODULE
│ │ this_class: #2 // "module-info"
│ │ super_class: #0
│ │ @@ -14,15 +14,15 @@
│ │ #4 = Utf8 jakarta.el
│ │ #5 = Module #4 // "jakarta.el"
│ │ #6 = Utf8 6.0.1
│ │ #7 = Utf8 jakarta/el
│ │ #8 = Package #7 // jakarta/el
│ │ #9 = Utf8 java.base
│ │ #10 = Module #9 // "java.base"
│ │ - #11 = Utf8 17.0.16
│ │ + #11 = Utf8 17.0.2
We compiled with 17.0.6 but the upstream was compiled with 17.0.2. Note that this wasn't the only difference, there was also difference as a result of https://bugs.openjdk.org/browse/JDK-8273914, but I will explain that in another issue and relink here.
We have 11 instances out of 500 where there was a content mismatch. However, personally, I have not seen many projects leverage the module system of Java so there is a trade-off here.
11 instances
maven,com.sun.xml.ws:jaxws-rt,4.0.3,jaxws-rt-4.0.3.jar maven,com.zaxxer:HikariCP,5.1.0,HikariCP-5.1.0.jar maven,jakarta.el:jakarta.el-api,6.0.1,jakarta.el-api-6.0.1.jar maven,com.sun.xml.messaging.saaj:saaj-impl,3.0.4,saaj-impl-3.0.4.jar maven,io.smallrye.reactive:mutiny,2.6.2,mutiny-2.6.2.jar maven,org.roaringbitmap:RoaringBitmap,1.2.0,RoaringBitmap-1.2.0.jar maven,org.snakeyaml:snakeyaml-engine,2.9,snakeyaml-engine-2.9.jar maven,org.eclipse.angus:angus-activation,2.0.2,angus-activation-2.0.2.jar maven,jakarta.xml.soap:jakarta.xml.soap-api,3.0.2,jakarta.xml.soap-api-3.0.2.jar maven,org.glassfish.jaxb:jaxb-runtime,4.0.5,jaxb-runtime-4.0.5.jar maven,jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api,3.0.2,jakarta.servlet.jsp.jstl-api-3.0.2.jar