Created
January 3, 2020 09:00
-
-
Save binjoo/b2230691b6524b83d8d90b4474d316f0 to your computer and use it in GitHub Desktop.
动态编译Java代码
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TrendsJava { | |
public static void main(String[] args) { | |
int i = 10; | |
String code = "System.out.println(\"Hello World!\"+(13+2*5/3));"; | |
code += "for(int i=0;i<" + i + ";i++){"; | |
code += " System.out.println(Math.pow(i,2));"; | |
code += "}"; | |
try { | |
run(code); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
private synchronized static File compile(String code) throws Exception { | |
File file = File.createTempFile("JavaRuntime", ".java", new File(Constants.BASEDIR)); | |
file.deleteOnExit(); | |
// 获得类名 | |
String classname = getBaseFileName(file); | |
// 将代码输出到文件 | |
PrintWriter out = new PrintWriter(new FileOutputStream(file)); | |
out.println(getClassCode(code, classname)); | |
out.close(); | |
// 编译生成的java文件 | |
String[] cpargs = new String[] { "-d", Constants.BASEDIR, file.getName() }; | |
System.out.println(System.getProperty("user.dir")); | |
// 动态编译 | |
JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); | |
int status = javac.run(null, null, null, "-d", Constants.BASEDIR, Constants.BASEDIR + file.getName()); | |
if (status != 0) { | |
throw new Exception("语法错误!"); | |
} | |
return file; | |
} | |
private static synchronized void run(String code) throws Exception { | |
String classname = getBaseFileName(compile(code)); | |
new File(Constants.BASEDIR + classname + Constants.SUFFIX).deleteOnExit(); | |
try { | |
MyClassLoader loader = new MyClassLoader(); | |
Class cls = loader.findClass(classname); | |
Method main = cls.getMethod("method", null); | |
main.invoke(cls, null); | |
} catch (Exception se) { | |
se.printStackTrace(); | |
} | |
} | |
// 将一块代码封装到 method函数中 | |
private static String getClassCode(String code, String className) { | |
StringBuffer text = new StringBuffer(); | |
text.append("public class " + className + "{\n"); | |
text.append(" public static void method(){\n"); | |
text.append(" " + code + "\n"); | |
text.append(" }\n"); | |
text.append("}"); | |
return text.toString(); | |
} | |
private static String getBaseFileName(File file) { | |
String fileName = file.getName(); | |
if (fileName.contains(".")) { | |
return fileName.split("\\.")[0]; | |
} else { | |
return fileName; | |
} | |
} | |
} | |
// 重写类加载器达到加载指定目录的类 | |
class MyClassLoader extends ClassLoader { | |
@Override | |
protected Class<?> findClass(String name) { | |
String myPath = new File(Constants.BASEDIR + name + Constants.SUFFIX).toURI().toString(); | |
System.out.println(myPath); | |
byte[] cLassBytes = null; | |
Path path = null; | |
try { | |
path = Paths.get(new URI(myPath)); | |
cLassBytes = Files.readAllBytes(path); | |
} catch (IOException | URISyntaxException e) { | |
e.printStackTrace(); | |
} | |
Class clazz = defineClass(name, cLassBytes, 0, cLassBytes.length); | |
return clazz; | |
} | |
} | |
// 常量 | |
interface Constants { | |
String BASEDIR = "C:\\Users\\Administrator\\Desktop\\filejava\\"; | |
String SUFFIX = ".class"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment