Java 将字节数组加载到内存类加载器中

Java 将字节数组加载到内存类加载器中,java,memory,byte,classloader,encryption,Java,Memory,Byte,Classloader,Encryption,我想知道如何将字节数组加载到内存中URLClassLoader? 字节数组是jar文件的解密字节(如下所示) 大多数内存类加载器使用的是类加载器,而不是URLClassLoader! 我需要它使用URLClassLoader byte[] fileB = Util.crypt.getFileBytes(inputFile); byte[] dec; dec = Util.crypt.decrypt(fileB, "16LENGTHLONGKEYX".getBytes())

我想知道如何将字节数组加载到内存中URLClassLoader? 字节数组是jar文件的解密字节(如下所示)

大多数内存类加载器使用的是类加载器,而不是URLClassLoader! 我需要它使用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?

谢谢

您是否看过ClassLoader javadocs中的NetworkClassLoader示例:


以此为基础,您只需要实现loadClassData方法,该方法将从解密的jar字节中提取所需的资源。您可以使用
JarInputStream(new ByteArrayInputStream(dec))
包装解密后的字节,然后遍历jar条目,直到找到您感兴趣的资源/类,然后返回jar条目的字节数组

您看过ClassLoader javadocs中的NetworkClassLoader示例了吗:


以此为基础,您只需要实现loadClassData方法,该方法将从解密的jar字节中提取所需的资源。您可以使用
JarInputStream(new ByteArrayInputStream(dec))
包装解密的字节,然后遍历jar条目,直到找到您感兴趣的资源/类,然后返回jar条目的字节数组

,我将在这里发布我过去完成的一个实现:

// 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);
///...
}
我的自定义类加载器:

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;
    }
}

我将在这里发布我过去所做的一个实现:

// 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);
///...
}
我的自定义类加载器:

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;
    }
}

你可能不得不站在你的头上,创建一个URLStreamHandlerFactory和它背后的所有gorp。或者扩展URLClassLoader以便调用defineClass。您可能需要站在头上创建一个URLStreamHandlerFactory及其背后的所有gorp。或者扩展URLClassLoader,以便可以调用defineClass.Interest,尽管我不是直接从网络加载JAR。所有jar实际上都存储在本地的temp目录中,并在每次运行程序时下载。我正在使用“new URLClassLoader(jars)”(jars是所有jar文件的数组列表)来创建类加载器,虽然使用普通的类加载器并添加它们没有效果,但这似乎是可行的。我并不是说这将从网络加载它,它只是一些示例代码,您可以根据自己的目的进行修改。您可以调用EncryptedJarClassLoader,根据需要向内部集合添加尽可能多的JAR,并且假设您有解密它们的方法,您应该能够遵循上述有趣的步骤,尽管我不是直接从网络加载JAR。所有jar实际上都存储在本地的temp目录中,并在每次运行程序时下载。我正在使用“new URLClassLoader(jars)”(jars是所有jar文件的数组列表)来创建类加载器,虽然使用普通的类加载器并添加它们没有效果,但这似乎是可行的。我并不是说这将从网络加载它,它只是一些示例代码,您可以根据自己的目的进行修改。您可以调用EncryptedJarClassLoader,向内部集合添加任意数量的JAR,并且假设您有解密它们的方法,您应该能够按照上面的方法进行操作。让我试试这个,我会回复您的!这可能真的有效。我没有发布所有的代码,所以您可能需要更改/更正一些行。原始代码包含一个动态Java编译器,该编译器接收带有代码的字符串,使用这个类加载器编译并加载它。让我试试这个,我会给你回复的!这可能真的有效。我没有发布所有的代码,所以您可能需要更改/更正一些行。原始代码包含一个动态Java编译器,该编译器接收带有代码的字符串,并使用该类加载器对其进行编译和加载。