使用bytearray加载jar,无法找到嵌套类

时间:2018-03-09 20:17:00

标签: java jar classloader

我在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中的所有类?

1 个答案:

答案 0 :(得分:1)

您需要按类加载器所需的顺序加载类,而不是按照它们恰好位于JAR文件中的顺序加载。因此,您需要覆盖findClass()方法并在该点搜索JAR文件以查找所请求的类。

使用文件会更简单。