从不同的文件系统加载类文件

时间:2016-01-02 14:44:40

标签: java classloader

我需要加载一个存在于不同服务器上的类文件,并在类文件中执行一个方法。我不想使用http或RMI,但想要应用此方法。我正在寻找URLClassLoader,但我没有到达任何地方。有人可以给我一个从不同的服务器加载一个类的例子。

1 个答案:

答案 0 :(得分:1)

您可以将 .class 文件作为 BLOB 对象存储在数据库中。您应该使用缓存,跟踪在简单的 HashMap 中使用的所有类,以便您只能从数据库中检索每个类一次。

当委托的父类加载器抛出ClassNotFoundException时,必须执行从数据库中检索类二进制文件的代码点。

@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
    Class cls = null;

    try {
        cls = parent.loadClass(name);           // Delegate to the parent Class Loader
    } catch (ClassNotFoundException clnfE) {    // If parent fails, try to locate and load the class
        byte[] bytes = new byte[0];
        try {
            bytes = loadClassFromDatabase(name);
        } catch (SQLException sqlE) {
            throw new ClassNotFoundException("Unable to load class", sqlE);
        }
        return defineClass(name, bytes, 0, bytes.length);
    }

    return cls;
}

您可以修改检索类二进制文件的方法。例如,您可以从数据库,ftp服务器或简单文件或甚至简单的套接字连接中检索类二进制文件。以下是类二进制文件从数据库中检索的示例;

private byte[] loadClassFromDatabase(String name) throws SQLException {
    PreparedStatement pstmt = null;
    Connection connection = null;

    try {
        connection = DriverManager.getConnection(connectionString);

        String sql = "SELECT CLASS FROM CLASSES WHERE CLASS_NAME = ?";
        pstmt = connection.prepareStatement(sql);
        pstmt.setString(1, name);
        ResultSet rs = pstmt.executeQuery();

        if (rs.next()) {
            Blob blob = rs.getBlob(1);
            byte[] data = blob.getBytes(1, (int) blob.length());
            return data;
        }
    } catch (SQLException e) {
        System.out.println("Unexpected exception: " + e.toString());
    } catch (Exception e) {
        System.out.println("Unexpected exception: " + e.toString());
    } finally {
        if (pstmt != null) {
            pstmt.close();
        }

        if(connection != null) {
            connection.close();
        }
    }

    return null;
}

检索类二进制文件的方法应返回一个字节数组,然后类加载器使用defineClass(name, bytes, 0, bytes.length)方法定义类。很明显,可以从数据库,套接字连接,文件阅读器......中检索字节数组。

我已经编写了一个在 apache derby 上运行的简单演示作为内存缓存。你可以查看一下;

https://github.com/bzdgn/simple-class-loader/blob/master/src/com/levent/classloader/DerbyServerClassLoader.java

整个演示项目;

https://github.com/bzdgn/simple-class-loader