我试图在中分析Java6的源代码。ANTLR4确实在词法分析方面做得很好,但是现在我想知道是否可以管理更高级的问题,比如列出继承的方法。
我的想法(根据谷歌的说法):
ToolProvider.getSystemJavaCompiler()获得系统编译器,并通过run()将源代码编译成.class文件.class文件打包到.jar并以某种方式加载它们。.class文件子弹1,4,5和6都足够干净,描述得很好。我相信nr。2可以用本教程求解。所以我的核心问题是nr。3,因为我不知道如何加载和分析.class文件。
有什么想法吗?这有可能吗?如果是这样的话,是怎么做的?你能给我推荐一个教程或例子吗?我的想法对不对?
我不喜欢使用第三方库,因为我想深入了解。
发布于 2014-06-30 17:02:50
多亏了所有的评论和谷歌,我终于明白了--基本上,我需要一个这样的例子:
/* Usage
--------
$ javac CompileJarLoadReflect.java
$ java CompileJarLoadReflect MyClass YourClass CompileJarLoadReflect
MyClass.java compilation is successful
YourClass.java compilation is successful
CompileJarLoadReflect.java compilation is successful
3 files successfully compiled
Class MyClass
myMethod
Class YourClass
yourMethod
Class CompileJarLoadReflect
main
compile
compile
load
jar
*/
/* Thanks to
------------
http://www.java2s.com/Code/Java/File-Input-Output/CreateJarfile.htm
http://stackoverflow.com/questions/194698/how-to-load-a-jar-file-at-runtime/673414#673414
*/
import javax.tools.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Method;
/** Simple compilation, packaging and loading example */
public class CompileJarLoadReflect {
/** JAR buffer size*/
public static int BUFFER_SIZE = 10 * 1024;
/** Compile all files given (by their location) */
public void compile(String[] files) throws Exception {
for (String f : files) compile(f + ".java");
System.out.println(files.length + " files successfully compiled");
}
/** Compile one particular file */
protected void compile(String f) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null, f);
if (compilationResult == 0) System.out.println(f + " compilation is successful");
else throw new Exception("Compilation error at file " + f);
}
/** Pack tobeJared classes into jarName */
public void jar(String jarName, String[] tobeJared) throws Exception {
File archiveFile = new File(jarName);
byte buffer[] = new byte[BUFFER_SIZE];
FileOutputStream stream = new FileOutputStream(archiveFile);
JarOutputStream out = new JarOutputStream(stream, new Manifest());
for (String name : tobeJared) {
File f = new File(name + ".class");
if (f == null || !f.exists() || f.isDirectory()) throw new Exception("Jar problem at file " + name);
JarEntry jarAdd = new JarEntry(f.getName());
jarAdd.setTime(f.lastModified());
out.putNextEntry(jarAdd);
FileInputStream in = new FileInputStream(f);
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0) break;
out.write(buffer, 0, nRead);
}
in.close();
}
out.close();
stream.close();
}
/** Load jar archive at jarName and then print methods of all classes in clazzes */
public void load(String jarName, String[] clazzes) throws Exception {
File file = new File(jarName);
URL url = file.toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
for (String c : clazzes) {
System.out.println("Class " + c);
Class cls = cl.loadClass(c);
Method[] methods = cls.getDeclaredMethods();
for (Method m : methods) System.out.println("\t" + m.getName());
}
}
/** Try everyting out, use params without .java */
public static void main(String[] args) {
String jarName = "output.jar";
try {
CompileJarLoadReflect cjlr = new CompileJarLoadReflect();
cjlr.compile(args);
cjlr.jar(jarName, args);
cjlr.load(jarName, args);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}我希望它能帮到别人。
https://stackoverflow.com/questions/24490860
复制相似问题