0

I'm using ecj for Genetic Programming and I have it built so it takes the best fit individual program after a run, and creates a java class with a function from the lisp code that is created.

I then have my program compile the java file. Is there anyway I can run the newly compiled class file in the same run?

I want to be able to:

RunMain --> Create Java --> Compile Class --> Call function in newly created class --> EndMainRun

So far, I'm having trouble calling the method in the newly created class.

Every time I create the new java file and compile, it rewrites the old one. But whenever that class is called later, it's running the old function pre-overwrite. Any tips would be much appreciated!

Edit: Here's some very basic pseudo code to show what I've got so far, a lot of it is abstracted. Assume that there is already a MathFunction.class file before I run this.

PseudoCode
Main(){
runGeneticProgrammingAlgorithm();
generateJavaFileFromBestFitIndividual(name = MathFunction.java) //Replaces old MathFunction.java
compile(MathFunction.java) //using JavaCompilerApi, replaces old MathFunction.class
double value = MathFunction.calculate(25);

The old function returned -1 for value, the new function should return 5, but it's still returning -1. Even if I put this all in a loop, it'll keep spitting out -1, -1, -1....

Edit 2:

I'm still having it return the same value despite the function being completely different. Here is the code:

    URL[] urls = null;

    File dir = new File("src" + java.io.File.separator + "ec");

    URL url = dir.toURI().toURL();

    urls = new URL[] { url };

    ClassLoader cl = new URLClassLoader(urls);

    Class cls = cl.loadClass("ec.MathSolution");

    MathSolution mathFunction = (MathSolution) cls.newInstance();

    System.out.println(mathFunction.calculate(123.5));

Edit 3:

Found an amazing source online here: http://www.toptal.com/java/java-wizardry-101-a-guide-to-java-class-reloading

KrispyK
  • 235
  • 6
  • 18

1 Answers1

1

Achieving what you want to do is non-trivial but easily possible with some classloader magic.

The fact that you say 'it's running the old function pre-overwrite'... indicates that you are creating an instance of this class from the same classloader that you got it from the first time around.

I suggest reading up on ClassLoaders.

At a high level your algorithm should go:

  1. Create java
  2. Compile Class
  3. Create a ClassLoader that is a child of your current classloader.
  4. Load the class compiled at step 2 using this classloader
  5. Instantiate the class or otherwise use it.
  6. Now you see there is a new revision... start from 1

I will try to edit this answer with some code samples.

Anup Puranik
  • 165
  • 1
  • 10