我用Java实现了一个简单的基于插件的应用程序。主插件类派生自名为“Plugin”的抽象类。应用程序从JAR文件中读取该类,并通过创建该类的实例来运行该插件。标准程序我猜:)
到目前为止,一切都很好。但是当我将一个库包含到我的插件中时会出现问题,例如MySQL Connector。执行后抛出异常NoClassDefFoundError和ClassNotFoundException。我通过将MySQL连接器库添加到主应用程序来克服这个问题,但那又有什么意义呢? :)
我不是Java专家,所以我不确定是否有任何替代解决方案,例如为库等定义类路径。
这是我的插件加载器: http://pastebin.com/90rQ9NfJ
这是我的插件基类: http://pastebin.com/Juuicwkm
我正在从GUI执行:
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 :(得分:0)
您也应该包含您的源代码。
您是如何通过命令行或GUI执行该类的?如果从命令行,则必须在类路径(java -classpath)中包含MySQLConnector库以及任何其他依赖库。这个问题的最佳答案可以帮助您 - Java: how to import a jar file from command line
答案 1 :(得分:0)
如果是这种情况,你的类是一个Mysql驱动程序,你必须排除(在类调用时)不可用的类。在.jar文件的文件夹中有一个名为“integration”的文件夹,它包含“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
-----------------------------------------------
好的???