Liny_@NotePad

沉迷ACG中

试下动态编译。。

YOYO posted @ 2009年11月06日 19:17 in 【Java SE】 with tags 动态编译 反射 , 2214 阅读

 前几天看到了 今天米事就来写一写, = = 期间遇到了两个问题:
用eclipse来写com.sun.tools找不到,以及运行时找不到文件(java.lang.ClassNotFoundException)。。

先贴代码:

  1. package org.yoyo.test;
  2.  
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. import java.lang.reflect.InvocationTargetException;
  7. import java.lang.reflect.Method;
  8. import java.net.MalformedURLException;
  9. import java.net.URL;
  10. import java.net.URLClassLoader;
  11. import java.util.Scanner;
  12.  
  13. import com.sun.tools.javac.Main;
  14.  
  15. /**
  16. * 动态编译测试
  17. * @author YOYO
  18. */
  19. public class RuntimeCompileTest {
  20.  
  21.         /**
  22.          * CompileMain
  23.          */
  24.         private static Main javac = new Main();
  25.  
  26.         /**
  27.          * 创建临时文件存放代码
  28.          * @param codes
  29.          * @return
  30.          */
  31.         private File createFile(String codes) {
  32.                 try {
  33.                         File file = File.createTempFile("RuntimeCompile_", ".java",
  34.                                         new File(System.getProperty("user.dir")));
  35.                         String className = getClassName(file);
  36.                         PrintWriter writer = new PrintWriter(file);
  37.                         writer.write("public class " + className + " {" + "\r\n");
  38.                         writer.write("  public static void main(String[] args) {" + "\r\n");
  39.                         writer.write(codes);
  40.                         writer.write("  }" + "\r\n");
  41.                         writer.write("}" + "\r\n");
  42.                         writer.flush();
  43.                         writer.close();
  44.  
  45.                         return file;
  46.                 } catch (IOException e) {
  47.                         e.printStackTrace();
  48.                         return null;
  49.                 }
  50.         }
  51.  
  52.         /**
  53.          * 输入代码
  54.          * @return
  55.          */
  56.         private String inputCode() {
  57.                 StringBuffer codes = new StringBuffer("");
  58.  
  59.                 System.out.println("请输入Java代码:");
  60.                 Scanner scanner = new Scanner(System.in);
  61.                 while (scanner.hasNext()) {
  62.                         codes.append(scanner.nextLine() + "\r\n");
  63.                 }
  64.                 scanner.close();
  65.  
  66.                 return new String(codes);
  67.         }
  68.  
  69.         /**
  70.          * 编译
  71.          * @param fileName
  72.          * @return
  73.          */
  74.         @SuppressWarnings("static-access")
  75.         private synchronized int compile(String fileName) {
  76.                 String[] args = new String[] {"-d", System.getProperty("user.dir"), fileName};
  77.                 return javac.compile(args);
  78.         }
  79.  
  80.         /**
  81.          * 执行
  82.          * @param file
  83.          * @return
  84.          */
  85.         @SuppressWarnings("unchecked")
  86.         private synchronized boolean run(File file) {
  87.                 new File(file.getParent(), getClassName(file) + ".class").deleteOnExit();
  88.                 try {
  89.                         URL url = new URL("file:/" + System.getProperty("user.dir") + ""
  90.                                         + File.separator);
  91.                         URLClassLoader urlClass = new URLClassLoader(new URL[] { url });
  92.                         Class clazz = urlClass.loadClass(getClassName(file));
  93.                         Method main = clazz.getMethod("main",
  94.                                         new Class[] { String[].class });
  95.                         main.invoke(null, new Object[] { new String[0] });
  96.  
  97.                         return true;
  98.                 } catch (ClassNotFoundException e) {
  99.                         e.printStackTrace();
  100.                 } catch (SecurityException e) {
  101.                         e.printStackTrace();
  102.                 } catch (NoSuchMethodException e) {
  103.                         e.printStackTrace();
  104.                 } catch (IllegalArgumentException e) {
  105.                         e.printStackTrace();
  106.                 } catch (IllegalAccessException e) {
  107.                         e.printStackTrace();
  108.                 } catch (InvocationTargetException e) {
  109.                         e.printStackTrace();
  110.                 } catch (MalformedURLException e) {
  111.                         e.printStackTrace();
  112.                 }
  113.  
  114.                 return false;
  115.         }
  116.  
  117.         /**
  118.          * 获得类名
  119.          * @param file
  120.          * @return
  121.          */
  122.         private String getClassName(File file) {
  123.                 return file.getName().substring(0,
  124.                                 file.getName().length() - ".java".length());
  125.         }
  126.  
  127.         /**
  128.          * 测试
  129.          * @return
  130.          */
  131.         public boolean newTest() {
  132.                 File file = createFile(inputCode());
  133.                 if ("".equals(file.getName()) || 0 != compile(file.getName())) {
  134.                         return false;
  135.                 }
  136.                 return run(file);
  137.         }
  138.  
  139.         /**
  140.          * @param args
  141.          */
  142.         public static void main(String[] args) {
  143.                 System.out.println("Test : " + new RuntimeCompileTest().newTest());
  144.         }
  145.  
  146. }

com.sun.tools找不到的解决方法:在项目属性-Libraries里面加上jdk下面的tools.jar包即可。

java.lang.ClassNotFoundException引起原因:我原来用的是Class.forName(...)方法,这个方法只加载ClassPath里面的类,因此找不到。。
改成上面代码中的URLClassLoader来读取就可以了。

测试一下。。。:

请输入Java代码:
for (int i = 0; i < 26; ++i) {
 System.out.print((char)('A' + i));
}
System.out.println();

ABCDEFGHIJKLMNOPQRSTUVWXYZ
Test : true
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter