gnodet commented on issue #11642:
URL: https://github.com/apache/maven/issues/11642#issuecomment-4224389770

   ## Analysis: Making Maven 4 truly modular (JPMS)
   
   _Claude Code on behalf of Guillaume Nodet_
   
   I performed a comprehensive analysis of the Maven 4 codebase to understand 
what it would take to assign `Automatic-Module-Name` entries (and eventually 
full `module-info.java` descriptors) to all published Maven artifacts. Here are 
the findings.
   
   ---
   
   ### Current State
   
   - **No `module-info.java`** files exist anywhere in the Maven 4 codebase
   - **No `Automatic-Module-Name`** manifest entries are configured in any 
module
   - Maven 4 does have infrastructure to **detect and handle** JPMS in user 
projects (`PathModularization`, `DependencyResolverResult`), but its own JARs 
are not modularized
   
   ---
   
   ### Module Inventory
   
   | Layer | Modules | Published JARs |
   |-------|---------|----------------|
   | API | 11 | 11 |
   | Impl | 10 | 9 (maven-support has no source) |
   | Compat | 14 | 14 |
   | **Total** | **35** | **34** |
   
   ---
   
   ### Proposed Automatic Module Names
   
   #### API Modules (clean — no package overlaps among themselves)
   
   | ArtifactId | Proposed Module Name | Top-level Package |
   |------------|---------------------|-------------------|
   | maven-api-annotations | `org.apache.maven.api.annotations` | 
`org.apache.maven.api.annotations` |
   | maven-api-xml | `org.apache.maven.api.xml` | `org.apache.maven.api.xml` |
   | maven-api-model | `org.apache.maven.api.model` | 
`org.apache.maven.api.model` |
   | maven-api-settings | `org.apache.maven.api.settings` | 
`org.apache.maven.api.settings` |
   | maven-api-toolchain | `org.apache.maven.api.toolchain` | 
`org.apache.maven.api.toolchain` |
   | maven-api-metadata | `org.apache.maven.api.metadata` | 
`org.apache.maven.api.metadata` |
   | maven-api-plugin | `org.apache.maven.api.plugin.descriptor` | 
`org.apache.maven.api.plugin.descriptor` |
   | maven-api-di | `org.apache.maven.api.di` | `org.apache.maven.api.di` |
   | maven-api-core | `org.apache.maven.api` | `org.apache.maven.api` |
   | maven-api-spi | `org.apache.maven.api.spi` | `org.apache.maven.api.spi` |
   | maven-api-cli | `org.apache.maven.api.cli` | `org.apache.maven.api.cli` |
   
   #### Impl Modules
   
   | ArtifactId | Proposed Module Name | Top-level Package |
   |------------|---------------------|-------------------|
   | maven-di | `org.apache.maven.di` | `org.apache.maven.di` |
   | maven-xml | `org.apache.maven.internal.xml` | 
`org.apache.maven.internal.xml` |
   | maven-jline | `org.apache.maven.jline` | `org.apache.maven.jline` |
   | maven-logging | `org.apache.maven.logging` | 
`org.apache.maven.logging.api` |
   | maven-impl | `org.apache.maven.impl` | `org.apache.maven.impl` |
   | maven-core | `org.apache.maven.core` | `org.apache.maven` (many 
sub-packages) |
   | maven-cli | `org.apache.maven.cling` | `org.apache.maven.cling` |
   | maven-executor | `org.apache.maven.executor` | 
`org.apache.maven.cling.executor` |
   | maven-testing | `org.apache.maven.testing` | 
`org.apache.maven.api.di.testing` |
   
   #### Compat Modules (problematic — see below)
   
   | ArtifactId | Proposed Module Name | Notes |
   |------------|---------------------|-------|
   | maven-artifact | `org.apache.maven.artifact` | Split packages with 
maven-compat |
   | maven-model | `org.apache.maven.model.compat` | Split with 
maven-model-builder |
   | maven-plugin-api | `org.apache.maven.plugin.api` | Split with maven-compat 
|
   | maven-settings | `org.apache.maven.settings.compat` | Split with 
maven-compat |
   | maven-builder-support | `org.apache.maven.building` | Clean |
   | maven-repository-metadata | `org.apache.maven.repository.metadata.compat` 
| Split with maven-compat |
   | maven-model-builder | `org.apache.maven.model.builder` | Split with 
maven-model |
   | maven-settings-builder | `org.apache.maven.settings.builder` | Clean |
   | maven-toolchain-model | `org.apache.maven.toolchain.model.compat` | Clean |
   | maven-toolchain-builder | `org.apache.maven.toolchain.builder` | Clean |
   | maven-resolver-provider | `org.apache.maven.repository.internal` | Clean |
   | maven-compat | `org.apache.maven.compat` | Heavily split |
   | maven-embedder | `org.apache.maven.embedder` | Clean |
   
   ---
   
   ### Critical Issue: Split Packages
   
   JPMS forbids two named modules from exporting the same package. The analysis 
found **21 split packages** across Maven modules. These fall into three 
categories:
   
   #### 1. API ↔ Impl splits (1 split)
   
   | Package | Modules |
   |---------|---------|
   | `org.apache.maven.api.cli` | `maven-api-cli` + `maven-executor` |
   
   **Fix:** Move `Executor`, `ExecutorException`, `ExecutorRequest` from 
`maven-executor` to `maven-api-cli`, or relocate them to a distinct package 
like `org.apache.maven.executor`.
   
   #### 2. Impl ↔ Compat splits (13 splits)
   
   `maven-core` shares 13 packages with various compat modules:
   
   | Package | Compat Module(s) |
   |---------|-------------------|
   | `org.apache.maven` | maven-compat |
   | `org.apache.maven.artifact` | maven-artifact, maven-compat |
   | `org.apache.maven.artifact.handler` | maven-artifact |
   | `org.apache.maven.artifact.repository` | maven-artifact, maven-compat |
   | `org.apache.maven.artifact.repository.layout` | maven-artifact, 
maven-compat |
   | `org.apache.maven.artifact.resolver.filter` | maven-artifact, maven-compat 
|
   | `org.apache.maven.execution` | maven-compat |
   | `org.apache.maven.model.plugin` | maven-model-builder |
   | `org.apache.maven.plugin` | maven-compat, maven-plugin-api |
   | `org.apache.maven.plugin.internal` | maven-compat |
   | `org.apache.maven.project` | maven-compat |
   | `org.apache.maven.project.artifact` | maven-compat |
   | `org.apache.maven.settings` | maven-compat, maven-settings |
   
   #### 3. Compat ↔ Compat splits (13 splits)
   
   Multiple compat modules share packages among themselves (e.g., 
`maven-artifact` and `maven-compat` share 8 packages, `maven-model` and 
`maven-model-builder` share `org.apache.maven.model.merge`).
   
   #### 4. API namespace in impl layer
   
   `impl/maven-impl` contains 23 classes in 
`org.apache.maven.api.services.model` — a package using the API namespace 
convention but living in the implementation layer. This would need to be 
relocated or promoted to an API module.
   
   ---
   
   ### Recommended Approach
   
   #### Phase 1: Add `Automatic-Module-Name` to API modules (low risk, high 
value)
   
   The 11 API modules have **zero package overlaps among themselves** and form 
a clean module graph. Adding `Automatic-Module-Name` to these is safe and 
immediately unblocks downstream projects like Quarkus:
   
   ```xml
   <plugin>
     <artifactId>maven-jar-plugin</artifactId>
     <configuration>
       <archive>
         <manifestEntries>
           <Automatic-Module-Name>${module.name}</Automatic-Module-Name>
         </manifestEntries>
       </archive>
     </configuration>
   </plugin>
   ```
   
   These are the modules that downstream projects actually depend on, so this 
covers the primary use case from the issue.
   
   #### Phase 2: Add `Automatic-Module-Name` to clean impl modules (low risk)
   
   Modules like `maven-di`, `maven-xml`, `maven-jline`, `maven-logging`, and 
`maven-impl` have no package overlaps and can safely receive automatic module 
names.
   
   #### Phase 3: Fix split packages in impl layer (medium effort)
   
   - Move `org.apache.maven.api.cli.Executor*` classes out of the API namespace 
in `maven-executor`
   - Relocate `org.apache.maven.api.services.model` classes in `maven-impl` to 
`org.apache.maven.impl.model.spi` or similar
   - Address the `maven-core` splits with compat modules by relocating 
compat-side classes to distinct packages where feasible
   
   #### Phase 4: Compat layer (hard, possibly deferred)
   
   The compat modules have extensive split packages **by design** — they 
preserve the Maven 3 module/package structure where the same package was spread 
across multiple JARs. Options:
   1. **Do not modularize compat modules** — they remain on the classpath as 
unnamed modules. This is pragmatic since they are deprecated.
   2. **Merge split compat modules** into fewer JARs to eliminate splits 
(breaking change for anyone depending on individual compat JARs).
   3. **Relocate classes** to eliminate splits (breaking change for direct 
class references).
   
   Option 1 is recommended: compat modules should stay classpath-only, and 
downstream projects should migrate to the Maven 4 API.
   
   #### Phase 5: Full `module-info.java` (future)
   
   Once automatic module names are stable, full module descriptors can be added 
incrementally, starting with the leaf API modules (`maven-api-annotations`, 
`maven-api-xml`) and working up the dependency graph.
   
   ---
   
   ### Summary
   
   | Phase | Scope | Risk | Modules |
   |-------|-------|------|---------|
   | 1 | API `Automatic-Module-Name` | Low | 11 modules |
   | 2 | Clean impl `Automatic-Module-Name` | Low | 5 modules |
   | 3 | Fix impl split packages | Medium | 3 modules (executor, impl, core) |
   | 4 | Compat layer decision | High | 14 modules (recommend: leave 
classpath-only) |
   | 5 | Full `module-info.java` | High | All modules incrementally |
   
   Phase 1 alone addresses the original request and benefits downstream 
consumers. Phases 2-3 are incremental improvements. Phase 4 is a design 
decision. Phase 5 is a long-term goal.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to