我需要加载一个存在于不同服务器上的类文件,并在类文件中执行一个方法。我不想使用http或RMI,但想要应用此方法。我正在寻找URLClassLoader,但我没有到达任何地方。有人可以给我一个从不同的服务器加载一个类的例子。
答案 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 上运行的简单演示作为内存缓存。你可以查看一下;
整个演示项目;