Reputation: 815
We have an app that's been migrated from a traditional WAR Spring web application to what we had hoped would be a modern Spring Boot executable Jar.
One of the app modules uses the JavaCompiler
API to generate Java code and compile it in runtime.
The generated code requires dependencies that reside in the web app classpath, and so we had roughly the following code:
StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
List<String> optionList = new ArrayList<String>();
// set compiler's classpath to be same as the runtime's
String classpathString = System.getProperty("java.class.path");
optionList.addAll(Arrays.asList("-nowarn",
"-classpath",
classpathString,
"-g",
"-source",
javaVersion,
"-target",
javaVersion));
Collection classpathFiles = getClasspathJars(classpathString);
addPreviousCompiledClassesToClasspathFiles(rootClassPath, classpathFiles);
try {
File file = new File(getTargetRoot(tempClassPath));
file.mkdirs();
standardFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Lists.newArrayList(file));
standardFileManager.setLocation(StandardLocation.CLASS_PATH, classpathFiles);
// adding current dir to the source path, to find the compiled DV
if (generateSeparateJarsForEachDecision.equals(NO_JAR)) {
standardFileManager.setLocation(StandardLocation.SOURCE_PATH, Lists.newArrayList(file));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
List<CharSequenceJavaFileObject> compilationUnits = Lists
.newArrayList(new CharSequenceJavaFileObject( StringUtils.capitalize(filename),
toString(javaCode)));
JavaCompiler.CompilationTask task = compiler
.getTask(writer, standardFileManager, listener, optionList, null, compilationUnits);
status = task.call();
```
However, that doesn't work with Boot.
The classpath only contains my-app.jar
, and I can't add any of the nested jars to the -cp
of the task - it just won't those nested jars.
I've also attempted to manually add the to the -cp
parameter them like so: {absolute-path}/my-app.jar!/BOOT-INF/lib/my-dep.jar
{absolute-path}/my-app.jar!/BOOT-INF/lib/*.jar
None of those worked.
Thought about using the <requiresUnpack>
tag on build too, but that didn't seem to help because I couldn't get a hold of the expanded dir in order to add it to the classpath.
Upvotes: 8
Views: 920
Reputation: 3
Faced similar issue.
Looks like a limitation with spring boot.
So created a standalone application with Jersey and Tomcat embedded.
Now jar contains all libraries and able to set it as class path to Java Compiler
Upvotes: 0