【问题标题】:Load a Byte Array into a Memory Class Loader将字节数组加载到内存类加载器中
【发布时间】:2012-03-23 00:13:39
【问题描述】:

我想知道如何将字节数组加载到 memory URLClassLoader 中? 字节数组是一个jar文件的解密字节(如下图)!

大多数内存类加载器都使用 ClassLoader 而不是 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?

谢谢!

【问题讨论】:

  • 你可能不得不站起来创建一个 URLStreamHandlerFactory 和它背后的所有 gorp。或者扩展 URLClassLoader 以便您可以调用 defineClass。

标签: java memory byte classloader encryption


【解决方案1】:

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

http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ClassLoader.html

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

【讨论】:

  • 有趣,虽然我不是直接从网络加载罐子。所有的 jars 实际上都存储在本地的 temp 目录中,每次运行程序时都会下载。我正在使用“new URLClassLoader(jars)”(jars 是所有 jar 文件的数组列表)来创建类加载器,这似乎有效,尽管使用普通的 ClassLoader 并添加它们没有。
  • 我并不是说这会从网络加载它,它只是一些示例代码,您可以根据自己的目的进行修改。您可以调用您的 EncryptedJarClassLoader,将任意数量的 jar 添加到内部集合中,并假设您有解密它们的方法,您应该能够按照上述操作
【解决方案2】:

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

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

【讨论】:

  • 让我试试这个,我会回复你的!这实际上可能有效。
  • 我没有发布所有代码,因此您可能需要更改/更正一些行。原始代码包含一个动态 Java 编译器,它接收带有代码的字符串,编译它并使用这个 ClassLoader 加载它。
猜你喜欢
  • 2017-10-31
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 2014-03-28
  • 1970-01-01
相关资源
最近更新 更多