Use javac API in plugin
I want to run custom AnnotationProcessor from the plugin and I've found that javac API can be invoked easily from the java code itself. Like
compiler = ToolProvider.getSystemJavaCompiler();
...
task.setProcessors(Collections.singleton(p));
However, when I tried to invoke it from the Intellij Plugin, there was this error
> Error: Unable to find package java.lang in classpath or bootclasspath
I have correct jre setup, and I can build and compile my project from the IntelliJ. So I can't see why the classpath is incorrect.
Things that didn't help
Using another class loader to load compiler class
ClassLoader.getSystemClassLoader();
Object compiler = callStaticMethod(classLoader, JavacTool.class, "create");
Adding compiler options to the compilation task
String root = "/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home";
final List<String> options = Arrays.asList(
"-Xbootclasspath/p:" + root,
"-classpath", root);
JavaCompiler.CompilationTask task = compiler.getTask(outWriter, fileManager, diagnostics, options, Collections.singleton(qualifiedName), Collections.singleton(source));
Adding url to the UrlClassLoader before calling compiler
String pathname = "/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/rt.jar";
File pathElement = new File(pathname);
URL url = pathElement.toPath().normalize().toUri().toURL();
callInstanceMethod(urlClassLoader, "addURL", new Class[]{URL.class}, url);
I'm still seeing this error "Unable to find package java.lang in classpath or bootclasspath"
Anyone has ideas how to configure plugin to run javac API?
Please sign in to leave a comment.
Please explain in more detail, what "run custom AnnotationProcessor from the plugin" means exactly
- how is this related to IJ plugin
- what code is instrumented
- what is triggering it
Yann Cebron I've attached a sample project to showcase idea
>>>> file <<<<
root
-- comp (Java module)
---- MyProcessor.java (AnnotationProcessor I try getting invoked)
---- Formatter.java (file retrieving and calling javac from the code)
-- ide (IJ module)
---- ParseAction (IJ action get called by the user)
When a user clicks "ParseAction" from the Editor menu, it calls Formatter.
Expected: AnnotationProcessor is triggered
Actual: error "Unable to find package java.lang in classpath or bootclasspath" is written during task#call
I've been struggling with this blocker for a few weeks already, trying different combinations (mentioned in the question). It would be amazing if you can see the root of a problem and help me fix it.
My guess this is because "comp" module classes are loaded with `UriClassLoader`. But I don't see a way to change it: even when other class loader is set per thread, javac classes are still loaded with `UriClassLoader`.
Sergey I see you had similar project long time in the past, maybe you can help?
Did you try any of the given workaround from the other thread?
Yes, actually, I changed the calling class to enum, removed custom Context and DiagnosticCollector, and change FileManger implementation, and it worked in the end. Not sure what exactly helped..