From a36dfa969bc4a38048ad3d12c9f5951e349774c5 Mon Sep 17 00:00:00 2001 From: Andy Boothe Date: Tue, 7 Jan 2025 14:00:59 -0600 Subject: [PATCH] start updating tests to run against exact simulated classpath --- pom.xml | 49 ++++++++++++-- rapier-core/pom.xml | 6 +- .../test/java/rapier/core/DaggerTestBase.java | 66 +++++++++++++++++-- .../src/test/java/rapier/core/util/Maven.java | 37 +++++++++++ .../processor/cli/CliProcessorTest.java | 5 +- 5 files changed, 146 insertions(+), 17 deletions(-) create mode 100644 rapier-core/src/test/java/rapier/core/util/Maven.java diff --git a/pom.xml b/pom.xml index 2378d38..5197fca 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,13 @@ 11 11 11 + + + 2.54 + 1 + 2.0.1 + 3.0.2 @@ -63,16 +69,29 @@ maven-surefire-plugin 3.5.2 - + - --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED - --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED - --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED - --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + --add-exports + jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + --add-opens + jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + --add-exports + jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + --add-opens + jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + --add-exports + jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + --add-opens + jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + + ${dagger.version} + ${javax.inject.version} + ${jakarta.inject-api.version} + ${jsr305.version} + @@ -205,6 +224,22 @@ dagger-compiler ${dagger.version} + + javax.inject + javax.inject + ${javax.inject.version} + + + jakarta.inject + jakarta.inject-api + ${jakarta.inject-api.version} + + + com.google.code.findbugs + jsr305 + ${jsr305.version} + + com.google.testing.compile compile-testing diff --git a/rapier-core/pom.xml b/rapier-core/pom.xml index 4cc250b..0b214b7 100644 --- a/rapier-core/pom.xml +++ b/rapier-core/pom.xml @@ -32,12 +32,14 @@ javax.inject javax.inject - 1 jakarta.inject jakarta.inject-api - 2.0.1 + + + com.google.code.findbugs + jsr305 com.google.dagger diff --git a/rapier-core/src/test/java/rapier/core/DaggerTestBase.java b/rapier-core/src/test/java/rapier/core/DaggerTestBase.java index 0714606..36f3035 100644 --- a/rapier-core/src/test/java/rapier/core/DaggerTestBase.java +++ b/rapier-core/src/test/java/rapier/core/DaggerTestBase.java @@ -19,6 +19,7 @@ */ package rapier.core; +import static java.util.stream.Collectors.joining; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -34,6 +35,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -43,8 +45,7 @@ import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; - - +import rapier.core.util.Maven; public abstract class DaggerTestBase { @SuppressWarnings("serial") @@ -122,8 +123,12 @@ protected String compileAndRunSourceCode(List compilationUnitSourceCodes try { // Dynamically load the compiled classes - try (URLClassLoader classLoader = new URLClassLoader(new URL[] {tempDir.toURI().toURL()}, - Thread.currentThread().getContextClassLoader())) { + final List classpath = new ArrayList<>(); + for (File simulationClasspathEntry : simulationClasspath()) + classpath.add(simulationClasspathEntry.toURI().toURL()); + classpath.add(tempDir.toURI().toURL()); + try (URLClassLoader classLoader = new URLClassLoader(classpath.toArray(URL[]::new), + ClassLoader.getPlatformClassLoader())) { final Class mainClass = classLoader.loadClass(mainCompilationUnitName); @@ -200,6 +205,7 @@ private String compileSourceCode(File tempDir, List compilationUnitSourc "JavaCompiler not available. Make sure JDK is used instead of JRE."); } + // Write the source files to disk final List sourceFiles = new ArrayList<>(); for (final String compilationUnitSourceCode : compilationUnitSourceCodes) { final Matcher classNameMatcher = @@ -219,9 +225,13 @@ private String compileSourceCode(File tempDir, List compilationUnitSourc // Set up diagnostic collector to capture compilation errors DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + // Set up our classpath + final String classpath = simulationClasspath().stream().map(File::getAbsolutePath) + .collect(joining(File.pathSeparator)); + // Configure annotation processors (include Dagger's processor) - List options = List.of("-processor", String.join(",", annotationProcessors), "-s", - tempDir.getAbsolutePath()); + List options = List.of("-cp", classpath, "-processor", + String.join(",", annotationProcessors), "-s", tempDir.getAbsolutePath()); // Compile the source file try (StandardJavaFileManager fileManager = @@ -244,4 +254,48 @@ private String compileSourceCode(File tempDir, List compilationUnitSourc return errors; } } + + /** + * The Dagger version to use for compiling test code. This should be passed by + * maven-surefire-plugin using the exact dagger version from the POM. See the root POM for the + * specific details of the setup. + */ + private static final String DAGGER_VERSION = + Optional.ofNullable(System.getProperty("dagger.version")) + .orElseThrow(() -> new IllegalStateException("dagger.version system property not set")); + + /** + * The javax.inject version to use for compiling test code. This should be passed by + * maven-surefire-plugin using the exact javax.inject version from the POM. See the root POM for + * the specific details of the setup. + */ + private static final String JAVAX_INJECT_VERSION = + Optional.ofNullable(System.getProperty("javax.inject.version")).orElseThrow( + () -> new IllegalStateException("javax.inject.version system property not set")); + + /** + * The Jakarta Inject API version to use for compiling test code. This should be passed by + * maven-surefire-plugin using the exact Jakarta Inject API version from the POM. See the root POM + * for the specific details + */ + private static final String JAKARTA_INJECT_API_VERSION = + Optional.ofNullable(System.getProperty("jakarta.inject-api.version")).orElseThrow( + () -> new IllegalStateException("jakarta.inject-api.version system property not set")); + + private static final String JSR_305_VERSION = + Optional.ofNullable(System.getProperty("jsr305.version")).orElseThrow( + () -> new IllegalStateException("jsr305.version system property not set")); + + + private List simulationClasspath() { + final File daggerJar = + Maven.findJarInLocalRepository("com.google.dagger", "dagger", DAGGER_VERSION); + final File javaxInjectJar = + Maven.findJarInLocalRepository("javax.inject", "javax.inject", JAVAX_INJECT_VERSION); + final File jakartaInjectApiJar = Maven.findJarInLocalRepository("jakarta.inject", + "jakarta.inject-api", JAKARTA_INJECT_API_VERSION); + final File jsr305Jar = Maven.findJarInLocalRepository("com.google.code.findbugs", + "jsr305", JSR_305_VERSION); + return List.of(daggerJar, javaxInjectJar, jakartaInjectApiJar, jsr305Jar); + } } diff --git a/rapier-core/src/test/java/rapier/core/util/Maven.java b/rapier-core/src/test/java/rapier/core/util/Maven.java new file mode 100644 index 0000000..7297957 --- /dev/null +++ b/rapier-core/src/test/java/rapier/core/util/Maven.java @@ -0,0 +1,37 @@ +package rapier.core.util; + +import java.io.File; + +public final class Maven { + private Maven() {} + + private static final String LOCAL_REPO_PATH = System.getProperty("user.home") + "/.m2/repository"; + + /** + * Finds the JAR file for a given Maven artifact in the local repository. Makes no attempt to + * download the artifact if it does not exist in the local cache. For this reason, this method + * should generally only be used for artifacts that are present in the build, since the build will + * guarantee that the artifact is present in the local repository. + * + * @param groupId The group ID of the artifact + * @param artifactId The artifact ID of the artifact + * @param version The version of the artifact + * @return An Optional containing the JAR file if it exists, or an empty Optional otherwise + */ + public static File findJarInLocalRepository(String groupId, String artifactId, String version) { + // Convert groupId to directory path (e.g., org.apache.maven -> org/apache/maven) + final String groupPath = groupId.replace('.', '/'); + + // Construct the path to the JAR file + final String jarPath = String.format("%s/%s/%s/%s/%s-%s.jar", LOCAL_REPO_PATH, groupPath, + artifactId, version, artifactId, version); + + // Return the JAR file as a File object + final File jarFile = new File(jarPath); + + if (!jarFile.exists()) + throw new IllegalArgumentException("JAR file does not exist: " + jarFile); + + return jarFile; + } +} diff --git a/rapier-processor-cli/src/test/java/rapier/processor/cli/CliProcessorTest.java b/rapier-processor-cli/src/test/java/rapier/processor/cli/CliProcessorTest.java index e3f49ae..63f2eb6 100644 --- a/rapier-processor-cli/src/test/java/rapier/processor/cli/CliProcessorTest.java +++ b/rapier-processor-cli/src/test/java/rapier/processor/cli/CliProcessorTest.java @@ -20,6 +20,7 @@ package rapier.processor.cli; import static com.google.testing.compile.CompilationSubject.assertThat; +import static java.util.Collections.emptyList; import javax.tools.JavaFileObject; import org.junit.jupiter.api.Test; import com.google.testing.compile.Compilation; @@ -49,8 +50,8 @@ public interface ExampleComponent { """); // Run the annotation processor - final Compilation compilation = - Compiler.javac().withProcessors(new CliProcessor()).compile(source); + final Compilation compilation = Compiler.javac().withClasspath(emptyList()) + .withProcessors(new CliProcessor()).compile(source); // Assert the compilation succeeded assertThat(compilation).succeeded();