我有一个包含以下结构的zip文件
plugin
data
abc.jar
xyz.jar
我想使用这些jar创建一个URLClassLoder实例。 一种方法是解压缩此文件,然后使用该文件系统路径创建URLClassLoaders。 我可以在记忆中做同样的事吗?
答案 0 :(得分:1)
好的,你可以查看这个答案https://stackoverflow.com/a/2614154/90313
您可以一起使用它们来实现所需的功能。
答案 1 :(得分:0)
以下是有效的解决方案。您可以根据需要进行修改。
打开拉链的参考:recursively unzip archive in memory
有关类加载的参考:Java: How to load Class stored as byte[] into the JVM?
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public final class ZippedJarClassReader {
private final static String JAR_EXTENSION = ".jar";
public static Map<String, byte[]> loadZip(final File file) throws IOException {
final byte[] bytes = Files.readAllBytes(file.toPath());
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(bytes);
return unzip(baos);
}
public static final Map<String, byte[]> unzip(final ByteArrayOutputStream baos) {
final Map<String, byte[]> result = new HashMap<String, byte[]>();
try(final ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
ZipEntry entry;
while ((entry = in.getNextEntry()) != null) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
if (!entry.isDirectory()) {
os.write(in.readAllBytes());
if (entry.getName().toLowerCase().endsWith(JAR_EXTENSION)) {
result.putAll(unzip(os));
} else if (entry.getName().toLowerCase().endsWith(".class")) {
result.put(entry.getName().replaceAll("/", ".").substring(0, entry.getName().length() - 6), os.toByteArray());
}
}
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
public final class ZipClassLoader extends URLClassLoader {
private final Map<String, byte[]> classes;
public ZipClassLoader(URL[] urls, final File zipFile) throws IOException {
super(urls);
classes = ZippedJarClassReader.loadZip(zipFile);
}
@Override
public final Class<?> findClass(String name) throws ClassNotFoundException {
final byte[] bytes = classes.get(name);
if(bytes != null) return defineClass(name, bytes, 0, bytes.length);
return super.findClass(name);
}
}
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.ZipException;
public class Test {
@SuppressWarnings("resource")
public static void main(String[] args) throws ZipException, IOException, ClassNotFoundException {
final File zipFile = new File("zipfile.zip");
final URLClassLoader loader = new ZipClassLoader(new URL[] {}, zipFile);
final Class<?> classz = loader.loadClass("org.util.nanolog.Test");
System.out.println(classz);
}
}
答案 2 :(得分:0)
好的,youtube.liveChatMessages().list(liveChatId=liveChatId,part="snippet")
URI方案似乎不起作用,但nio可以。这是加载Jetifier(Android构建工具)而不解压缩所有内容的示例。
jar:
这可行,并成功从Jetifier中打个招呼。我使用JDK 13。