|
34 | 34 | import java.io.File;
|
35 | 35 | import java.io.PrintWriter;
|
36 | 36 | import java.io.StringWriter;
|
| 37 | +import java.lang.invoke.MethodHandle; |
| 38 | +import java.lang.invoke.MethodHandles; |
| 39 | +import java.lang.invoke.MethodType; |
37 | 40 | import java.nio.charset.Charset;
|
38 | 41 | import java.nio.charset.IllegalCharsetNameException;
|
39 | 42 | import java.nio.charset.UnsupportedCharsetException;
|
|
52 | 55 | import org.codehaus.plexus.compiler.CompilerOutputStyle;
|
53 | 56 | import org.codehaus.plexus.compiler.CompilerResult;
|
54 | 57 | import org.codehaus.plexus.util.StringUtils;
|
55 |
| -import org.eclipse.jdt.core.compiler.CompilationProgress; |
56 |
| -import org.eclipse.jdt.core.compiler.batch.BatchCompiler; |
57 | 58 |
|
58 | 59 | /**
|
59 | 60 | *
|
|
63 | 64 | public class EclipseJavaCompiler extends AbstractCompiler {
|
64 | 65 | public EclipseJavaCompiler() {
|
65 | 66 | super(CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE, ".java", ".class", null);
|
| 67 | + if (Runtime.version().feature() < 17) throw new EcjFailureException("ECJ only works on Java 17+"); |
| 68 | + try { |
| 69 | + // Do not directly import EclipseJavaCompilerDelegate or any ECJ classes compiled to target 17. |
| 70 | + // This ensures that the plugin still runs on Java 11 and can report the error above. |
| 71 | + Class<?> delegateClass = Class.forName("org.codehaus.plexus.compiler.eclipse.EclipseJavaCompilerDelegate"); |
| 72 | + MethodHandles.Lookup lookup = MethodHandles.lookup(); |
| 73 | + MethodType getClassLoaderMT = MethodType.methodType(ClassLoader.class); |
| 74 | + MethodType batchCompileMT = MethodType.methodType(boolean.class, List.class, PrintWriter.class); |
| 75 | + getClassLoaderMH = lookup.findStatic(delegateClass, "getClassLoader", getClassLoaderMT); |
| 76 | + batchCompileMH = lookup.findStatic(delegateClass, "batchCompile", batchCompileMT); |
| 77 | + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { |
| 78 | + throw new RuntimeException(e); |
| 79 | + } |
66 | 80 | }
|
67 | 81 |
|
68 | 82 | // ----------------------------------------------------------------------
|
69 | 83 | // Compiler Implementation
|
70 | 84 | // ----------------------------------------------------------------------
|
71 | 85 | boolean errorsAsWarnings = false;
|
| 86 | + private final MethodHandle getClassLoaderMH; |
| 87 | + private final MethodHandle batchCompileMH; |
72 | 88 |
|
73 | 89 | @Override
|
74 | 90 | public String getCompilerId() {
|
@@ -324,31 +340,15 @@ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
324 | 340 |
|
325 | 341 | getLog().debug("ecj command line: " + args);
|
326 | 342 |
|
327 |
| - success = BatchCompiler.compile( |
328 |
| - args.toArray(new String[args.size()]), devNull, devNull, new CompilationProgress() { |
329 |
| - @Override |
330 |
| - public void begin(int i) {} |
331 |
| - |
332 |
| - @Override |
333 |
| - public void done() {} |
334 |
| - |
335 |
| - @Override |
336 |
| - public boolean isCanceled() { |
337 |
| - return false; |
338 |
| - } |
339 |
| - |
340 |
| - @Override |
341 |
| - public void setTaskName(String s) {} |
342 |
| - |
343 |
| - @Override |
344 |
| - public void worked(int i, int i1) {} |
345 |
| - }); |
| 343 | + success = (boolean) batchCompileMH.invoke(args, devNull); |
346 | 344 | getLog().debug(sw.toString());
|
347 | 345 |
|
348 | 346 | if (errorF.length() < 80) {
|
349 | 347 | throw new EcjFailureException(sw.toString());
|
350 | 348 | }
|
351 | 349 | messageList = new EcjResponseParser().parse(errorF, errorsAsWarnings);
|
| 350 | + } catch (Throwable e) { |
| 351 | + throw new Exception(e); |
352 | 352 | } finally {
|
353 | 353 | if (null != errorF) {
|
354 | 354 | try {
|
@@ -508,14 +508,16 @@ private static boolean haveSourceOrReleaseArgument(List<String> args) {
|
508 | 508 | }
|
509 | 509 |
|
510 | 510 | private JavaCompiler getEcj() {
|
511 |
| - ServiceLoader<JavaCompiler> javaCompilerLoader = |
512 |
| - ServiceLoader.load(JavaCompiler.class, BatchCompiler.class.getClassLoader()); |
| 511 | + ClassLoader classLoader; |
| 512 | + try { |
| 513 | + classLoader = (ClassLoader) getClassLoaderMH.invoke(); |
| 514 | + } catch (Throwable e) { |
| 515 | + throw new RuntimeException(e); |
| 516 | + } |
| 517 | + ServiceLoader<JavaCompiler> javaCompilerLoader = ServiceLoader.load(JavaCompiler.class, classLoader); |
513 | 518 | Class<?> c = null;
|
514 | 519 | try {
|
515 |
| - c = Class.forName( |
516 |
| - "org.eclipse.jdt.internal.compiler.tool.EclipseCompiler", |
517 |
| - false, |
518 |
| - BatchCompiler.class.getClassLoader()); |
| 520 | + c = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompiler", false, classLoader); |
519 | 521 | } catch (ClassNotFoundException e) {
|
520 | 522 | // Ignore
|
521 | 523 | }
|
|
0 commit comments