java程序關于第三方jar包發布的另一種方法
大概我們每個人都有過這種經歷,編好了一個應用,當打成jar包后,當引用第三包時卻總是拋ClassNotFoundException 而無法正常運行。我現在知道的有兩種解決方法,一種是在manifest.mf中設置classpath,把所需的第三方包手動加進去,還有一種就是用是用第三方打包工具了,比如fatjar。今天察看Jmeter的源代碼時發現了另一種方法。為了更清楚些,下面進行舉例進行說明:
先新建一個工程,建一個類,源代碼如下:
package first;
import java.util.Date;
public class My {
public String getTime(){
return new Date().toString();
}
}
然后把它打成包,用來模擬第三方包,不妨取名first.jar.
然后,再建第二個工程,把剛才的包加入到這個工程中,新建類如下:
package mypackage;
import first.My;
public class Task {
public void start(String [] args){
My my = new My();
System.out.println(my.getTime());
}
}
start()方法作為咱們整個應用的入口函數,經測試發現沒有問題。到此,準備工作完畢,下面開始進行解決問題的關鍵部分了:
新建類NewDrever,其源代碼如下:
package mypackage;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.List;
public class NewDrever {
public static void main(String [] args){
File userDir = new File(System.getProperty("user.dir"));
String jmDir = userDir.getAbsoluteFile().getParent();
File libDirs = new File(jmDir+File.separator+"lib");
File [] libJars = libDirs.listFiles(new FilenameFilter(){
public boolean accept(File dir,String name) {
if(name.endsWith(".jar"))
return true;
return false;
}
});
List jars = new LinkedList();
//System.out.println(System.getProperty("java.class.path"));
StringBuffer classpath = new StringBuffer();
for(int i = 0;i < libJars.length;i++){
try {
jars.add(new URL("file","",libJars[i].getPath()));
classpath.append(System.getProperty("path.separator"));
classpath.append(libJars[i].getPath());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
System.setProperty("java.class.path",System.getProperty("java.class.path")+classpath.toString());
//System.out.println(System.getProperty("java.class.path"));
URLClassLoader loader = new URLClassLoader((URL[])jars.toArray(new URL[0]));
//Thread.currentThread().setContextClassLoader(loader);
try {
Class JMeter = loader.loadClass("mypackage.Task");
Object instance = JMeter.newInstance();
Method startup = JMeter.getMethod("start",new Class[]{(new String[0]).getClass()});
startup.invoke(instance,new Object[]{args});
} catch(Exception e) {
e.printStackTrace();
}
}
}
把第二個工程打成可執行的jar包,取名second.jar,新建一個文件夾,不妨取名為Test,test下面分別建lib和bin兩個文件夾,把first.jar和second.jar拷貝到lib中,把second.jar再考到bin下面一份。現在還沒有完畢,把bin下的second.jar的包中除了NewDrever.class全部刪掉,至此完畢。這時,進到bin目錄下 敲java -jar second.jar 會在控制臺打出當前的時間。而時間來自"第三方包"。