javaCompilerLoader = ServiceLoader.load(JavaCompiler.class, classLoader);
Class> c = null;
try {
- c = Class.forName(
- "org.eclipse.jdt.internal.compiler.tool.EclipseCompiler",
- false,
- BatchCompiler.class.getClassLoader());
+ c = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompiler", false, classLoader);
} catch (ClassNotFoundException e) {
// Ignore
}
diff --git a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompilerDelegate.java b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompilerDelegate.java
new file mode 100644
index 00000000..663e255d
--- /dev/null
+++ b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompilerDelegate.java
@@ -0,0 +1,44 @@
+package org.codehaus.plexus.compiler.eclipse;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CompilationProgress;
+import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
+
+/**
+ * Wraps API calls involving Java 17 class files from ECJ. {@link EclipseJavaCompiler} delegates to this class.
+ *
+ * Note: This class needs to be compiled with target 17, while all the other classes in this module can be
+ * compiled with target 11, as long as they do not directly import this class but use {@link Class#forName(String)} and
+ * method handles to invoke any methods from here.
+ */
+public class EclipseJavaCompilerDelegate {
+ static ClassLoader getClassLoader() {
+ return BatchCompiler.class.getClassLoader();
+ }
+
+ static boolean batchCompile(List args, PrintWriter devNull) {
+ return BatchCompiler.compile(
+ args.toArray(new String[0]), devNull, devNull, new BatchCompilerCompilationProgress());
+ }
+
+ private static class BatchCompilerCompilationProgress extends CompilationProgress {
+ @Override
+ public void begin(int i) {}
+
+ @Override
+ public void done() {}
+
+ @Override
+ public boolean isCanceled() {
+ return false;
+ }
+
+ @Override
+ public void setTaskName(String s) {}
+
+ @Override
+ public void worked(int i, int i1) {}
+ }
+}
diff --git a/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EclipseCompilerUnsupportedJdkTest.java b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EclipseCompilerUnsupportedJdkTest.java
new file mode 100644
index 00000000..b19a4f8d
--- /dev/null
+++ b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EclipseCompilerUnsupportedJdkTest.java
@@ -0,0 +1,63 @@
+package org.codehaus.plexus.compiler.eclipse;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.io.File;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.codehaus.plexus.compiler.Compiler;
+import org.codehaus.plexus.compiler.CompilerConfiguration;
+import org.codehaus.plexus.compiler.CompilerException;
+import org.codehaus.plexus.testing.PlexusTest;
+import org.codehaus.plexus.util.FileUtils;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
+
+import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@PlexusTest
+@Isolated("changes static variable")
+public class EclipseCompilerUnsupportedJdkTest {
+ static final boolean IS_JDK_SUPPORTED = EclipseJavaCompiler.isJdkSupported;
+
+ @Inject
+ @Named("eclipse")
+ Compiler compiler;
+
+ @BeforeAll
+ public static void setUpClass() {
+ EclipseJavaCompiler.isJdkSupported = false;
+ }
+
+ @AfterAll
+ public static void cleanUpClass() {
+ EclipseJavaCompiler.isJdkSupported = IS_JDK_SUPPORTED;
+ }
+
+ @Test
+ public void testUnsupportedJdk() {
+ CompilerException error = assertThrows(CompilerException.class, () -> compiler.performCompile(getConfig()));
+ MatcherAssert.assertThat(error.getMessage(), Matchers.containsString("ECJ needs JRE 17+"));
+ }
+
+ private CompilerConfiguration getConfig() throws Exception {
+ String sourceDir = getBasedir() + "/src/test-input/src/main";
+ Set sourceFiles = FileUtils.getFileNames(new File(sourceDir), "**/*.java", null, false, true).stream()
+ .map(File::new)
+ .collect(Collectors.toSet());
+ CompilerConfiguration compilerConfig = new CompilerConfiguration();
+ compilerConfig.addSourceLocation(sourceDir);
+ compilerConfig.setOutputLocation(getBasedir() + "/target/eclipse/classes");
+ compilerConfig.setSourceFiles(sourceFiles);
+ compilerConfig.setTargetVersion("1.8");
+ compilerConfig.setSourceVersion("1.8");
+ return compilerConfig;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 13171985..1e36098a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -182,7 +182,7 @@
maven-enforcer-plugin
- enforce-java
+ enforce-maven-and-java-bytecode
enforce
@@ -192,6 +192,15 @@
[17,)
[ERROR] OLD JDK [${java.version}] in use. This projects requires JDK 17 or newer
+
+ 11
+
+
+ org.aspectj:aspectjtools
+ org.eclipse.jdt:ecj
+ org.codehaus.plexus:plexus-compiler-eclipse
+
+