java内存动态编译执行

一般的java的动态编译是需要先生成java文件,然后编译成class,最后用classloader加载进来生成最终的实例的。 
本例程则不需要生成任何文件,一切在内存中进行。
 
标签: <无>
 

代码片段(6)[全屏查看所有代码]

1. [代码][Java]代码     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.jui.core.dynamic;
 
public class DynaCompTest {
     public static void main(String[] args) throws Exception {
         String fullName = "DynaClass" ;
         StringBuilder src = new StringBuilder();
         src.append( "public class DynaClass {\n" );
         src.append( "    public String toString() {\n" );
         src.append( "        return \"Hello, I am \" + " );
         src.append( "this.getClass().getSimpleName();\n" );
         src.append( "    }\n" );
         src.append( "}\n" );
 
         System.out.println(src);
         DynamicEngine de = DynamicEngine.getInstance();
         Object instance =  de.javaCodeToObject(fullName,src.toString());
         System.out.println(instance);
     }
}

2. [代码][Java]代码     

?
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
package org.jui.core.dynamic;
 
import javax.tools.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.File;
 
public class DynamicEngine {
     private static DynamicEngine ourInstance = new DynamicEngine();
 
     public static DynamicEngine getInstance() {
         return ourInstance;
     }
     private URLClassLoader parentClassLoader;
     private String classpath;
     private DynamicEngine() {
         this .parentClassLoader = (URLClassLoader) this .getClass().getClassLoader();
         this .buildClassPath();
     }
     private void buildClassPath() {
         this .classpath = null ;
         StringBuilder sb = new StringBuilder();
         for (URL url : this .parentClassLoader.getURLs()) {
             String p = url.getFile();
             sb.append(p).append(File.pathSeparator);
         }
         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();
     }
}

3. [代码][Java]代码     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package org.jui.core.dynamic;
 
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import java.net.URI;
 
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;
     }
}

4. [代码][Java]代码     

?
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
package org.jui.core.dynamic;
 
import javax.tools.*;
import java.io.IOException;
import java.security.SecureClassLoader;
 
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;
     }
}

5. [代码][Java]代码     

?
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
package org.jui.core.dynamic;
 
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import java.io.IOException;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.net.URI;
 
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;
     }
}

6. [代码][Java]代码     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.jui.core.dynamic;
 
import java.net.URLClassLoader;
import java.net.URL;
 
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);
     }
}

猜你喜欢

转载自zh-ka-163-com.iteye.com/blog/2230748
今日推荐