diff --git a/pom.xml b/pom.xml index 33ee638f..cd7d325f 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ under the License. 3.9.0 11 2.6.0 + 3.0.0 4.0.0-alpha-8 @@ -427,6 +428,17 @@ under the License. + + com.diffplug.spotless + spotless-maven-plugin + + + + 2.81.0 + + + + diff --git a/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java b/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java index 0a2d4d73..d42a8fe1 100644 --- a/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java +++ b/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java @@ -131,6 +131,19 @@ public void execute( } if (cacheState == INITIALIZED || skipCache) { result = cacheController.findCachedBuild(session, project, mojoExecutions, skipCache); + + // Capture validation-time properties for all mojos to ensure consistent property reading + // at the same lifecycle point for all builds (eliminates Maven 4 injection timing issues) + // Always capture when cacheState is INITIALIZED since we may need to save + if (cacheState == INITIALIZED) { + Map validationTimeEvents = + captureValidationTimeProperties(session, project, mojoExecutions); + result = CacheResult.rebuilded(result, validationTimeEvents); + LOGGER.debug( + "Captured validation-time properties for {} mojos in project {}", + validationTimeEvents.size(), + projectName); + } } } else { LOGGER.info("Cache is disabled on project level for {}", projectName); @@ -163,8 +176,16 @@ public void execute( .isEmpty()) { LOGGER.info("Cache storing is skipped since there was no \"clean\" phase."); } else { - final Map executionEvents = mojoListener.getProjectExecutions(project); - cacheController.save(result, mojoExecutions, executionEvents); + // Validation-time events must exist for cache storage + // If they don't exist, this indicates a bug in the capture logic + if (result.getValidationTimeEvents() == null + || result.getValidationTimeEvents().isEmpty()) { + throw new AssertionError( + "Validation-time properties not captured for project " + projectName + + ". This is a bug - validation-time capture should always succeed when saving to cache."); + } + LOGGER.debug("Using validation-time properties for cache storage (consistent lifecycle point)"); + cacheController.save(result, mojoExecutions, result.getValidationTimeEvents()); } } @@ -434,6 +455,63 @@ private static String normalizedPath(Path path, Path baseDirPath) { return normalizedPath; } + /** + * Captures plugin properties at validation time for all mojo executions. + * This ensures properties are read at the same lifecycle point for all builds, + * eliminating timing mismatches caused by Maven 4's auto-injection of properties + * like --module-version during execution. + * + * @param session Maven session + * @param project Current project + * @param mojoExecutions List of mojo executions to capture properties for + * @return Map of execution key to MojoExecutionEvent captured at validation time + */ + private Map captureValidationTimeProperties( + MavenSession session, MavenProject project, List mojoExecutions) { + Map validationTimeEvents = new java.util.HashMap<>(); + + for (MojoExecution mojoExecution : mojoExecutions) { + // Skip mojos that don't execute or are in clean phase + if (mojoExecution.getLifecyclePhase() == null + || !lifecyclePhasesHelper.isLaterPhaseThanClean(mojoExecution.getLifecyclePhase())) { + continue; + } + + Mojo mojo = null; + try { + mojoExecutionScope.enter(); + mojoExecutionScope.seed(MavenProject.class, project); + mojoExecutionScope.seed(MojoExecution.class, mojoExecution); + + mojo = mavenPluginManager.getConfiguredMojo(Mojo.class, session, mojoExecution); + MojoExecutionEvent event = new MojoExecutionEvent(session, project, mojoExecution, mojo); + validationTimeEvents.put(mojoExecutionKey(mojoExecution), event); + + LOGGER.debug( + "Captured validation-time properties for {}", + mojoExecution.getMojoDescriptor().getFullGoalName()); + + } catch (PluginConfigurationException | PluginContainerException e) { + LOGGER.warn( + "Cannot capture validation-time properties for {}: {}", + mojoExecution.getMojoDescriptor().getFullGoalName(), + e.getMessage()); + } finally { + try { + mojoExecutionScope.exit(); + } catch (MojoExecutionException e) { + LOGGER.debug("Error exiting mojo execution scope: {}", e.getMessage()); + } + if (mojo != null) { + mavenPluginManager.releaseMojo(mojo, mojoExecution); + } + } + } + + LOGGER.debug("Captured validation-time properties for {} mojos", validationTimeEvents.size()); + return validationTimeEvents; + } + private enum CacheRestorationStatus { SUCCESS, FAILURE, diff --git a/src/main/java/org/apache/maven/buildcache/CacheResult.java b/src/main/java/org/apache/maven/buildcache/CacheResult.java index e2c118b1..096cdb3b 100644 --- a/src/main/java/org/apache/maven/buildcache/CacheResult.java +++ b/src/main/java/org/apache/maven/buildcache/CacheResult.java @@ -18,8 +18,11 @@ */ package org.apache.maven.buildcache; +import java.util.Map; + import org.apache.maven.buildcache.xml.Build; import org.apache.maven.buildcache.xml.CacheSource; +import org.apache.maven.execution.MojoExecutionEvent; import static java.util.Objects.requireNonNull; @@ -31,49 +34,91 @@ public class CacheResult { private final RestoreStatus status; private final Build build; private final CacheContext context; + private final Map validationTimeEvents; - private CacheResult(RestoreStatus status, Build build, CacheContext context) { + private CacheResult( + RestoreStatus status, + Build build, + CacheContext context, + Map validationTimeEvents) { this.status = requireNonNull(status); this.build = build; this.context = context; + this.validationTimeEvents = validationTimeEvents; } public static CacheResult empty(CacheContext context) { requireNonNull(context); - return new CacheResult(RestoreStatus.EMPTY, null, context); + return new CacheResult(RestoreStatus.EMPTY, null, context, null); + } + + public static CacheResult empty(CacheContext context, Map validationTimeEvents) { + requireNonNull(context); + return new CacheResult(RestoreStatus.EMPTY, null, context, validationTimeEvents); } public static CacheResult empty() { - return new CacheResult(RestoreStatus.EMPTY, null, null); + return new CacheResult(RestoreStatus.EMPTY, null, null, null); } public static CacheResult failure(Build build, CacheContext context) { requireNonNull(build); requireNonNull(context); - return new CacheResult(RestoreStatus.FAILURE, build, context); + return new CacheResult(RestoreStatus.FAILURE, build, context, null); + } + + public static CacheResult failure( + Build build, CacheContext context, Map validationTimeEvents) { + requireNonNull(build); + requireNonNull(context); + return new CacheResult(RestoreStatus.FAILURE, build, context, validationTimeEvents); } public static CacheResult success(Build build, CacheContext context) { requireNonNull(build); requireNonNull(context); - return new CacheResult(RestoreStatus.SUCCESS, build, context); + return new CacheResult(RestoreStatus.SUCCESS, build, context, null); + } + + public static CacheResult success( + Build build, CacheContext context, Map validationTimeEvents) { + requireNonNull(build); + requireNonNull(context); + return new CacheResult(RestoreStatus.SUCCESS, build, context, validationTimeEvents); } public static CacheResult partialSuccess(Build build, CacheContext context) { requireNonNull(build); requireNonNull(context); - return new CacheResult(RestoreStatus.PARTIAL, build, context); + return new CacheResult(RestoreStatus.PARTIAL, build, context, null); + } + + public static CacheResult partialSuccess( + Build build, CacheContext context, Map validationTimeEvents) { + requireNonNull(build); + requireNonNull(context); + return new CacheResult(RestoreStatus.PARTIAL, build, context, validationTimeEvents); } public static CacheResult failure(CacheContext context) { requireNonNull(context); - return new CacheResult(RestoreStatus.FAILURE, null, context); + return new CacheResult(RestoreStatus.FAILURE, null, context, null); + } + + public static CacheResult failure(CacheContext context, Map validationTimeEvents) { + requireNonNull(context); + return new CacheResult(RestoreStatus.FAILURE, null, context, validationTimeEvents); } public static CacheResult rebuilded(CacheResult orig, Build build) { requireNonNull(orig); requireNonNull(build); - return new CacheResult(orig.status, build, orig.context); + return new CacheResult(orig.status, build, orig.context, orig.validationTimeEvents); + } + + public static CacheResult rebuilded(CacheResult orig, Map validationTimeEvents) { + requireNonNull(orig); + return new CacheResult(orig.status, orig.build, orig.context, validationTimeEvents); } public boolean isSuccess() { @@ -103,4 +148,8 @@ public RestoreStatus getStatus() { public boolean isFinal() { return build != null && build.getDto().is_final(); } + + public Map getValidationTimeEvents() { + return validationTimeEvents; + } } diff --git a/src/test/java/org/apache/maven/buildcache/its/ExplicitModuleVersionTest.java b/src/test/java/org/apache/maven/buildcache/its/ExplicitModuleVersionTest.java new file mode 100644 index 00000000..51388e36 --- /dev/null +++ b/src/test/java/org/apache/maven/buildcache/its/ExplicitModuleVersionTest.java @@ -0,0 +1,83 @@ +/* + * 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. + */ +package org.apache.maven.buildcache.its; + +import org.apache.maven.buildcache.its.junit.IntegrationTest; +import org.apache.maven.it.VerificationException; +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.Test; + +/** + * Integration test for JPMS module compilation with explicit moduleVersion configuration. + * + *

This test verifies that the validation-time property capture approach works correctly + * when the moduleVersion is explicitly configured in the POM. Unlike Maven 4's auto-injection + * scenario, this configuration is present at validation time, so there's no timing mismatch. + * However, validation-time capture should still work correctly. + * + *

This test verifies: + *

    + *
  1. First build creates cache entry with validation-time properties
  2. + *
  3. Second build restores from cache successfully
  4. + *
  5. Explicit configuration is captured correctly at validation time
  6. + *
+ */ +@IntegrationTest("src/test/projects/explicit-module-version") +class ExplicitModuleVersionTest { + + /** + * Verifies that JPMS module compilation with explicit moduleVersion works with cache restoration. + * This tests that validation-time capture works correctly when moduleVersion is explicitly + * configured in the POM (no Maven 4 auto-injection needed). + * + * @param verifier Maven verifier for running builds + * @throws VerificationException if verification fails + */ + @Test + void testExplicitModuleVersionCacheRestoration(Verifier verifier) throws VerificationException { + verifier.setAutoclean(false); + + // First build - should create cache entry with validation-time properties + verifier.setLogFileName("../log-build-1.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify compilation succeeded + verifier.verifyFilePresent("target/classes/module-info.class"); + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/explicit/ExplicitVersionModule.class"); + + // Second build - should restore from cache + verifier.setLogFileName("../log-build-2.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify cache was used (not rebuilt) + verifier.verifyTextInLog( + "Found cached build, restoring org.apache.maven.caching.test.explicit:explicit-module-version from cache"); + + // Verify compilation was skipped (restored from cache) + verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile"); + + // Verify output files were restored from cache + verifier.verifyFilePresent("target/classes/module-info.class"); + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/explicit/ExplicitVersionModule.class"); + } +} diff --git a/src/test/java/org/apache/maven/buildcache/its/Maven4JpmsModuleTest.java b/src/test/java/org/apache/maven/buildcache/its/Maven4JpmsModuleTest.java new file mode 100644 index 00000000..e3ab9087 --- /dev/null +++ b/src/test/java/org/apache/maven/buildcache/its/Maven4JpmsModuleTest.java @@ -0,0 +1,89 @@ +/* + * 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. + */ +package org.apache.maven.buildcache.its; + +import org.apache.maven.buildcache.its.junit.IntegrationTest; +import org.apache.maven.it.VerificationException; +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.Test; + +/** + * Integration test for Maven 4 JPMS module compilation with automatic --module-version injection. + * + *

This test verifies that issue #375 is fixed by the validation-time property capture approach. + * Maven 4 automatically injects {@code --module-version ${project.version}} into compiler arguments + * during execution. Without the fix, this creates a timing mismatch: + *

    + *
  • First build: Properties captured during execution (WITH injection)
  • + *
  • Second build: Properties captured during validation (WITHOUT injection yet)
  • + *
  • Result: Cache invalidation due to parameter mismatch
  • + *
+ * + *

The fix captures properties at validation time for ALL builds, ensuring consistent reading + * at the same lifecycle point. This test verifies: + *

    + *
  1. First build creates cache entry
  2. + *
  3. Second build restores from cache (NO cache invalidation)
  4. + *
  5. NO {@code ignorePattern} configuration required
  6. + *
+ */ +@IntegrationTest("src/test/projects/maven4-jpms-module") +class Maven4JpmsModuleTest { + + /** + * Verifies that Maven 4 JPMS module compilation works with cache restoration. + * Maven 4 auto-injects {@code --module-version} during compilation, but the + * validation-time capture approach ensures this doesn't cause cache invalidation. + * + * @param verifier Maven verifier for running builds + * @throws VerificationException if verification fails + */ + @Test + void testMaven4JpmsModuleCacheRestoration(Verifier verifier) throws VerificationException { + verifier.setAutoclean(false); + + // First build - should create cache entry with validation-time properties + verifier.setLogFileName("../log-build-1.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify compilation succeeded + verifier.verifyFilePresent("target/classes/module-info.class"); + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/maven4/HelloMaven4.class"); + + // Second build - should restore from cache WITHOUT invalidation + // This is the critical test: validation-time properties should match stored properties + verifier.setLogFileName("../log-build-2.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify cache was used (not rebuilt) - this proves the fix works! + verifier.verifyTextInLog( + "Found cached build, restoring org.apache.maven.caching.test.maven4:maven4-jpms-module from cache"); + + // Verify compilation was skipped (restored from cache) + verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile"); + + // Verify output files were restored from cache + verifier.verifyFilePresent("target/classes/module-info.class"); + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/maven4/HelloMaven4.class"); + } +} diff --git a/src/test/java/org/apache/maven/buildcache/its/MultiModuleJpmsTest.java b/src/test/java/org/apache/maven/buildcache/its/MultiModuleJpmsTest.java new file mode 100644 index 00000000..f7dcc0e4 --- /dev/null +++ b/src/test/java/org/apache/maven/buildcache/its/MultiModuleJpmsTest.java @@ -0,0 +1,89 @@ +/* + * 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. + */ +package org.apache.maven.buildcache.its; + +import org.apache.maven.buildcache.its.junit.IntegrationTest; +import org.apache.maven.it.VerificationException; +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.Test; + +/** + * Integration test for multi-module project with JPMS modules using validation-time property capture. + * + *

This test verifies that the validation-time property capture approach works correctly + * in multi-module projects where some modules are JPMS modules and some are regular Java modules. + * This ensures that validation-time capture scales properly across project structures. + * + *

This test verifies: + *

    + *
  1. First build creates cache entries for all modules
  2. + *
  3. Second build restores all modules from cache successfully
  4. + *
  5. Validation-time capture works consistently across multiple modules
  6. + *
+ */ +@IntegrationTest("src/test/projects/multi-module-jpms") +class MultiModuleJpmsTest { + + /** + * Verifies that multi-module project with JPMS modules works with cache restoration. + * This ensures validation-time capture scales across multiple modules correctly. + * + * @param verifier Maven verifier for running builds + * @throws VerificationException if verification fails + */ + @Test + void testMultiModuleJpmsCacheRestoration(Verifier verifier) throws VerificationException { + verifier.setAutoclean(false); + + // First build - should create cache entries for all modules + verifier.setLogFileName("../log-build-1.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify compilation succeeded for module-a (JPMS) + verifier.verifyFilePresent("module-a/target/classes/module-info.class"); + verifier.verifyFilePresent("module-a/target/classes/org/apache/maven/caching/test/multi/modulea/ModuleA.class"); + + // Verify compilation succeeded for module-b (non-JPMS) + verifier.verifyFilePresent("module-b/target/classes/org/apache/maven/caching/test/multi/moduleb/ModuleB.class"); + + // Second build - should restore all modules from cache + verifier.setLogFileName("../log-build-2.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify module-a was restored from cache + verifier.verifyTextInLog( + "Found cached build, restoring org.apache.maven.caching.test.multi:module-a from cache"); + verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile"); + + // Verify module-b was restored from cache + verifier.verifyTextInLog( + "Found cached build, restoring org.apache.maven.caching.test.multi:module-b from cache"); + + // Verify output files were restored from cache for module-a + verifier.verifyFilePresent("module-a/target/classes/module-info.class"); + verifier.verifyFilePresent("module-a/target/classes/org/apache/maven/caching/test/multi/modulea/ModuleA.class"); + + // Verify output files were restored from cache for module-b + verifier.verifyFilePresent("module-b/target/classes/org/apache/maven/caching/test/multi/moduleb/ModuleB.class"); + } +} diff --git a/src/test/java/org/apache/maven/buildcache/its/NonJpmsProjectTest.java b/src/test/java/org/apache/maven/buildcache/its/NonJpmsProjectTest.java new file mode 100644 index 00000000..e65f100c --- /dev/null +++ b/src/test/java/org/apache/maven/buildcache/its/NonJpmsProjectTest.java @@ -0,0 +1,80 @@ +/* + * 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. + */ +package org.apache.maven.buildcache.its; + +import org.apache.maven.buildcache.its.junit.IntegrationTest; +import org.apache.maven.it.VerificationException; +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.Test; + +/** + * Integration test for non-JPMS Java project with validation-time property capture. + * + *

This test verifies that the validation-time property capture approach doesn't introduce + * regressions for regular (non-JPMS) Java projects. These projects don't use module-info.java + * and don't trigger Maven 4's --module-version auto-injection, so they should work correctly + * with validation-time capture. + * + *

This test verifies: + *

    + *
  1. First build creates cache entry for non-JPMS project
  2. + *
  3. Second build restores from cache successfully
  4. + *
  5. No regressions introduced for regular Java projects
  6. + *
+ */ +@IntegrationTest("src/test/projects/non-jpms-project") +class NonJpmsProjectTest { + + /** + * Verifies that non-JPMS Java project compilation works correctly with cache restoration. + * This ensures validation-time capture doesn't introduce regressions for regular Java projects. + * + * @param verifier Maven verifier for running builds + * @throws VerificationException if verification fails + */ + @Test + void testNonJpmsProjectCacheRestoration(Verifier verifier) throws VerificationException { + verifier.setAutoclean(false); + + // First build - should create cache entry with validation-time properties + verifier.setLogFileName("../log-build-1.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify compilation succeeded + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/nonjpms/RegularJavaClass.class"); + + // Second build - should restore from cache + verifier.setLogFileName("../log-build-2.txt"); + verifier.executeGoal("clean"); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + + // Verify cache was used (not rebuilt) + verifier.verifyTextInLog( + "Found cached build, restoring org.apache.maven.caching.test.nonjpms:non-jpms-project from cache"); + + // Verify compilation was skipped (restored from cache) + verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile"); + + // Verify output files were restored from cache + verifier.verifyFilePresent("target/classes/org/apache/maven/caching/test/nonjpms/RegularJavaClass.class"); + } +} diff --git a/src/test/projects/explicit-module-version/.mvn/extensions.xml b/src/test/projects/explicit-module-version/.mvn/extensions.xml new file mode 100644 index 00000000..9eea7f26 --- /dev/null +++ b/src/test/projects/explicit-module-version/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + org.apache.maven.extensions + maven-build-cache-extension + ${projectVersion} + + diff --git a/src/test/projects/explicit-module-version/.mvn/maven-build-cache-config.xml b/src/test/projects/explicit-module-version/.mvn/maven-build-cache-config.xml new file mode 100644 index 00000000..fcfc182d --- /dev/null +++ b/src/test/projects/explicit-module-version/.mvn/maven-build-cache-config.xml @@ -0,0 +1,16 @@ + + + + true + SHA-256 + + + + + + + + + + diff --git a/src/test/projects/explicit-module-version/pom.xml b/src/test/projects/explicit-module-version/pom.xml new file mode 100644 index 00000000..9fa8d7bb --- /dev/null +++ b/src/test/projects/explicit-module-version/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + org.apache.maven.caching.test.explicit + explicit-module-version + 1.0.0-SNAPSHOT + jar + + Explicit Module Version Test + Test project for JPMS module with explicit moduleVersion configuration + + + UTF-8 + 11 + 11 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + + --module-version + ${project.version} + -parameters + -g + + + + + + diff --git a/src/test/projects/explicit-module-version/src/main/java/module-info.java b/src/test/projects/explicit-module-version/src/main/java/module-info.java new file mode 100644 index 00000000..cff12c3b --- /dev/null +++ b/src/test/projects/explicit-module-version/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module org.apache.maven.caching.test.explicit { + exports org.apache.maven.caching.test.explicit; +} diff --git a/src/test/projects/explicit-module-version/src/main/java/org/apache/maven/caching/test/explicit/ExplicitVersionModule.java b/src/test/projects/explicit-module-version/src/main/java/org/apache/maven/caching/test/explicit/ExplicitVersionModule.java new file mode 100644 index 00000000..aedd8504 --- /dev/null +++ b/src/test/projects/explicit-module-version/src/main/java/org/apache/maven/caching/test/explicit/ExplicitVersionModule.java @@ -0,0 +1,7 @@ +package org.apache.maven.caching.test.explicit; + +public class ExplicitVersionModule { + public String getMessage() { + return "Hello from JPMS module with explicit version!"; + } +} diff --git a/src/test/projects/maven4-jpms-module/.mvn/extensions.xml b/src/test/projects/maven4-jpms-module/.mvn/extensions.xml new file mode 100644 index 00000000..9eea7f26 --- /dev/null +++ b/src/test/projects/maven4-jpms-module/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + org.apache.maven.extensions + maven-build-cache-extension + ${projectVersion} + + diff --git a/src/test/projects/maven4-jpms-module/.mvn/maven-build-cache-config.xml b/src/test/projects/maven4-jpms-module/.mvn/maven-build-cache-config.xml new file mode 100644 index 00000000..43e9abc6 --- /dev/null +++ b/src/test/projects/maven4-jpms-module/.mvn/maven-build-cache-config.xml @@ -0,0 +1,16 @@ + + + + true + SHA-256 + + + + + + + + + + diff --git a/src/test/projects/maven4-jpms-module/pom.xml b/src/test/projects/maven4-jpms-module/pom.xml new file mode 100644 index 00000000..bb810052 --- /dev/null +++ b/src/test/projects/maven4-jpms-module/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.apache.maven.caching.test.maven4 + maven4-jpms-module + 1.0.0-SNAPSHOT + + + 11 + 11 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + + + -parameters + -g + + + + + + diff --git a/src/test/projects/maven4-jpms-module/src/main/java/module-info.java b/src/test/projects/maven4-jpms-module/src/main/java/module-info.java new file mode 100644 index 00000000..44332f07 --- /dev/null +++ b/src/test/projects/maven4-jpms-module/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module org.apache.maven.caching.test.maven4 { + exports org.apache.maven.caching.test.maven4; +} diff --git a/src/test/projects/maven4-jpms-module/src/main/java/org/apache/maven/caching/test/maven4/HelloMaven4.java b/src/test/projects/maven4-jpms-module/src/main/java/org/apache/maven/caching/test/maven4/HelloMaven4.java new file mode 100644 index 00000000..2bc10f4b --- /dev/null +++ b/src/test/projects/maven4-jpms-module/src/main/java/org/apache/maven/caching/test/maven4/HelloMaven4.java @@ -0,0 +1,7 @@ +package org.apache.maven.caching.test.maven4; + +public class HelloMaven4 { + public String getMessage() { + return "Hello from Maven 4 JPMS module!"; + } +} diff --git a/src/test/projects/multi-module-jpms/.mvn/extensions.xml b/src/test/projects/multi-module-jpms/.mvn/extensions.xml new file mode 100644 index 00000000..9eea7f26 --- /dev/null +++ b/src/test/projects/multi-module-jpms/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + org.apache.maven.extensions + maven-build-cache-extension + ${projectVersion} + + diff --git a/src/test/projects/multi-module-jpms/.mvn/maven-build-cache-config.xml b/src/test/projects/multi-module-jpms/.mvn/maven-build-cache-config.xml new file mode 100644 index 00000000..466b6061 --- /dev/null +++ b/src/test/projects/multi-module-jpms/.mvn/maven-build-cache-config.xml @@ -0,0 +1,16 @@ + + + + true + SHA-256 + + + + + + + + + + diff --git a/src/test/projects/multi-module-jpms/module-a/pom.xml b/src/test/projects/multi-module-jpms/module-a/pom.xml new file mode 100644 index 00000000..45d4ca27 --- /dev/null +++ b/src/test/projects/multi-module-jpms/module-a/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + org.apache.maven.caching.test.multi + multi-module-jpms + 1.0.0-SNAPSHOT + + + module-a + jar + + Module A (JPMS) + JPMS module with Maven 4 auto-injection + diff --git a/src/test/projects/multi-module-jpms/module-a/src/main/java/module-info.java b/src/test/projects/multi-module-jpms/module-a/src/main/java/module-info.java new file mode 100644 index 00000000..5be6ec5b --- /dev/null +++ b/src/test/projects/multi-module-jpms/module-a/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module org.apache.maven.caching.test.multi.modulea { + exports org.apache.maven.caching.test.multi.modulea; +} diff --git a/src/test/projects/multi-module-jpms/module-a/src/main/java/org/apache/maven/caching/test/multi/modulea/ModuleA.java b/src/test/projects/multi-module-jpms/module-a/src/main/java/org/apache/maven/caching/test/multi/modulea/ModuleA.java new file mode 100644 index 00000000..b99cf51e --- /dev/null +++ b/src/test/projects/multi-module-jpms/module-a/src/main/java/org/apache/maven/caching/test/multi/modulea/ModuleA.java @@ -0,0 +1,7 @@ +package org.apache.maven.caching.test.multi.modulea; + +public class ModuleA { + public String getMessage() { + return "Hello from Module A (JPMS)!"; + } +} diff --git a/src/test/projects/multi-module-jpms/module-b/pom.xml b/src/test/projects/multi-module-jpms/module-b/pom.xml new file mode 100644 index 00000000..4319094a --- /dev/null +++ b/src/test/projects/multi-module-jpms/module-b/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + org.apache.maven.caching.test.multi + multi-module-jpms + 1.0.0-SNAPSHOT + + + module-b + jar + + Module B (Non-JPMS) + Regular Java module without JPMS + diff --git a/src/test/projects/multi-module-jpms/module-b/src/main/java/org/apache/maven/caching/test/multi/moduleb/ModuleB.java b/src/test/projects/multi-module-jpms/module-b/src/main/java/org/apache/maven/caching/test/multi/moduleb/ModuleB.java new file mode 100644 index 00000000..3372e221 --- /dev/null +++ b/src/test/projects/multi-module-jpms/module-b/src/main/java/org/apache/maven/caching/test/multi/moduleb/ModuleB.java @@ -0,0 +1,7 @@ +package org.apache.maven.caching.test.multi.moduleb; + +public class ModuleB { + public String getMessage() { + return "Hello from Module B (non-JPMS)!"; + } +} diff --git a/src/test/projects/multi-module-jpms/pom.xml b/src/test/projects/multi-module-jpms/pom.xml new file mode 100644 index 00000000..f974f779 --- /dev/null +++ b/src/test/projects/multi-module-jpms/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + org.apache.maven.caching.test.multi + multi-module-jpms + 1.0.0-SNAPSHOT + pom + + Multi-Module JPMS Test + Test project for multi-module with mixed JPMS and non-JPMS modules + + + module-a + module-b + + + + UTF-8 + 11 + 11 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + -parameters + -g + + + + + + + diff --git a/src/test/projects/non-jpms-project/.mvn/extensions.xml b/src/test/projects/non-jpms-project/.mvn/extensions.xml new file mode 100644 index 00000000..9eea7f26 --- /dev/null +++ b/src/test/projects/non-jpms-project/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + org.apache.maven.extensions + maven-build-cache-extension + ${projectVersion} + + diff --git a/src/test/projects/non-jpms-project/.mvn/maven-build-cache-config.xml b/src/test/projects/non-jpms-project/.mvn/maven-build-cache-config.xml new file mode 100644 index 00000000..a7b48de4 --- /dev/null +++ b/src/test/projects/non-jpms-project/.mvn/maven-build-cache-config.xml @@ -0,0 +1,16 @@ + + + + true + SHA-256 + + + + + + + + + + diff --git a/src/test/projects/non-jpms-project/pom.xml b/src/test/projects/non-jpms-project/pom.xml new file mode 100644 index 00000000..dd3884b4 --- /dev/null +++ b/src/test/projects/non-jpms-project/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.apache.maven.caching.test.nonjpms + non-jpms-project + 1.0.0-SNAPSHOT + jar + + Non-JPMS Project Test + Test project for regular Java project without JPMS + + + UTF-8 + 11 + 11 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + + -parameters + -g + + + + + + diff --git a/src/test/projects/non-jpms-project/src/main/java/org/apache/maven/caching/test/nonjpms/RegularJavaClass.java b/src/test/projects/non-jpms-project/src/main/java/org/apache/maven/caching/test/nonjpms/RegularJavaClass.java new file mode 100644 index 00000000..379d4e20 --- /dev/null +++ b/src/test/projects/non-jpms-project/src/main/java/org/apache/maven/caching/test/nonjpms/RegularJavaClass.java @@ -0,0 +1,7 @@ +package org.apache.maven.caching.test.nonjpms; + +public class RegularJavaClass { + public String getMessage() { + return "Hello from regular Java class!"; + } +}