在上篇博文中寫道,通過Java的反射機制解析了指定的jar包,得到了其中的全類名,方法名,參數名,但是也許有的博友在使用時應該會發現存在一點問題。問題就是在解析簡單的接口案例時可以完整的解析,但是如果解析復雜的jar包時出現ClassNotFoundException的異常。那么何為復雜的Jar包?我們平時寫的小DOme,基本上依賴就JDK的jar包就可實現,但是當我們項目中引入其他的依賴jar包時,那么在利用之前寫的方法通過反射去解析時,就會出現ClassNotFoundException的異常。這篇文章我們就重點來解決該問題。
我們還是以一個簡單的案例來演示一下!
例如:我們要解析:HZM-payment-api-1.1.1021.jar 這個復雜的jar包。
我們知道這個jar包依賴的jar包有:activation-1.1.jar,aliyun-java-sdk-core-3.0.0.jar,aliyun-java-sdk-dm-3.0.0-rc1.jar,commons-codec-1.6.jar,commons-io-2.1.jar。。。。的一系類jar包。
我們接下來要做的就是將這些jar包 添加到 URLClassLoader 中構建去運行環境,這樣就不會出現異常了。具體代碼如下:
public class jarTest {
public static void getJarName(String jarFile) throws Exception {
try{
//通過將給定路徑名字符串轉換為抽象路徑名來創建一個新File實例
File f = new File(jarFile);
URL url1 = f.toURI().toURL();
File f1 = new File("F:\\lib\\lib\\activation-1.1.jar");
URL url2 = f1.toURI().toURL();
File f2 = new File("F:\\lib\\lib\\aliyun-java-sdk-core-3.0.0.jar");
URL url3 = f2.toURI().toURL();
File f3 = new File("F:\\lib\\lib\\aliyun-java-sdk-dm-3.0.0-rc1.jar");
URL url4 = f3.toURI().toURL();
File f4 = new File("F:\\lib\\lib\\commons-codec-1.6.jar");
URL url5 = f4.toURI().toURL();
File f5 = new File("F:\\lib\\lib\\commons-io-2.1.jar");
URL url6 = f5.toURI().toURL();
File f6 = new File("F:\\lib\\lib\\commons-lang3-3.1.jar");
URL url7 = f6.toURI().toURL();
File f7 = new File("F:\\lib\\lib\\commons-logging-1.1.1.jar");
URL url8 = f7.toURI().toURL();
File f8 = new File("F:\\lib\\lib\\ELP-common-branch-1.95.jar");
URL url9 = f8.toURI().toURL();
File f9 = new File("F:\\lib\\lib\\fastjson-1.1.43.jar");
URL url10 = f9.toURI().toURL();
File f10 = new File("F:\\lib\\lib\\httpclient-4.2.1.jar");
URL url11 = f10.toURI().toURL();
File f11 = new File("F:\\lib\\lib\\httpcore-4.2.1.jar");
URL url12 = f11.toURI().toURL();
File f12 = new File("F:\\lib\\lib\\jaxrs-api-3.0.7.Final.jar");
URL url13 = f12.toURI().toURL();
File f13 = new File("F:\\lib\\lib\\jboss-annotations-api_1.1_spec-1.0.1.Final.jar");
URL url14 = f13.toURI().toURL();
File f14 = new File("F:\\lib\\lib\\jcip-annotations-1.0.jar");
URL url15 = f14.toURI().toURL();
File f15 = new File("F:\\lib\\lib\\jcl-over-slf4j-1.7.10.jar");
URL url16 = f15.toURI().toURL();
File f16 = new File("F:\\lib\\lib\\log4j-over-slf4j-1.7.10.jar");
URL url17 = f16.toURI().toURL();
File f17 = new File("F:\\lib\\lib\\logback-classic-1.1.2.jar");
URL url18 = f17.toURI().toURL();
File f18 = new File("F:\\lib\\lib\\resteasy-jaxrs-3.0.7.Final.jar");
URL url19 = f18.toURI().toURL();
File f19 = new File("F:\\lib\\lib\\slf4j-api-1.7.10.jar");
URL url20 = f19.toURI().toURL();
File f20 = new File("F:\\lib\\lib\\taobao-sdk-java-auto-20160607.jar");
URL url21 = f20.toURI().toURL();
File f21 = new File("F:\\lib\\lib\\HZM-common-1.0.jar");
URL url22 = f21.toURI().toURL();
URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url1,url2,url3,url4,
url5,url6,url7,url8,url9,url10,url11,url12,url13,url4,url15,url16,url17,
url18,url19,url20,url21,url22},Thread.currentThread().getContextClassLoader());
//通過jarFile和JarEntry得到所有的類
JarFile jar = new JarFile(jarFile);
System.out.println("解析的文件名為:"+jarFile);
//返回zip文件條目的枚舉
Enumeration<JarEntry> enumFiles = jar.entries();
JarEntry entry;
//測試此枚舉是否包含更多的元素
while(enumFiles.hasMoreElements()){
entry = (JarEntry)enumFiles.nextElement();
if(entry.getName().indexOf("META-INF")<0){
String classFullName = entry.getName();
if(!classFullName.endsWith(".class")){
classFullName = classFullName.substring(0,classFullName.length()-1);
} else{
//去掉后綴.class
String className = classFullName.substring(0,classFullName.length()-6).replace("/", ".");
Class<?> myclass = myClassLoader.loadClass(className);
// Class<?> myclass=myClassLoader.findClass(className);
//判斷是否為接口 只解析接口
boolean isInterface =myclass.isInterface();
if(isInterface){
//打印類名
System.out.println("*****************************");
System.out.println("全類名:" + className);
System.out.println(isInterface);
//得到類中包含的屬性
Method[] methods = myclass.getMethods();
for (Method method : methods) {
String methodName = method.getName();
System.out.println("方法名稱:" + methodName);
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> clas : parameterTypes) {
// String parameterName = clas.getName();
String parameterName = clas.getSimpleName();
System.out.println("參數類型:" + parameterName);
}
System.out.println("==========================");
}
}
}
}
}
} catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
//jar包所在路徑
getJarName("F:\\lib\\lib\\HZM-payment-api-1.1.1021.jar");
}
}
可能會有很多博友會覺得手動添加jar包會很麻煩。接下來我將寫一篇通過文件上傳來上傳jar包,避免手動輸入繁瑣
