Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ E.g.:

Class<?> helloClass = InMemoryJavaCompiler.compile("org.mdkt.HelloClass", sourceCode.toString());

String classNames[] = new String[]{"com.compile.test.A", "com.compile.test.B"};
String sources[] = new String[]{"package com.compile.test;import com.compile.test.B;public class A{ B b;int i;}",
"package com.compile.test; public class B{String a;}"};

Class<?>[] classes = InMemoryJavaCompiler.mutilCompile(classNames, sources);

Artifact is pushed to Sonatype OSS Releases Repository

https://oss.sonatype.org/content/repositories/releases/
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/mdkt/compiler/DynamicClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ public void setCode(CompiledCode cc) {
customCompiledCode.put(cc.getName(), cc);
}

public CompiledCode getCompiledCode(String className) {
return customCompiledCode.get(className);
}

public Map<String, CompiledCode> getCustomCompiledCode() {
return customCompiledCode;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
CompiledCode cc = customCompiledCode.get(name);
Expand All @@ -27,4 +35,8 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] byteCode = cc.getByteCode();
return defineClass(name, byteCode, 0, byteCode.length);
}

public Class<?> getClass(String name, byte[] data) throws Exception {
return defineClass(name, data, 0, data.length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,25 @@ protected ExtendedStandardJavaFileManager(JavaFileManager fileManager, CompiledC
this.cl.setCode(compiledCode);
}

/**
* Creates a new instance of ForwardingJavaFileManager.
*
* @param fileManager
* @param compiledCodes
* @param cl
*/
protected ExtendedStandardJavaFileManager(JavaFileManager fileManager, CompiledCode[] compiledCodes, DynamicClassLoader cl) {
super(fileManager);
this.compiledCode = compiledCode;
this.cl = cl;
for (CompiledCode compiledCode : compiledCodes) {
this.cl.setCode(compiledCode);
}
}

@Override
public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
return compiledCode;
return cl.getCompiledCode(className);
}

@Override
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/org/mdkt/compiler/InMemoryJavaCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* Created by trung on 5/3/15.
Expand All @@ -21,4 +24,37 @@ public static Class<?> compile(String className, String sourceCodeInText) throws
boolean result = task.call();
return cl.loadClass(className);
}

public static Class<?>[] mutilCompile(String[] classNames, String[] sourceCodeInTexts) throws Exception {
if (javac == null) {
throw new Exception("ToolProvider.getSystemJavaCompiler()==null,java.home = "
+ System.getProperty("java.home") + " try to find tool.jar");
}
if (classNames.length != sourceCodeInTexts.length) {
throw new Exception("classNames length != sourceCodeInTexts length!");
}
List<SourceCode> compilationUnits = new ArrayList<SourceCode>();
CompiledCode compiledCodes[] = new CompiledCode[classNames.length];
for (int i = 0; i < classNames.length; i++) {
String className = classNames[i];
String sourceCodeInText = sourceCodeInTexts[i];
SourceCode sourceCode = new SourceCode(className, sourceCodeInText);
compiledCodes[i] = new CompiledCode(className);
compilationUnits.add(sourceCode);
}
DynamicClassLoader cl = new DynamicClassLoader(ClassLoader.getSystemClassLoader());
ExtendedStandardJavaFileManager fileManager = new ExtendedStandardJavaFileManager(javac.getStandardFileManager(null, null, null),
compiledCodes, cl);
JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, null, null, null, compilationUnits);
boolean result = task.call();
if (!result) {
throw new Exception("Compile error!!!!");
}
Map<String, CompiledCode> map = cl.getCustomCompiledCode();
List<Class<?>> list = new ArrayList<Class<?>>();
for (String key : map.keySet()) {
list.add(cl.findClass(key));
}
return list.toArray(new Class<?>[map.keySet().size()]);
}
}
11 changes: 11 additions & 0 deletions src/test/java/org/mdkt/compiler/InMemoryJavaCompilerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,15 @@ public void compile_whenTypical() throws Exception {
Assert.assertNotNull(helloClass);
Assert.assertEquals(1, helloClass.getDeclaredMethods().length);
}

@Test
public void compile_mutil_classes() throws Exception {
String classNames[] = new String[]{"com.compile.test.A", "com.compile.test.B"};
String sources[] = new String[]{"package com.compile.test;import com.compile.test.B;public class A{ B b;int i;}",
"package com.compile.test; public class B{String a;}"};

Class<?>[] classes = InMemoryJavaCompiler.mutilCompile(classNames, sources);
Assert.assertNotNull(classes);
Assert.assertEquals(classes.length, 2);
}
}