gpt4 book ai didi

java - 加载 jar 的自定义类加载器在类文件的常量池中提供了非法的 UTF8 字符串

转载 作者:行者123 更新时间:2023-12-02 04:13:14 24 4
gpt4 key购买 nike

我需要使用自定义类加载器来加载第 3 方驱动程序。计划是,驱动程序只是共享的 jar 存档,但带有 .dar 后缀(驱动程序存档)。然后,这些归档文件将被简单地添加到类路径中,而 jvm 会忽略此文件扩展名并像处理资源一样处理 dar 文件(这意味着忽略内部的类文件)。

现在我的问题是,我的类加载器在类文件异常的常量池中给了我一个非法的 UTF8 字符串。我该如何解决这个问题?

public class DriversClassLoader extends ClassLoader {

public DriversClassLoader() {
super(ClassLoader.getSystemClassLoader());
}

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if( name.startsWith("java.")) {
return super.loadClass(name, resolve);
} else {
// see if we have already loaded the class.
Class<?> c = findLoadedClass(name);
if (c != null) return c;

try {
URL driversUrl = super.getResource("drivers.dar").toURI().toURL();
System.out.println(driversUrl);
JarInputStream jis = new JarInputStream(driversUrl.openConnection().getInputStream());

ZipEntry entry;
while ((entry = jis.getNextEntry()) != null) {
if (entry.getName().matches(name)) {
System.out.println("loading: " + entry);
byte[] cBytes = new byte[(int) entry.getSize()];
jis.read(cBytes, 0, cBytes.length);

// this is where I get the exception
c = defineClass(name, cBytes, 0, cBytes.length);
if (resolve) resolveClass(c);
return c;
}
}
} catch (Exception e) {
throw new ClassNotFoundException("loading of class " + name + " failed", e);
}

// else delegate to parent
return super.loadClass(name, resolve);

/*
URL res = getResource(name);
if (res == null) throw new ClassNotFoundException("Class " + name + "not found in:");

try {
byte[] cBytes = IOUtils.toByteArray(new InputStreamReader(res.openStream()));
c = defineClass(name, cBytes, 0, cBytes.length);
if (resolve) resolveClass(c);
return c;
} catch (Exception e) {
throw new ClassNotFoundException("loading of class " + name + " failed", e);
}

// delegate to parent
return super.loadClass(name, resolve);*/
}
}

@Override
public URL getResource(String name) {
try {
URL driversUrl = super.getResource("drivers.dar").toURI().toURL();
System.out.println(driversUrl);
JarInputStream jis = new JarInputStream(driversUrl.openConnection().getInputStream());

ZipEntry entry;
while ((entry = jis.getNextEntry()) != null) {

if (entry.getName().matches(name)) {
System.out.println(entry);
return new URL("jar:" + driversUrl + "!/" + entry);
}
}
} catch (Exception e) {
e.printStackTrace();
}

// delegate to parent
return super.getResource(name);
}

@Override
public Enumeration<URL> getResources(String name) throws IOException {
//super.get
return super.getResources(name);
}
}

然后我就简单地

Class<?> aClass = Class.forName("a.class", false, new DriverClassLoader());
System.out.println("aclass = " + aClass);

编辑1:但该文件包含有效的类:

java -cp ../rangeCache/src/main/resources/drivers.dar pkg.test.Test

从 dar jar 输出 Hello

虽然这不会:

java -cp target/libs/range-cache-302-SNAPSHOT.jar:drivers/ com.data.cache.range.drivers.DriversClassLoader
jar:file:/home/rangeCache/target/libs/range-cache-302-SNAPSHOT.jar!/drivers.dar
loading: com/data/cache/range/drivers/DatastaxCassandraDriver.class
Exception in thread "main" java.lang.ClassFormatError: Illegal UTF8 string in constant pool in class file com/data/cache/range/drivers/DatastaxCassandraDriver/class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at com.mindbusters.data.cache.range.drivers.DriversClassLoader.loadClass(DriversClassLoader.java:40)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.data.cache.range.drivers.DriversClassLoader.main(DriversClassLoader.java:105)

最佳答案

您从 ZipEntry 读取字节的代码已损坏。

您首先不应依赖 ZipEntry.getSize(),因为如果未知,可能会返回 -1(请参阅 Javadocs)。

然后 InputStream.read(byte[], int , int) 可能会读取比请求的个字节。您应该循环读取字节,直到返回 -1 为止,或者使用 IOUtils.toByteArray 就像您已经做过一次一样。

关于java - 加载 jar 的自定义类加载器在类文件的常量池中提供了非法的 UTF8 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33580808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com