JDK-8344647 : Make java.se participate in the preview language feature `requires transitive java.base`
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 24
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-11-20
  • Updated: 2025-04-22
  • Resolved: 2024-12-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 24 JDK 25
24Fixed 25 b03Fixed
Related Reports
Relates :  
Description
After https://github.com/openjdk/jdk/commit/1e97c1c913220b07ff0c1c977cea80bc9436729d, I'm seeing the following regression in a compilation that succeeded on earlier versions:

```
error: cannot access module-info
  bad class file: /modules/java.se/module-info.class
    bad requires flag: ACC_TRANSITIVE (0x0020
    Please remove or make sure it appears in the correct subdirectory of the classpath.
1 error
```

The change adds a 'requires transitive java.base;` to java.se, and adds a special-case in src/java.base/share/classes/jdk/internal/module/ModuleInfo.java for the validation of 'requires transitive'.

There is no special case for java.se in src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java for that implementation of 'requires transitive' logic, should there be?

A simple, contrived repro is to compile a different version of java.base:

=== ./module-info.java ===
module java.base {
  exports java.lang;
}
=== ./java/lang/Object.java ===
package java.lang;
public class Object {}
=== ./T.java ===
class T {
  java.lang.instrument.ClassFileTransformer t;
}

javac --patch-module=java.base=. module-info.java java/lang/Object.java
jar cvf lib.jar module-info.class java/lang/Object.class
javac T.java --patch-module=java.base=lib.jar
error: cannot access module-info
  bad class file: /modules/java.se/module-info.class
    bad requires flag: ACC_TRANSITIVE (0x0020
    Please remove or make sure it appears in the correct subdirectory of the classpath.
1 error
Comments
A pull request was submitted for review. Branch: crac URL: https://git.openjdk.org/crac/pull/226 Date: 2025-04-22 10:20:26 +0000
22-04-2025

A pull request was submitted for review. Branch: jdk24 URL: https://git.openjdk.org/jdk/pull/22808 Date: 2024-12-18 10:00:53 +0000
18-12-2024

Changeset: d50b725a Branch: master Author: Jan Lahoda <jlahoda@openjdk.org> Date: 2024-12-18 09:58:40 +0000 URL: https://git.openjdk.org/jdk/commit/d50b725ac0f228f5b04dd68c123c7f6b263c0d02
18-12-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/22322 Date: 2024-11-22 13:42:32 +0000
22-11-2024

The `java.se` module is participating in preview (this is part of the preview JLS), and so is permitted to use the directive, and not being marked as preview. Normally, classes that participate in preview are detected by belonging to modules to which `java.base` exports the `jdk.internal.javac` package, and this is what javac's `ClassReader` uses as well for `requires transitive java.base`. I.e. having a `java.base` without the qualified exports makes `java.se` not being considered participating in preview. Thinking of it more, it may be more appropriate to hardcode the `java.se` name in javac, given that `jdk.internal.javac` is not a public API. I'll prepare a PR, to see what are the opinions.
21-11-2024

It might also be nice for the diagnostic to include the name of the module in the bad 'requires' directive
20-11-2024

Might want to consider also fixing this typo while here: --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java @@ -76,7 +76,7 @@ public static int value(Set<RequiresFlag> s) { @Override public String toString() { - return String.format("ACC_%s (0x%04x", name(), value); + return String.format("ACC_%s (0x%04x)", name(), value); } }
20-11-2024