- package com.mclon.jmxsgl.service.impl;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.URI;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.tools.Diagnostic;
- import javax.tools.DiagnosticCollector;
- import javax.tools.FileObject;
- import javax.tools.ForwardingJavaFileManager;
- import javax.tools.JavaCompiler;
- import javax.tools.JavaFileObject;
- import javax.tools.SimpleJavaFileObject;
- import javax.tools.StandardJavaFileManager;
- import javax.tools.ToolProvider;
- /**
- * 动态编译代码类
- *
- * @author zhangxu
- *
- */
- public class DynamicEngine {
- public static DynamicEngine getInstance() {
- return new DynamicEngine();
- }
- private URLClassLoader parentClassLoader;
- private static String classpath;
- private DynamicEngine() {
- this.parentClassLoader = (URLClassLoader) this.getClass()
- .getClassLoader();
- this.buildClassPath();
- }
- private void buildClassPath() {
- if (classpath == null) {
- StringBuilder sb = new StringBuilder();
- Map<String, String> filePath = new HashMap<String, String>();
- // 读取容器lib
- try {
- Enumeration<URL> urls = Thread.currentThread()
- .getContextClassLoader().getResources(".");
- String tomPath = urls.nextElement().getPath();
- File file = new File(tomPath);
- if (file.isDirectory()) {
- File[] fList = file.listFiles();
- for (int j = 0; j < fList.length; j++) {
- if (fList[j].isFile()
- && (fList[j].getName().contains(".jar"))) {
- fList[j].getPath();
- filePath.put(fList[j].getName(),
- tomPath + fList[j].getName());
- }
- }
- } else if (file.getName().contains(".jar")) {
- }
- } catch (Exception e) {
- System.out.println("Error: " + e);
- }
- // 读取工程lib
- for (URL url : this.parentClassLoader.getURLs()) {
- String p = url.getFile();
- File file = new File(url.toString());
- String fileName = file.getName();
- filePath.put(fileName, p);
- }
- // 组装classpath
- for (String key : filePath.keySet()) {
- sb.append(filePath.get(key)).append(File.pathSeparator);
- }
- System.out.println(sb.toString());
- this.classpath = sb.toString();
- }
- }
- public Object javaCodeToObject(String fullClassName, String javaCode)
- throws IllegalAccessException, InstantiationException {
- long start = System.currentTimeMillis();
- Object instance = null;
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
- ClassFileManager fileManager = new ClassFileManager(
- compiler.getStandardFileManager(diagnostics, null, null));
- List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();
- jfiles.add(new CharSequenceJavaFileObject(fullClassName, javaCode));
- List<String> options = new ArrayList<String>();
- options.add("-encoding");
- options.add("UTF-8");
- options.add("-classpath");
- options.add(this.classpath);
- JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
- diagnostics, options, null, jfiles);
- boolean success = task.call();
- if (success) {
- JavaClassObject jco = fileManager.getJavaClassObject();
- DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(
- this.parentClassLoader);
- Class clazz = dynamicClassLoader.loadClass(fullClassName, jco);
- instance = clazz.newInstance();
- } else {
- String error = "";
- for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
- error = error + compilePrint(diagnostic);
- }
- }
- long end = System.currentTimeMillis();
- System.out.println("javaCodeToObject use:" + (end - start) + "ms");
- return instance;
- }
- private String compilePrint(Diagnostic diagnostic) {
- System.out.println("Code:" + diagnostic.getCode());
- System.out.println("Kind:" + diagnostic.getKind());
- System.out.println("Position:" + diagnostic.getPosition());
- System.out.println("Start Position:" + diagnostic.getStartPosition());
- System.out.println("End Position:" + diagnostic.getEndPosition());
- System.out.println("Source:" + diagnostic.getSource());
- System.out.println("Message:" + diagnostic.getMessage(null));
- System.out.println("LineNumber:" + diagnostic.getLineNumber());
- System.out.println("ColumnNumber:" + diagnostic.getColumnNumber());
- StringBuffer res = new StringBuffer();
- res.append("Code:[" + diagnostic.getCode() + "]\\n");
- res.append("Kind:[" + diagnostic.getKind() + "]\\n");
- res.append("Position:[" + diagnostic.getPosition() + "]\\n");
- res.append("Start Position:[" + diagnostic.getStartPosition() + "]\\n");
- res.append("End Position:[" + diagnostic.getEndPosition() + "]\\n");
- res.append("Source:[" + diagnostic.getSource() + "]\\n");
- res.append("Message:[" + diagnostic.getMessage(null) + "]\\n");
- res.append("LineNumber:[" + diagnostic.getLineNumber() + "]\\n");
- res.append("ColumnNumber:[" + diagnostic.getColumnNumber() + "]\\n");
- return res.toString();
- }
- public class CharSequenceJavaFileObject extends SimpleJavaFileObject {
- private CharSequence content;
- public CharSequenceJavaFileObject(String className, CharSequence content) {
- super(URI.create("string:///" + className.replace('.', '/')
- + JavaFileObject.Kind.SOURCE.extension),
- JavaFileObject.Kind.SOURCE);
- this.content = content;
- }
- @Override
- public CharSequence getCharContent(boolean ignoreEncodingErrors) {
- return content;
- }
- }
- public class ClassFileManager extends ForwardingJavaFileManager {
- public JavaClassObject getJavaClassObject() {
- return jclassObject;
- }
- private JavaClassObject jclassObject;
- public ClassFileManager(StandardJavaFileManager standardManager) {
- super(standardManager);
- }
- @Override
- public JavaFileObject getJavaFileForOutput(Location location,
- String className, JavaFileObject.Kind kind, FileObject sibling)
- throws IOException {
- jclassObject = new JavaClassObject(className, kind);
- return jclassObject;
- }
- }
- public class JavaClassObject extends SimpleJavaFileObject {
- protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- public JavaClassObject(String name, JavaFileObject.Kind kind) {
- super(URI.create("string:///" + name.replace('.', '/')
- + kind.extension), kind);
- }
- public byte[] getBytes() {
- return bos.toByteArray();
- }
- @Override
- public OutputStream openOutputStream() throws IOException {
- return bos;
- }
- }
- public class DynamicClassLoader extends URLClassLoader {
- public DynamicClassLoader(ClassLoader parent) {
- super(new URL[0], parent);
- }
- public Class findClassByClassName(String className)
- throws ClassNotFoundException {
- return this.findClass(className);
- }
- public Class loadClass(String fullName, JavaClassObject jco) {
- byte[] classData = jco.getBytes();
- return this.defineClass(fullName, classData, 0, classData.length);
- }
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/1808201513479.html
来源: http://www.codesnippet.cn/detail/1808201513479.html