java - 如何将 bytearray 转换为 Jar

标签 java arrays

我正在尝试从字节数组加载一个 jar,而不将其写入文件(将其加载到内存中)。我制作了一个自定义的 ClassLoader,但是当我尝试使用它并加载一个类时,它给我 ClassNotFoundException。

类加载器

public class NetworkClassLoader extends ClassLoader 
{
/*
 * Default ClassLoader.
 */
private final ClassLoader startup;

/*
 * Byte array used to load classes.
 */
private final byte[] bytes;

/*
 * HashMap used to contain cached classes.
 */
private HashMap<String, byte[]> classes = new HashMap<>();

/*
 * Initializes byte array used for loading classes.
 * @param ClassLoader classLoader
 * @param byte[] bytes
 */
public NetworkClassLoader(ClassLoader classLoader, byte[] bytes) 
{
    this.startup = classLoader;
    this.bytes = bytes;
}

/*
 * Loads class from name.
 * (non-Javadoc)
 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
 * @param String name
 * @param boolean resolve
 * @throws ClassNotFoundException
 * @returns clazz
 */
@Override
public Class<?> loadClass(String name, boolean resolve) 
        throws ClassNotFoundException 
{
    Class<?> clazz = findLoadedClass(name);
    if (clazz == null) 
    {
        try 
        {
            InputStream in = getResourceAsStream(name.replace('.', '/') + ".class");
            if (in == null) return null;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            IOUtils.writeStream(in, out);
            in.close();
            byte[] bytes = out.toByteArray();
            out.close();
            clazz = defineClass(name, bytes, 0, bytes.length);
            if (resolve) 
            {
                resolveClass(clazz);
            }
        } 
        catch (Exception e) 
        {
            clazz = super.loadClass(name, resolve);
        }
    }
    return clazz;
}

/*
 * Returns resource.
 * (non-Javadoc)
 * @see java.lang.ClassLoader#getResource(java.lang.String)
 * @param String name
 */
@Override
public URL getResource(String name) 
{
    return null;
}

/*
 * Returns resource as stream.
 * (non-Javadoc)
 * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
 * @param String name
 * @return ByteArrayInputStream
 */
@Override
public InputStream getResourceAsStream(String name) 
{
    InputStream jarRes = this.startup.getResourceAsStream(name);
    if (jarRes != null) 
    {
        return jarRes;
    }
    if (!this.classes.containsKey(name)) 
    {
        return null;
    }
    return new ByteArrayInputStream((byte[])this.classes.get(name));
}

/*
 * Loads classes using byte array.
 */
public void inject()
{
    if (bytes == null) return;
     try
     {
         JarInputStream jis = new JarInputStream(new ByteArrayInputStream(bytes));
          try
          {
              JarEntry entry;
              while ((entry = jis.getNextJarEntry()) != null)
              {
                  String entryName = entry.getName();
                  ByteArrayOutputStream out = new ByteArrayOutputStream();
                  IOUtils.writeStream(jis, out);
                  byte[] bytes = out.toByteArray();
                  this.classes.put(entryName, bytes);
                  this.loadClass(entryName, false);
              }
          }
          catch (Exception e)
          {
              e.printStackTrace();
          }
     }
     catch (Exception e)
        {
          e.printStackTrace();
        }
 }

}

主要

byte[] array =      
IOUtils.readFileBytes(new File("C:\\Users\\o_m_a\\Desktop\\HWID.jar"));
ByteClassLoader loader = new ByteClassLoader(Main.class.getClassLoader(), array);
 loader.inject();
//System.out.println(Arrays.toString(array));

    try {
        Class<?> clazz = loader.loadClass("Main", true).newInstance();
        Method m = clazz.getMethod(method, (Class<?>[]) null);
        m.setAccessible(true);
        m.invoke(clazz.newInstance(), (Object[]) null);
    } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
        e.printStackTrace();
    }

它正确加载我的类并运行它,但我不断收到随机错误。

最佳答案

经过一些研究后,您似乎使用了错误的库。

代替 IOUtils.copyStream(in, out); 尝试使用 StreamUtils.writeTo(in, out);

关于java - 如何将 bytearray 转换为 Jar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45212086/

相关文章:

java - Lambda 表达式条件的代码覆盖率单元测试

android - 如何获取文件夹中所有图像文件的名称?

arrays - Swift:将字符串中的单独字符与字典中的值匹配

c - C语言中提取子字符串

c++ - 如何初始化一个很长的数组?

java - 类路径声明中的点

java - 使用 DefaultListModel 和 JList 显示列表

java - 单击时使 RecyclerView 图像全屏显示

java - Java 中按位运算符对 boolean 值的影响

c++ - 在字符数组 C++ 中存储整数值