JavaCompiler with custom ClassLoader and FileManager

classloader, java, java-compiler-api

Solution

(I assume that you're not really using a package name of "package" since that would just be illegal...)

Your custom `JavaFileManager` should be getting its `list` method invoked. Hopefully this notation makes sense, but the combination of args to that method should look like this:

[PLATFORM_CLASS_PATH, some, [CLASS], false]
[CLASS_PATH, some, [SOURCE, CLASS], false]
[PLATFORM_CLASS_PATH, some.pkg, [CLASS], false]
[CLASS_PATH, some.pkg, [SOURCE, CLASS], false]

I'm not sure how difficult it will be for your specific environment to create the appropriate `Iterable<JavaFileObject>` instances, but I think that's what would be required...

Problem

I wish to compile source without having the dependencies present on the machine. Example: File A.java: ``` import some.pkg.B; public class A extends B {...} ``` I don't have B source present, I wish to hook either JavaFileManager or a custom ClassLoader in order to get the symbols in question (the package 'some.package' and class B) and then use a service I have that retrieves the source string. The compiling code: (inputFiles has A.java) ``` JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); CustomClassLoader classLoader = new CustomClassLoader(); StandardJavaFileManager standardfileManager = compiler.getStandardFileManager(this, null, null); JavaFileManager fileManager = new CustomFileManager(standardfileManager, output, classLoader); CompilationTask task = compiler.getTask(null, fileManager, this, null, null, inputFiles); boolean result = task.call(); ``` Hooks on JavaFileManager (getFileForInput..) and on my classloader (findClass, loadClass ..) didn't triggered when compiling and I got error messages: ``` A.java:#: package some.pkg does not exist A.java:#: cannot find symbol symbol: class B ``` EDIT After playing around with the API, going over JavaCompiler (older version) source and reading Compilation Overview I still can't find an API hook I can use to provide me Symbols from the syntax trees. It seems that the API needs to get all resources based on package names as suggested by kschneid. One workaround I thought about is running the JavaCompiler and analyze the error messages for missing symbols. That way I will know which symbols are needed, get them and recompile. Any other workarounds / solutions?

Original source