0

I am trying to generate ,compile and run Java Class through program using reflection. I am able to successfully generate and compile the file but when running the file, getting the ClassNotFoundException.

package javaapplication2;

/**
 *
 * @author sachin.maurya
 */
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import java.lang.ClassLoader;
public class MakeTodayClass {
  Date today = new Date();
  String todayMillis = Long.toString(today.getTime());
  String todayClass = "z_" + todayMillis;
  String todaySource = "C:\\Users\\sachin.maurya\\Documents\\NetBeansProjects\\JavaApplication2\\src\\javaapplication2\\"+todayClass + ".java";

  public static void main (String args[]) throws InterruptedException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{
    MakeTodayClass mtc = new MakeTodayClass();
    mtc.createIt();
    if (mtc.compileIt()) {
       System.out.println("Running " + mtc.todayClass + ":\n\n");
        Thread.sleep(2000);
       mtc.runIt();
       }
    else
       System.out.println(mtc.todaySource + " is bad.");
    }

  public void createIt() {
    try {
      FileWriter aWriter = new FileWriter(todaySource, true);
      aWriter.write("public class "+ todayClass + "{");
      aWriter.write(" public void doit() {");
      aWriter.write(" System.out.println(\""+todayMillis+"\");");
      aWriter.write(" }}\n");
      aWriter.flush();      
      aWriter.close();
      }
    catch(Exception e){
      e.printStackTrace();
      }
    }

  public boolean compileIt() {
    String [] source = { new String(todaySource)};
    ByteArrayOutputStream baos= new ByteArrayOutputStream();

    new sun.tools.javac.Main(baos,source[0]).compile(source);
   return (baos.toString().indexOf("error")==-1);
    }

  public void runIt() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
    try {
      Class params[] = {};
      Object paramsObj[] = {};
      Class thisClass = Class.forName(todayClass);
      Object iClass = thisClass.newInstance();
      Method thisMethod = thisClass.getDeclaredMethod("doit", params);
      thisMethod.invoke(iClass, paramsObj);
      }
    catch (Exception e) {
      e.printStackTrace();
      }

  }

}

run:

Running z_1462876181460:


1462874906040
javaapplication2.Runner.runner()
java.lang.ClassNotFoundException: z_1462876181460
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at javaapplication2.Runner.runner(Runner.java:24)
    at javaapplication2.MakeTodayClass.runIt(MakeTodayClass.java:70)
    at javaapplication2.MakeTodayClass.main(MakeTodayClass.java:28)
BUILD SUCCESSFUL (total time: 2 seconds)

When I hardcode the value of 'todayClass' value i.e. some class file generated earlier then runIt() function is working properly, So it seems to be due to workflow of ClassLoader but I am not sure. Is it possible to run generated .class file ?

1 Answers1

0

The problem is that the ClassLoader cannot find the created class in the class path.

The easiest fix is to define your file location differently, perhaps something like (assuming that bin is in your class path):

String todaySource = "C:\\Users\\sachin.maurya\\Documents\\NetBeansProjects\\JavaApplication2\\bin\\"+todayClass + ".java";
dejvuth
  • 6,986
  • 3
  • 33
  • 36
  • Yes Bootstrap ClassLoader is not able to find class so I tried to use child classLoaders but still no luck and also I tried to implement as your suggestion but getting the same error. – Chandu Pandey May 10 '16 at 12:49
  • You should find out what your class path is, and put the file there. Try e.g. http://stackoverflow.com/a/23773036/1547337 to list all possible paths. – dejvuth May 10 '16 at 13:07