Java 反射解析指定jar包出现ClassNotFoundException异常,处理方式
在上篇博文中写道,通过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包,避免手动输入繁琐