Topic
  • 1 reply
  • Latest Post - ‏2007-09-07T06:44:18Z by SystemAdmin
SystemAdmin
SystemAdmin
235 Posts

Pinned topic Code modification then compiled into memory

‏2007-04-09T03:04:02Z |
hello all,

I have using java se 1.6 . Is it possible to take classes that have been loaded into memory, unloaded, then modified,compiled and reloaded into memory, using just java code. I do not want to have these modified classes written to disk at all.

Can this be done using pure java code. Can this be done without using ASM and/or hardly any op-codes.

Thanks in advance for all replies.

Jer A.
Updated on 2007-09-07T06:44:18Z at 2007-09-07T06:44:18Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    235 Posts

    Re: Code modification then compiled into memory

    ‏2007-09-07T06:44:18Z  
    You could start by writing a class loader( overriding either loadClass() or findClass() method).

    Use the new CompilerApi to compile the java source files dynamically.

    You can use the following code to start with.
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.util.HashMap;
    public class CustomClassLoader extends ClassLoader {
    public static HashMap classMap = new HashMap();

    @Override
    public Class<?> loadClass(String name,boolean resolveIt) throws ClassNotFoundException {
    // System.out.println("The nameis " + name);
    // name = name + ".class";
    Class result = null;

    System.out.println("the name is " + name);
    try {
    if(!(name.equalsIgnoreCase("test") || name.equalsIgnoreCase("a"))){
    result = super.findSystemClass(name);
    // System.out.println(" >>>>>> returning system class (in CLASSPATH).");
    return result;
    }
    } catch (ClassNotFoundException e) {
    // System.out.println(" >>>>>> Not a system class.");
    }
    // TODO Auto-generated method stub
    byte[] data = null;
    try{
    new CompilationTask().compileClass(name);
    FileInputStream fis = new FileInputStream(new File("/home/aashwin/workspace/jdk6/" + name +".class"));
    FileChannel fc = fis.getChannel();
    data = new byte[(int)(fc.size())]; // fc.size returns the size of the file which backs the channel
    ByteBuffer bb = ByteBuffer.wrap(data);
    fc.read(bb);

    }
    catch(Exception e){

    }
    Class c =defineClass(data, 0, data.length);

    if (resolveIt && c != null)
    resolveClass( c );

    classMap.put("class", c);
    return c;

    }

    }
    Finally attach your own custom class loader to any class.
    import java.lang.reflect.Method;
    public class Caller {

    public static CustomClassLoader ccl = new CustomClassLoader();

    public static void main(String[] args)throws ClassNotFoundException,IllegalAccessException{
    for(;;)
    {

    ccl = new CustomClassLoader();

    Object o = null;
    Class c;
    c = ccl.loadClass("test",false);
    try {
    o = c.newInstance();

    } catch (InstantiationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    try{
    Method test = c.getMethod("test",null);
    test.invoke(o, null);
    }
    catch(Exception e){

    }

    // t.test();
    }
    }
    }