in src/main/java/org/apache/maven/plugins/scripting/engine/JavaEngine.java [91:168]
public CompiledScript compile(String script) throws ScriptException {
// plexus compiler is great but overkill there so don't bring it just for that
final JavaCompiler compiler =
requireNonNull(ToolProvider.getSystemJavaCompiler(), "you must run on a JDK to have a compiler");
Path tmpDir = null;
try {
tmpDir = Files.createTempDirectory(getClass().getSimpleName());
final String packageName = getClass().getPackage().getName() + ".generated";
final String className = "JavaCompiledScript_" + Math.abs(script.hashCode());
final String source = toSource(packageName, className, script);
final Path src = tmpDir.resolve("sources");
final Path bin = tmpDir.resolve("bin");
final Path srcDir = src.resolve(packageName.replace('.', '/'));
Files.createDirectories(srcDir);
Files.createDirectories(bin);
final Path java = srcDir.resolve(className + ".java");
try (Writer writer = Files.newBufferedWriter(java)) {
writer.write(source);
}
// TODO: make it configurable from the project in subsequent releases
final String classpath = mavenClasspathPrefix()
+ System.getProperty(
getClass().getName() + ".classpath",
System.getProperty("java.class.path", System.getProperty("surefire.real.class.path")));
// TODO: use a Logger in subsequent releases. Not very important as of now, so using std streams
final int run = compiler.run(
null,
System.out,
System.err,
Stream.of(
"-classpath",
classpath,
"-sourcepath",
src.toAbsolutePath().toString(),
"-d",
bin.toAbsolutePath().toString(),
java.toAbsolutePath().toString())
.toArray(String[]::new));
if (run != 0) {
throw new IllegalArgumentException(
"Can't compile the incoming script, here is the generated code: >\n" + source + "\n<\n");
}
final URLClassLoader loader = new URLClassLoader(
new URL[] {bin.toUri().toURL()}, Thread.currentThread().getContextClassLoader());
final Class<? extends CompiledScript> loadClass =
loader.loadClass(packageName + '.' + className).asSubclass(CompiledScript.class);
return loadClass
.getConstructor(ScriptEngine.class, URLClassLoader.class)
.newInstance(this, loader);
} catch (Exception e) {
throw new ScriptException(e);
} finally {
if (tmpDir != null) {
try {
Files.walkFileTree(tmpDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
if (log != null) {
log.debug(e);
}
}
}
}
}