我需要加载不同服务器上存在的类文件并执行该类文件中的方法。我不想使用 http 或 RMI,但想应用此方法。我正在查看 URLClassLoader 但没有任何进展。有人可以给我一个从不同服务器加载类的示例吗?
最佳答案
您可以将 .class 文件作为 BLOB 对象存储在数据库中。您应该使用缓存,跟踪您在简单的 HashMap 中使用的所有类,以便您只能从数据库中检索每个类一次。
当委托(delegate)的父类加载器抛出 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 上运行。您可以查看一下;
以及整个演示项目;
关于java - 从不同的文件系统加载类文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34567137/