From f35b926d82488860e1a3b34613de4cf286cf7dfa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 17:41:39 +0000 Subject: [PATCH 1/5] Initial plan From 18d2784eb5512a0772c482832c17a88e10e882e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 17:50:33 +0000 Subject: [PATCH 2/5] Add Java 22 Class File API module parser implementation Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- META-INF/MANIFEST.MF | 11 ++ plexus-java/pom.xml | 34 ++++++ .../java/jpms/BinaryModuleInfoParser.java | 21 ++++ .../jpms/ClassFileApiModuleInfoParser.java | 113 ++++++++++++++++++ pom.xml | 1 + 5 files changed, 180 insertions(+) create mode 100644 META-INF/MANIFEST.MF create mode 100644 plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java create mode 100644 plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..e6d3c0d --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Created-By: Maven JAR Plugin 3.4.2 +Build-Jdk-Spec: 17 +Specification-Title: Plexus Languages :: Java +Specification-Version: 1.5 +Specification-Vendor: Codehaus Plexus +Implementation-Title: Plexus Languages :: Java +Implementation-Version: 1.5.1-SNAPSHOT +Implementation-Vendor: Codehaus Plexus +Multi-Release: true + diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml index 836b4d8..341dafe 100644 --- a/plexus-java/pom.xml +++ b/plexus-java/pom.xml @@ -128,6 +128,40 @@ + + jdk22 + + [22,) + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + jdk22 + + compile + + + 22 + true + + ${project.basedir}/src/main/java22 + + + --enable-preview + + + + + + + + + diff --git a/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java b/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java new file mode 100644 index 0000000..7d50475 --- /dev/null +++ b/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java @@ -0,0 +1,21 @@ +package org.codehaus.plexus.languages.java.jpms; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +class BinaryModuleInfoParser extends ClassFileApiModuleInfoParser {} diff --git a/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java b/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java new file mode 100644 index 0000000..086324f --- /dev/null +++ b/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java @@ -0,0 +1,113 @@ +package org.codehaus.plexus.languages.java.jpms; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.attribute.ModuleAttribute; +import java.lang.classfile.attribute.ModuleExportInfo; +import java.lang.classfile.attribute.ModuleProvidesInfo; +import java.lang.classfile.attribute.ModuleRequiresInfo; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier; + +/** + * Extract information from module using the Class File API + * + * @author Robert Scholte + * @since 1.5.0 + */ +class ClassFileApiModuleInfoParser extends AbstractBinaryModuleInfoParser { + @Override + JavaModuleDescriptor parse(InputStream in) throws IOException { + byte[] bytes = in.readAllBytes(); + ClassModel classModel = ClassFile.of().parse(bytes); + + ModuleAttribute moduleAttr = classModel + .findAttribute(java.lang.classfile.Attributes.module()) + .orElseThrow(() -> new IOException("Not a module-info class file")); + + JavaModuleDescriptor.Builder builder = + JavaModuleDescriptor.newModule(moduleAttr.moduleName().name().stringValue()); + + // Process requires + for (ModuleRequiresInfo requiresInfo : moduleAttr.requires()) { + String moduleName = requiresInfo.requires().name().stringValue(); + int flags = requiresInfo.requiresFlagsMask(); + + boolean isStatic = (flags & ClassFile.ACC_STATIC_PHASE) != 0; + boolean isTransitive = (flags & ClassFile.ACC_TRANSITIVE) != 0; + + if (isStatic || isTransitive) { + Set modifiers = new LinkedHashSet<>(); + if (isStatic) { + modifiers.add(JavaModifier.STATIC); + } + if (isTransitive) { + modifiers.add(JavaModifier.TRANSITIVE); + } + builder.requires(modifiers, moduleName); + } else { + builder.requires(moduleName); + } + } + + // Process exports + for (ModuleExportInfo exportInfo : moduleAttr.exports()) { + String packageName = + exportInfo.exportedPackage().name().stringValue().replace('/', '.'); + if (exportInfo.exportsTo().isEmpty()) { + builder.exports(packageName); + } else { + Set targets = new HashSet<>(); + exportInfo + .exportsTo() + .forEach(target -> targets.add(target.name().stringValue())); + builder.exports(packageName, targets); + } + } + + // Process uses + moduleAttr.uses().forEach(usesInfo -> { + String serviceName = usesInfo.name().stringValue().replace('/', '.'); + builder.uses(serviceName); + }); + + // Process provides + for (ModuleProvidesInfo providesInfo : moduleAttr.provides()) { + String serviceName = providesInfo.provides().name().stringValue().replace('/', '.'); + List providers = new ArrayList<>(); + providesInfo + .providesWith() + .forEach(provider -> + providers.add(provider.name().stringValue().replace('/', '.'))); + builder.provides(serviceName, providers); + } + + return builder.build(); + } +} diff --git a/pom.xml b/pom.xml index a69ca3f..0f03d30 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ src/main/java/**/*.java src/main/java9/**/*.java + src/main/java22/**/*.java src/test/java/**/*.java From 83f3dff592a25a4773baca71d8ea7bb515f2433b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 17:52:26 +0000 Subject: [PATCH 3/5] Add documentation and improve Java version handling for Class File API Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- .gitignore | 1 + META-INF/MANIFEST.MF | 11 -------- plexus-java/pom.xml | 33 +++++++++++++++++++++++- plexus-java/src/main/java22/README.md | 37 +++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 12 deletions(-) delete mode 100644 META-INF/MANIFEST.MF create mode 100644 plexus-java/src/main/java22/README.md diff --git a/.gitignore b/.gitignore index f0df543..08cb729 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /plexus-java/target *.iml .idea/ +/META-INF diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF deleted file mode 100644 index e6d3c0d..0000000 --- a/META-INF/MANIFEST.MF +++ /dev/null @@ -1,11 +0,0 @@ -Manifest-Version: 1.0 -Created-By: Maven JAR Plugin 3.4.2 -Build-Jdk-Spec: 17 -Specification-Title: Plexus Languages :: Java -Specification-Version: 1.5 -Specification-Vendor: Codehaus Plexus -Implementation-Title: Plexus Languages :: Java -Implementation-Version: 1.5.1-SNAPSHOT -Implementation-Vendor: Codehaus Plexus -Multi-Release: true - diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml index 341dafe..0655a6e 100644 --- a/plexus-java/pom.xml +++ b/plexus-java/pom.xml @@ -131,7 +131,7 @@ jdk22 - [22,) + [22,24) @@ -162,6 +162,37 @@ + + jdk24 + + [24,) + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + jdk24 + + compile + + + 22 + true + + ${project.basedir}/src/main/java22 + + + + + + + + + diff --git a/plexus-java/src/main/java22/README.md b/plexus-java/src/main/java22/README.md new file mode 100644 index 0000000..f009839 --- /dev/null +++ b/plexus-java/src/main/java22/README.md @@ -0,0 +1,37 @@ +# Java 22+ Class File API Implementation + +This directory contains an implementation of the module-info parser using the Java Class File API, which was introduced as a preview feature in Java 22 (JEP 457). + +## Background + +The Class File API provides a native Java API for parsing and generating class files, eliminating the need for external libraries like ASM for this purpose. + +### Timeline + +- **Java 22** (March 2024): Preview feature (JEP 457) - requires `--enable-preview` +- **Java 23** (September 2024): Second Preview (JEP 466) - requires `--enable-preview` +- **Java 24** (March 2025): Expected to be finalized (JEP 484) - no preview flag needed + +## Implementation + +This implementation uses: +- `java.lang.classfile.ClassFile` for parsing class files +- `java.lang.classfile.attribute.ModuleAttribute` for accessing module information +- The same `JavaModuleDescriptor` builder pattern as other implementations + +## Building + +When building with Java 22 or 23, the `--enable-preview` flag is automatically added by the Maven compiler plugin configuration. + +When building with Java 24+, the preview flag should not be needed as the API should be finalized. + +When building with Java 17 or earlier, this code is not compiled, and the Java 9 implementation (using `java.lang.module.ModuleDescriptor`) is used instead. + +## Multi-Release JAR + +This implementation is part of a multi-release JAR structure: +- Java 8: Uses ASM-based parser +- Java 9-21: Uses `java.lang.module.ModuleDescriptor` +- Java 22+: Uses Class File API (this implementation) + +The appropriate version is automatically selected at runtime based on the JVM version. From 6513abb960442cce2857167d09a4ad6de95aad89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 17:54:36 +0000 Subject: [PATCH 4/5] Document Class File API support in main README Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index d299f8d..c9da454 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,13 @@ Plexus Java: * [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-java.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-java) +## Module Parsing Implementations + +Plexus Java uses a multi-release JAR to provide optimal module-info parsing for different Java versions: + +- **Java 8**: ASM-based parser for module-info.class files +- **Java 9-21**: Native `java.lang.module.ModuleDescriptor` API +- **Java 22+**: Java Class File API (JEP 457/466/484) + +The appropriate implementation is automatically selected based on the runtime JVM version. + From 20c7949866c97da27d8ab0797084b76726eaf832 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Oct 2025 22:12:57 +0000 Subject: [PATCH 5/5] Migrate from Java 22 to Java 24 to avoid preview API issues Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- README.md | 4 +- plexus-java/pom.xml | 38 +------------------ .../src/main/{java22 => java24}/README.md | 20 +++++----- .../java/jpms/BinaryModuleInfoParser.java | 0 .../jpms/ClassFileApiModuleInfoParser.java | 0 pom.xml | 2 +- 6 files changed, 14 insertions(+), 50 deletions(-) rename plexus-java/src/main/{java22 => java24}/README.md (50%) rename plexus-java/src/main/{java22 => java24}/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java (100%) rename plexus-java/src/main/{java22 => java24}/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java (100%) diff --git a/README.md b/README.md index c9da454..3d4e85d 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ Plexus Java: Plexus Java uses a multi-release JAR to provide optimal module-info parsing for different Java versions: - **Java 8**: ASM-based parser for module-info.class files -- **Java 9-21**: Native `java.lang.module.ModuleDescriptor` API -- **Java 22+**: Java Class File API (JEP 457/466/484) +- **Java 9-23**: Native `java.lang.module.ModuleDescriptor` API +- **Java 24+**: Java Class File API (JEP 484) The appropriate implementation is automatically selected based on the runtime JVM version. diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml index 0655a6e..78a5049 100644 --- a/plexus-java/pom.xml +++ b/plexus-java/pom.xml @@ -128,40 +128,6 @@ - - jdk22 - - [22,24) - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - jdk22 - - compile - - - 22 - true - - ${project.basedir}/src/main/java22 - - - --enable-preview - - - - - - - - - jdk24 @@ -180,10 +146,10 @@ compile - 22 + 24 true - ${project.basedir}/src/main/java22 + ${project.basedir}/src/main/java24 diff --git a/plexus-java/src/main/java22/README.md b/plexus-java/src/main/java24/README.md similarity index 50% rename from plexus-java/src/main/java22/README.md rename to plexus-java/src/main/java24/README.md index f009839..c9c1af4 100644 --- a/plexus-java/src/main/java22/README.md +++ b/plexus-java/src/main/java24/README.md @@ -1,6 +1,6 @@ -# Java 22+ Class File API Implementation +# Java 24+ Class File API Implementation -This directory contains an implementation of the module-info parser using the Java Class File API, which was introduced as a preview feature in Java 22 (JEP 457). +This directory contains an implementation of the module-info parser using the Java Class File API, which was finalized in Java 24 (JEP 484). ## Background @@ -8,9 +8,9 @@ The Class File API provides a native Java API for parsing and generating class f ### Timeline -- **Java 22** (March 2024): Preview feature (JEP 457) - requires `--enable-preview` -- **Java 23** (September 2024): Second Preview (JEP 466) - requires `--enable-preview` -- **Java 24** (March 2025): Expected to be finalized (JEP 484) - no preview flag needed +- **Java 22** (March 2024): Preview feature (JEP 457) +- **Java 23** (September 2024): Second Preview (JEP 466) +- **Java 24** (March 2025): Finalized (JEP 484) ## Implementation @@ -21,17 +21,15 @@ This implementation uses: ## Building -When building with Java 22 or 23, the `--enable-preview` flag is automatically added by the Maven compiler plugin configuration. +When building with Java 24+, this code is automatically compiled and included in the multi-release JAR. -When building with Java 24+, the preview flag should not be needed as the API should be finalized. - -When building with Java 17 or earlier, this code is not compiled, and the Java 9 implementation (using `java.lang.module.ModuleDescriptor`) is used instead. +When building with Java 23 or earlier, this code is not compiled, and the Java 9 implementation (using `java.lang.module.ModuleDescriptor`) is used instead. ## Multi-Release JAR This implementation is part of a multi-release JAR structure: - Java 8: Uses ASM-based parser -- Java 9-21: Uses `java.lang.module.ModuleDescriptor` -- Java 22+: Uses Class File API (this implementation) +- Java 9-23: Uses `java.lang.module.ModuleDescriptor` +- Java 24+: Uses Class File API (this implementation) The appropriate version is automatically selected at runtime based on the JVM version. diff --git a/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java b/plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java similarity index 100% rename from plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java rename to plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java diff --git a/plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java b/plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java similarity index 100% rename from plexus-java/src/main/java22/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java rename to plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java diff --git a/pom.xml b/pom.xml index 0f03d30..50705a6 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ src/main/java/**/*.java src/main/java9/**/*.java - src/main/java22/**/*.java + src/main/java24/**/*.java src/test/java/**/*.java