-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJavaCodeCompiler.java
More file actions
133 lines (113 loc) · 5.1 KB
/
Copy pathJavaCodeCompiler.java
File metadata and controls
133 lines (113 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package run.myCode.compiler;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class JavaCodeCompiler {
private static final boolean DEBUG = Boolean.getBoolean("run.mycode.debug");
/**
* Compile Java source files into memory
*
* @param files a List of JavaFileObjects containing the source code to
* compile
* @param options a List of compiler options (null means none)
* @return The compiled main class
* @throws ClassNotFoundException
*/
public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> files, List<String> options)
throws ClassNotFoundException {
return compile(files, JavaCodeCompiler.class.getClassLoader(), options);
}
/**
* Compile Java source files into memory
*
* @param files a List of JavaFileObjects containing the source code to
* compile
* @param urlcl a ClassLoader that contains dependencies of the files being
* compiled
* @param options a List of compiler options (null means none)
*
* @return A classloader containing the compiled classes and their dependencies
*
* @throws ClassNotFoundException
*/
public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> files, ClassLoader urlcl,
List<String> options) throws ClassNotFoundException {
final FromMemoryClassLoader classLoader = new FromMemoryClassLoader(urlcl);
// get system compiler:
// Use the standard Java compiler provided by the JDK. This avoids ECJ
// attempting to resolve in-memory sources on disk which resulted in
// "File ... is missing" errors during tests.
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// create a diagnostic listener for compilation diagnostic message processing on
// compilation WARNING/ERROR
final CompileDiagnosticListener diag = new CompileDiagnosticListener();
final StandardJavaFileManager stdfileManager = compiler.getStandardFileManager(diag, Locale.ENGLISH, null);
InMemoryJavaFileManager fileManager = new InMemoryJavaFileManager(stdfileManager, classLoader);
for (JavaFileObject file : files) {
fileManager.addSource(file);
if (DEBUG) {
System.out.println("Compiling source " + file.getName());
}
}
// specify options for compiler
if (options == null) {
options = new ArrayList<>();
}
// Build the classpath from the current folder and the system classpath
StringBuilder classpathBuilder =
new StringBuilder("." +
System.getProperty("path.separator") +
System.getProperty("java.class.path"));
// Add any included jar files from the lib folder to the classpath (wildcard isn't working)
try {
Files.list(new File("/var/task/lib/").toPath())
.filter(s -> s.toString().endsWith(".jar") || s.toString().endsWith(".JAR"))
.forEach(f -> {
classpathBuilder.append(System.getProperty("path.separator"));
classpathBuilder.append(f.toString());
});
}
catch (NoSuchFileException ex) {
// if the /var/task/lib folder doesn't exist, no problem.
//Logger.getLogger(JavaCodeCompiler.class.getName()).log(Level.INFO, null, ex);
}
catch (IOException ex) {
Logger.getLogger(JavaCodeCompiler.class.getName()).log(Level.SEVERE, null, ex);
}
String classpath = classpathBuilder.toString();
// System.out.println(">> " + classpath + " <<");
// Set the classpath and java version for the compiler
options.addAll(Arrays.asList("-classpath",
classpath));
options.addAll(Arrays.asList("--release", "17"));
Writer out = new PrintWriter(System.out);
// Compile the code
JavaCompiler.CompilationTask task = compiler.getTask(out, fileManager, diag, options, null, files);
if (DEBUG) {
System.out.println("Starting compilation with mem URIs");
}
boolean result = task.call();
if (!result) {
for (String msg : diag.getFormattedDiagnostics()) {
System.out.println(msg);
System.out.println();
}
throw new ClassNotFoundException("Compilation failed");
}
// Return the classloader containing the compiled classes
return classLoader;
}
}