2004年11月29日

        一直以来都想在自己的代码中实现编译和运行,主要是基于这样的想法,假如用户能够根据自己的要求编写一些脚本,这样,很多维护工作就可以由具有相当经验的用户自己完成,避免因为需求一点点变动就修改源代码。前一阵子,我根据自己的理解编写了一下代码:
  public void compileAFile()
 {
  StringBuffer sb=new StringBuffer();
  sb.append("javac ");
  sb.append(this.srcFileName);
  if(this.destFileName!=null && this.destFileName!="")
  {
   sb.append(" -d ");
   sb.append(System.getProperty("java.class.path"));
  }
  Runtime rt=Runtime.getRuntime();
  try{
  System.out.println(sb.toString());
  Process p=rt.exec(sb.toString());
  p.waitFor();
  InputStream error=p.getErrorStream();
  byte[] buf=new byte[1024];
  while(error.available()!=0){
   int num=error.read(buf);
   String outStr=new String(buf,0,num,"utf-8");
   System.out.println(outStr);
  }
  }catch(Exception e){
   e.printStackTrace();
  }
 }
public void runAFile()
 {
  try{
  //String classpath=System.getProperty("java.class.path");
  //System.out.println(classpath);
  System.out.println(this.destFileName);
  Class cl=this.getClass().getClassLoader().loadClass(this.destFileName);
  Object ob=cl.newInstance();
  Method md=cl.getMethod("execute",null);
  md.invoke(ob,null);
  }catch(Exception e){
   e.printStackTrace();
  }
 }
compileAFile用来编译一个类,runAFile用来运行一个类中的已知的方法.  这样的确能够编译和运行一个类,但总觉得不好,主要是调用系统中的一个可运行程序,结果不好控制,后来看到jasperreport,这是其中的一段代码:
public String compileClass(File sourceFile, String classpath) throws JRException
 {
  String[] source = new String[3];
  source[0] = sourceFile.getPath();
  source[1] = "-classpath";
  source[2] = classpath;
  
  //ByteArrayOutputStream baos = new ByteArrayOutputStream();
  String errors = null;

  try
  {
   Class clazz = JRClassLoader.loadClassForName("com.sun.tools.javac.Main");
   Object compiler = clazz.newInstance();
   //Method compileMethod = clazz.getMethod("compile", new Class[] {String[].class, PrintWriter.class});
   Method compileMethod = clazz.getMethod("compile", new Class[] {String[].class});

   int result = ((Integer)compileMethod.invoke(compiler, new Object[] {source})).intValue();
   if(result != MODERN_COMPILER_SUCCESS)
   {
    errors = "See error messages above.";
   }
  }
  catch (Exception e)
  {
   throw new JRException("Error compiling report java source file : " + sourceFile, e);
  }

  /*
  if( baos.toString().indexOf("error") != -1 )
  {
   return baos.toString();
  }
  */
  
  return errors;
 }
当然,这是对jdk1.3的