Compile Java contained in a String

A bit of hacking around lead to the following example. Create an instance of InMemorySourceCompiler and pass it the name of the program and the source code as a String. Any suggestions/improvements are appreciated as a comment to this answer.

The following example creates a JFrame that contains the output of the source.

Main.java:

import java.lang.reflect.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
  
import sun.tools.javac.*;  
import sun.tools.java.*;
   
public class Main extends JFrame
{
   public Main(String s) {
      getContentPane().add(new JTextArea(s, 3, 50));
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
  
   public static void main(String args[]) throws Exception
   {
      // Save all data written to System.out to a byte array and display in frame
      PrintStream ps = System.out;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      System.setOut(new PrintStream(baos));
 
      InMemorySourceCompiler imsCompiler = new InMemorySourceCompiler("Test",
          "public class Test {" +
          "   public static void main(String args[]) {" +
          "      System.out.println("Output of program:");" +
          "      for (int i=0; i<10; i++) {" +
          "         System.out.println(i);" +
          "      }" +
          "      System.out.println("End of output.");" + 
          "   }" +
          "}");
      imsCompiler.executeMain();
 
      byte[] b = baos.toByteArray();
 
      System.setOut(ps);
 
      String s = new String(b);
 
      Main main = new Main(s);
      main.setSize(200, 230);
      main.setVisible(true);  
   }
}
       
class InMemorySourceCompiler {
   protected String name;
   protected String source;
   protected Class compiledClass;
  
   public InMemorySourceCompiler(String name, String source) throws Exception {
      this.name = name;
      this.source = source;
      loadClass();
   }
 
   protected void loadClass() throws Exception {
      ClassPath cp = new ClassPath(System.getProperty("java.class.path"));
      OutputStream os = System.out;
      BatchEnvironment be = new BatchEnvironment(os, cp);
      be.flags = 0x41004;
      be.majorVersion = 45;
      be.minorVersion = 3;
      be.covFile = null;
      be.setCharacterEncoding(null);
 
      be.parseFile(new InMemorySourceClassFile(name+".java", source));
 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 
      be.flushErrors();
      Vector v = new Vector();
 
      for (Enumeration enum = be.getClasses(); enum.hasMoreElements();) {
         v.addElement(enum.nextElement());
      }
 
      for (int i=0; i<v.size(); i++) {
         ClassDeclaration cd = (ClassDeclaration) v.elementAt(i);
         Object object = cd.getClassDefinition(be);
 
         if (object instanceof SourceClass) {
            SourceClass sourceclass = (SourceClass) object;
            cd.setDefinition(sourceclass, 5);
            SourceClass sourceclass1 = (SourceClass) object;
            baos.reset();
            sourceclass.compile(baos);
         }
         else if (object instanceof BinaryClass) {
            BinaryClass binaryclass = (BinaryClass) object;
            binaryclass.write(be, baos);
         }
         byte[] b = baos.toByteArray();
 
         InMemorySourceCompilerClassLoader myClassLoader = new InMemorySourceCompilerClassLoader();
         compiledClass = myClassLoader.getClassFromBytes(name, b);
      }
   }
 
   public void executeMain() throws Exception {
      Method m = compiledClass.getMethod("main", new Class[]{ String[].class });
      m.invoke(null, new Object[]{null});
   }
 
   static class InMemorySourceCompilerClassLoader extends ClassLoader
   {
      public Class getClassFromBytes(String name, byte[] b) {
         return defineClass(name, b, 0, b.length);
      }
   }
}
 
class InMemorySourceClassFile extends ClassFile
{
   private String filename;
   private String text;
 
   public InMemorySourceClassFile(String filename, String text) {
      super(new File(filename));
      this.filename = filename;
      this.text = text;
   }
 
   public String getAbsoluteName() {
      return filename;
   }
 
   public boolean exists() {
      return true;
   }
 
   public InputStream getInputStream() {
      return new StringBufferInputStream(text);
   }
 
   public String getName() {
      return filename;
   }
 
   public String getPath() {
      return "";
   }
 
   public boolean isDirectory() {
      return false;
   }
 
   public boolean isZipped() {
      return false;
   }
  
   public long lastModified() {
      return new Date().getTime();
   }
 
   public long length() {
      return text.length();
   }
 
   public String toString() {
      return filename;
   }
}