1

My issue is that I want to create a class in execution time (I create a file .java with the name, package, methods, etc. all right). When I try to compile and execute it always load the old version, not the newer one I write during the execution of my program.

What should I change in my code?

File f = new File("src/pfc/Temp.java");

FileWriter w = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(w);
PrintWriter wr = new PrintWriter(bw);
wr.write("package pfc;\n\npublic class Temp {\n\tpublic float getResult(float[] array){\nfloat res=0;//usar para guardar el resultado final\n");//preparamos la clase
wr.write(entrada.getText());//escribimos en el archivo
wr.write("\nreturn res;\n}\n}");
bw.flush();
bw.close();
wr.flush();
wr.close();
String fileToCompile = f.getAbsolutePath();
try {
    pfc.Temp result = new pfc.Temp();

    //Otra forma

    Class<?> c = Class.forName("pfc.Temp");
    Class[] argTypes = new Class[] { float[].class };
    Method main = c.getDeclaredMethod("getResult", argTypes);
    float nts[] = new float[model.getColumnCount()];
    for(int i = 0; i < model.getRowCount(); i++){
        System.err.println("Voy a la fila: "+i+" de "+model.getRowCount());
        for(int j = 1; j < model.getColumnCount(); j++){
            nts[j] = Float.parseFloat(model.getValueAt(i,j).toString());
            System.err.println("Notas parciales: "+nts[j]+" de la columna "+j+" sobre "+model.getColumnCount());
        }
    }
    Object comp = main.invoke(result, (Object) nts);

Thanks !


Ok, I will try to explain it better. I have a desktop application and I want to load a class when I'm executing it. The problem is that this class I modified with a JTextArea, then I write to the file and want to compile this, but in this way it doesn`t work. It compile the file it was written before I run my application, no the newer I write in the execution.

I will try with ClassLoader, my Temp.java is like this:

package pfc;

public class Temp {
public float getResult(float[] array){
       float res=0;//usar para guardar el resultado final
       float erer = array[1];float fdsfds = array[2];float awd = array[3];

       res= 5;
       return res;
    }
 }

And when I edit this in my aplication, like to replace res= 5; to res= 10; I compile but the result is 5 and not 10.

1
  • I don't see compilation, and lodaing code in what you presented, You are not using new version of class becasuse there is none. Commented Jan 2, 2013 at 9:02

2 Answers 2

1

I dont understand what does your Temp class, but this code worked for me with a TestClass with a setter and a getter. (You need the tools.jar, you can find it in the JDK filepath \lib )

package pfc;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ClassGenerator {

public static BufferedWriter writeClass(String dir, String className) throws IOException {
    BufferedWriter bw1 = new BufferedWriter( new FileWriter( dir + File.separator + className
            + ".java" ) );
    bw1.write( "public class " + className + " {" );
    bw1.newLine( );
    bw1.write( "  private int value;" );
    bw1.newLine( );
    bw1.write( "  public int getValue() {" );
    bw1.newLine( );
    bw1.write( "    return this.value;" );
    bw1.newLine( );
    bw1.write( "  }" );
    bw1.newLine( );
    bw1.write( "  public void setValue(int value) {" );
    bw1.newLine( );
    bw1.write( "    this.value = value;" );
    bw1.newLine( );
    bw1.write( "  }" );
    bw1.newLine( );
    bw1.write( "}" );
    bw1.newLine( );
    bw1.close( );
    return bw1;
}

public static void main(String [] args) throws IOException, ClassNotFoundException,
        NoSuchMethodException, SecurityException, InstantiationException,
        IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    String className = "TestClass";
    String dir = "bin";
    BufferedWriter bw = writeClass( dir , className );

    com.sun.tools.javac.Main.compile( new String [] { dir + File.separator + className
            + ".java" } );

    ClassLoader classLoader1 = ClassGenerator.class.getClassLoader( );
    Class clazz1 = classLoader1.loadClass( className );

    Constructor ctr1 = clazz1.getConstructor( new Class [0] );
    Object testClassInstance = ctr1.newInstance( new Object [0] );
    Method setter1 = clazz1.getMethod( "setValue" , new Class [] { int.class } );
    setter1.invoke( testClassInstance , 12 );

    Method getter1 = clazz1.getMethod( "getValue" , new Class [0] );
    Object result = getter1.invoke( testClassInstance );
    System.out.println( result.toString( ) );
}
}
Sign up to request clarification or add additional context in comments.

1 Comment

The problem was with NetBeans. I putted the Temp.java inside the project classpath and then it always load at first the old file. I tried to put it outside and then it works fine (with the code that you propose). Thanks !
1

Actually you need to use the ClassLoader in order to load the class. Additionally, if you are just using the .java file, you need to compile to generate the .class file in order to be loaded and then call the constructor to get an instance.

Here there is an interesting blog related with the subject

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.