Search code examples
javamemorybyteclassloaderencryption

Load a Byte Array into a Memory Class Loader


I am wondering how I can load a byte array into a memory URLClassLoader? The byte array is the decrypted bytes of a jar file (as seen below)!

Most of the memory class loaders are using ClassLoader and not URLClassLoader! I need it to be using URLClassLoader.

    byte[] fileB = Util.crypt.getFileBytes(inputFile);
    byte[] dec;
    dec = Util.crypt.decrypt(fileB, "16LENGTHLONGKEYX".getBytes());
    //Load bytes into memory and load a class here?

Thanks!


Solution

  • I will post here a implementation I had done in the past:

    // main
    String className = "tests.compiler.DynamicCompilationHelloWorldEtc";
    //...
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    File classesDir = new File(tempDir);
    CustomClassLoader ccl = new CustomClassLoader(classLoader, classesDir);         
    if (ccl != null) {
        Class clazz = ccl.loadClass(className);
    ///...
    }
    

    My Custom ClassLoader:

    package tests.classloader;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.nio.ByteBuffer;
    
    public class CustomClassLoader extends ClassLoader {
    
        private File classesDir;
    
        public CustomClassLoader(ClassLoader parent, File classesDir) {
           super(parent);      
    
           this.classesDir = classesDir;
        }
    
        public Class findClass(String name) {
           byte[] data = loadDataFromAny(name);
           return defineClass(name, data, 0, data.length);
        }
    
        private byte[] loadDataFromAny(String name) {
    
            name = name.replace('.', '/');
            name = name + ".class";
    
            byte[] ret = null;
    
            try {
                File f = new File(classesDir.getAbsolutePath(), name);
                FileInputStream fis = new FileInputStream(f);
    
                ByteBuffer bb = ByteBuffer.allocate(4*1024); 
                byte[] buf = new byte[1024];
                int readedBytes = -1; 
    
                while ((readedBytes = fis.read(buf)) != -1) {
                    bb.put(buf, 0, readedBytes);
                }
    
                ret = bb.array();           
            }
            catch (Exception e) {
                e.printStackTrace();
            }
    
            return ret;
        }
    }