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/README.md b/README.md
index d299f8d..3d4e85d 100644
--- a/README.md
+++ b/README.md
@@ -12,3 +12,13 @@ Plexus Java:
* [](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-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 836b4d8..78a5049 100644
--- a/plexus-java/pom.xml
+++ b/plexus-java/pom.xml
@@ -128,6 +128,37 @@
+
+ jdk24
+
+ [24,)
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ jdk24
+
+ compile
+
+
+ 24
+ true
+
+ ${project.basedir}/src/main/java24
+
+
+
+
+
+
+
+
+
diff --git a/plexus-java/src/main/java24/README.md b/plexus-java/src/main/java24/README.md
new file mode 100644
index 0000000..c9c1af4
--- /dev/null
+++ b/plexus-java/src/main/java24/README.md
@@ -0,0 +1,35 @@
+# Java 24+ Class File API Implementation
+
+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
+
+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)
+- **Java 23** (September 2024): Second Preview (JEP 466)
+- **Java 24** (March 2025): Finalized (JEP 484)
+
+## 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 24+, this code is automatically compiled and included in the multi-release JAR.
+
+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-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/java24/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java b/plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java
new file mode 100644
index 0000000..7d50475
--- /dev/null
+++ b/plexus-java/src/main/java24/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/java24/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java b/plexus-java/src/main/java24/org/codehaus/plexus/languages/java/jpms/ClassFileApiModuleInfoParser.java
new file mode 100644
index 0000000..086324f
--- /dev/null
+++ b/plexus-java/src/main/java24/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..50705a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,7 @@
src/main/java/**/*.java
src/main/java9/**/*.java
+ src/main/java24/**/*.java
src/test/java/**/*.java