2016-01-02 2 views
1

Мне нужно загрузить файл класса, присутствующий на другом сервере, и выполнить метод в файле класса. Я не хочу использовать http или RMI, но хочу применить этот метод. Я смотрю URLClassLoader, но никуда не денутся. Может кто-нибудь, пожалуйста, дайте мне пример загрузки класса с другого сервера.Загрузка файла класса из другой файловой системы

+0

Задайте более конкретный вопрос. Что вводит в заблуждение относительно документации URLClassLoader? Что вы пробовали, а что работали и не работали? Как подключаются серверы (NFS, HTTP, ...)? –

ответ

1

Вы можете хранить ваши .class файлы в dataase в 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