Reputation: 1986
I have a jar (postgresql-9.4.1208.jre7.jar
) in a byte[]
. Id like to load and connect and run some basic SQL commands in runtime.
Therefore I created a new Classloader:
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);
}
}
}
}
The Jar loads successfully and I am able to get a instance of the Driver.
On the call to connect to a Database I get this Error:
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)
In the stacktrace I see the working instance of org.postgresql.Driver
looking for a class named org/postgresql/hostchooser/HostRequirement$1
.
My JarClassloader
does not load anonymous nested classes.
What shall I do to successfully load all classes in the jar?
Upvotes: 1
Views: 129
Reputation: 310909
You need to load the classes in the order the classloader needs them, not in the order they happen to be in the JAR file. So you need to override the findClass()
method and search the JAR file at that point for the class being requested.
It would be a lot simpler to use a file.
Upvotes: 1