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();

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

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 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 <<<<


-- comp (Java module)

---- (AnnotationProcessor I try getting invoked)

---- (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..


Please sign in to leave a comment.