Мне нужно использовать пользовательский ClassLoader для загрузки сторонних драйверов. План состоит в том, что драйверы - это просто общие архивы jar, но с суффиксом .dar (архив драйверов). Эти архивы затем просто добавляются в путь к классам, в то время как jvm игнорирует это расширение файла и обрабатывает файлы dar, такие как ресурсы (что означает игнорирование файлов классов внутри).Пользовательский загрузчик классов, загружающий jar, дает мне строку Illegal UTF8 в постоянном пуле в файле класса
Теперь моя проблема в том, что мой загрузчик классов дает мне строку Illegal 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);
EDIT 1: Но файл содержит допустимые классы:
java -cp ../rangeCache/src/main/resources/drivers.dar pkg.test.Test
Выходы Привет из DAR баночке
Хотя это не делает:
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)
Коррумпированные файлы классов или не файлы классов вообще. – Kayaman
@ Каяман в архиве содержит допустимые классы: java -cp ../rangeCache/src/main/resources/drivers.dar pkg.test.Test работает как ожидалось – KIC