我在postgresql-9.4.1208.jre7.jar
中有一个jar(byte[]
)。我想在运行时加载并连接并运行一些基本的SQL命令。
因此我创建了一个新的类加载器:
public class JarClassloader extends ClassLoader {
public interface DriverProblemReporter {
void reportDriverProblem(String name, Throwable e);
}
private final byte[] driverdata;
private final DriverProblemReporter problemReporter;
public JarClassloader(byte[] jar, String drivername, DriverProblemReporter reporter) {
super(ClassLoader.getSystemClassLoader());
this.problemReporter = reporter;
try {
JarInputStream jis = new JarInputStream(new ByteArrayInputStream(jar));
JarEntry entry = jis.getNextJarEntry();
while (entry != null) {
handleEntry(entry, jis);
entry = jis.getNextJarEntry();
}
} catch (IOException e) {
e.printStackTrace();
}
this.driverdata = jar;
}
private void handleEntry(JarEntry entry, JarInputStream jis) {
if (!entry.isDirectory()) {
ByteArrayOutputStream baos;
try {
baos = new ByteArrayOutputStream();
IOUtils.copy(jis, baos);
baos.flush();
} catch (IOException e) {
problemReporter.reportDriverProblem(entry.getName(), e);
return;
}
try {
defineClass(baos.toByteArray(), 0, baos.size());
} catch (LinkageError e) {
problemReporter.reportDriverProblem(entry.getName(), e);
}
}
}
}
Jar加载成功,我可以获得驱动程序的实例。
在连接数据库的调用中,我收到此错误:
java.lang.NoClassDefFoundError: org/postgresql/hostchooser/HostRequirement$1
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:107)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:215)
at org.postgresql.Driver.makeConnection(Driver.java:406)
at org.postgresql.Driver.connect(Driver.java:274)
在堆栈跟踪中,我看到org.postgresql.Driver
的工作实例正在寻找名为org/postgresql/hostchooser/HostRequirement$1
的类。
我的JarClassloader
不会加载匿名嵌套类。
如何成功加载jar中的所有类?
答案 0 :(得分:1)
您需要按类加载器所需的顺序加载类,而不是按照它们恰好位于JAR文件中的顺序加载。因此,您需要覆盖findClass()
方法并在该点搜索JAR文件以查找所请求的类。
使用文件会更简单。