2012-04-16 6 views
0

Я реализовал простое приложение с плагинами с Java. Основной класс плагина получен из и абстрактного класса под названием «Плагин». Приложение читает этот класс из JAR-файла и запускает плагин, создавая экземпляр класса. Стандартная процедура, я думаю :)URLClassLoader не читает внешнюю JAR-библиотеку плагина

Все вилки до сих пор. Но проблема возникает, когда я включаю библиотеку в свой плагин, например, MySQL Connector. Исключение NoClassDefFoundError и ClassNotFoundException выводятся после выполнения. Я преодолеваю проблему, добавив библиотеку соединителей MySQL в основное приложение, но в чем же смысл? :)

Я не эксперт Java, так что я не уверен в каких-либо альтернативных решений, как определяющий путь к классам для библиотек и т.д.

Вот мой загрузчик плагинов: http://pastebin.com/90rQ9NfJ

А вот мой плагин базовый класс: http://pastebin.com/Juuicwkm

Я исполнение из графического интерфейса:

private void jButtonAddActionPerformed(java.awt.event.ActionEvent evt) { 
     JFileChooser fileChooser = new JFileChooser(); 
     fileChooser.setFileFilter(new FileNameExtensionFilter("JTask Plugin (*.JAR)", "JAR")); 

     if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) 
     { 
      File pluginFile = fileChooser.getSelectedFile(); 
      PluginLoader pluginLoader = new PluginLoader(); 
      Plugin plugin = pluginLoader.loadPlugin(pluginFile); 
      if (plugin != null) 
       jPanelPlugins.add(new PluginControl(jPanelPlugins, plugin)); 
     } 
    } 

ответ

0

Вы также должны включить свой исходный код.

Как вы выполняете класс i.e через командную строку или из графического интерфейса? Если из командной строки библиотеки MySQLConnector вместе с любой другой зависимой библиотекой должны быть включены в путь к классам (java -classpath). Ответ на этот вопрос должен помочь вам: Java: how to import a jar file from command line

+0

спасибо. Я нашел что-то об обновлении манифеста в файле jar http://java.sun.com/developer/Books/javaprogramming/JAR/basics/update.html, но он все еще выглядит слишком подробно. Я ищу что-то, что не нужно менять основное приложение снаружи. – Heka

0

Если в вашем случае ваш класс - это драйвер Mysql, который вы должны исключить (в момент вызова класса) классы, которые недоступны. В папке вашего .jar-файла есть один с именем «интеграция», в котором содержатся «jboss» и «c3p0», которых нет в настоящее время.

while (en.hasMoreElements()) { 
       JarEntry entry = new JarEntry(en.nextElement()); 
       String name = entry.getName(); 
       if (name.contains("/integration/")) { 
        continue; 
       } else { 
       if (!entry.isDirectory() && name.toLowerCase().endsWith(".class")) 
       { 
        classList.add(name.replace(".class", "")); 
       } 
       } 
} 

Это должно загрузить файл mysql.xxx.jar. Попробуйте это


dynamicload.java


package dynamicloading; 

import java.io.File; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.sql.Connection; 
import java.sql.Statement; 
import java.sql.Driver; 
import java.sql.DriverManager; 
import java.sql.DriverPropertyInfo; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.Enumeration; 
import java.util.Properties; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 

/** 
* 
* @author Administrator 
*/ 
class com_mysql_jdbc_Driver implements Driver { 
    private Driver driver; 
    com_mysql_jdbc_Driver(Driver cmjd) { 
     this.driver = cmjd; 
    } 
    @Override 
    public boolean acceptsURL(String aurlS) throws SQLException { 
     return this.driver.acceptsURL(aurlS); 
    } 
    @Override 
    public Connection connect(String aurlS, Properties pP) throws SQLException { 
     return this.driver.connect(aurlS, pP); 
    } 
    @Override 
    public int getMajorVersion() { 
     return this.driver.getMajorVersion(); 
    } 
    @Override 
    public int getMinorVersion() { 
     return this.driver.getMinorVersion(); 
    } 
    @Override 
    public DriverPropertyInfo[] getPropertyInfo(String aurlS, Properties pP) throws SQLException { 
     return this.driver.getPropertyInfo(aurlS, pP); 
    } 
    @Override 
    public boolean jdbcCompliant() { 
     return this.driver.jdbcCompliant(); 
    } 
} 

public class DynMain { 

    /** 
    * @param args the command line arguments 
    */ 

    public static void main(String[] args) throws Exception { 
     /* please set to your path*/ 
     File file = new File("U:/mozsamples/mysql-connector-java-5.1.19-bin.jar"); 
     Driver cmjdD; 
     String aktCS; 
     String urlS = "jdbc:mysql://localhost/db"; 
     String userS = "must-be-set"; 
     String passS = "must-be-set"; 
     Connection con; 
     Statement stmt; 
     URLClassLoader clazzLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}); 
     JarFile jarFile = new JarFile(file); 
     Enumeration<JarEntry> entries = jarFile.entries(); 

     while (entries.hasMoreElements()) { 
      JarEntry element = entries.nextElement(); 
      if (element.getName().endsWith(".class")) { 
       String name = element.getName(); 
       if (name.contains("/integration/")) { 
        System.out.println("ignored: " + name); 
        continue; 
       } else 
       { 
       try {  
        aktCS = element.getName().replaceAll(".class", "").replaceAll("/", "."); 
        clazzLoader.loadClass(aktCS); 
        if (name.contains("com/mysql/jdbc/Driver")) { 
         cmjdD = (Driver)Class.forName(aktCS, true, clazzLoader).newInstance(); 
         try { 
         DriverManager.registerDriver(new com_mysql_jdbc_Driver(cmjdD)); 
         System.out.println("register Class: " + aktCS); 
         } catch (SQLException e) { 
          e.printStackTrace(); 
         } 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       } 
      } 
     } 
    try { 
    con = DriverManager.getConnection(urlS,userS,passS); 
    stmt = con.createStatement(); 
    /*ResultSet rs = stmt.executeQuery("select * from idcart where ID=255"); */ 

    stmt.close(); 
    } catch (SQLException esql) { 
     esql.printStackTrace(); 
    } 
    int j=0 ; 
    System.out.println("loaded Driver----------------------------------"); 
    for(Enumeration en = DriverManager.getDrivers() ; en.hasMoreElements() ; j++) 
     System.out.println(en.nextElement().getClass().getName()); 

    if (j==0) { System.out.println("Driverlist empty"); } 

    System.out.println("-----------------------------------------------"); 
    } 
} 

Выход:

register Class: com.mysql.jdbc.Driver 
ignored: com/mysql/jdbc/integration/c3p0/MysqlConnectionTester.class 
ignored: com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.class 
ignored: com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.class 
loaded Driver---------------------------------- 
sun.jdbc.odbc.JdbcOdbcDriver 
dynamicloading.com_mysql_jdbc_Driver 
----------------------------------------------- 

ОК ???

+0

К сожалению, в структуре JAR нет такой «интеграционной» папки. – Heka

+0

Я нашел id в «mysql-connector-java-5.0.4-bin.jar» и «mysql-connector-java-5.1.6-bin.jar». Скажите, пожалуйста, имя вашего файла .jar. –

+0

И он только что загружен [MySql download] (http://dev.mysql.com/downloads/mirror.php?id=407253) –

Смежные вопросы