URLClassLoader 加载外部jar获取 JarFile(HTTP)问题(JarURLConnection)
当通过URLClassLoader去load一个外部的jar(HTTP)后获取这个jar实体对象会有一点小问题。正常情况下:
URL u = getClass().getProtectionDomain().getCodeSource().getLocation();即可获取到当前的jar路径,因为是URLClassLoader所以这里拿到的URI可能是HTTP协议。即:http://xxx.com/xxx.jar。这个时候如果:
JarURLConnection juc = (JarURLConnection) new URL(name).openConnection();无法从HttpURLConnection转为JarURLConnection:
java.lang.ClassCastException: sun.net.www.protocol.http.HttpURLConnection cannot be cast to java.net.JarURLConnection
API中给出的Demo:
一个JAR实体: jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class 一个JAR文件 jar:http://www.foo.com/bar/baz.jar!/ 一个JAR目录 jar:http://www.foo.com/bar/baz.jar!/COM/foo/ !/ 作为引用分割
这样写似乎就可以了:
//URL a = getClass().getResource("/" + getClass().getName().replace('.', '/') + ".class"); URL a = getClass().getResource(""); JarURLConnection juc = (JarURLConnection) a.openConnection(); JarFile jf = juc.getJarFile();
测试代码:
package com.test.hello; import java.io.File; import java.net.JarURLConnection; import java.net.URL; import java.nio.file.Path; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class JarTest { public void getAllClass(File f, Path path, List<String> ls){ if(f.isDirectory()){ File[] files = f.listFiles(); for (int i = 0; i < files.length; i++) { getAllClass(files[i],path,ls); } }else{ if(f.toString().endsWith(".class")){ String classPath = f.toString().replaceFirst(path.toString(), ""); classPath = classPath.startsWith("/")?classPath.replaceFirst("/", "").replaceAll("/", "."):classPath; ls.add(classPath.substring(0,classPath.length()-".class".length())); } } } public void getClassPath(List<String> ls){ try { URL u = getClass().getProtectionDomain().getCodeSource().getLocation(); if(!"http".equalsIgnoreCase(u.toURI().getScheme()) && new File(u.toURI()).isDirectory()){ File f = new File(u.toURI()); getAllClass(f,f.toPath(),ls); }else{ URL a = getClass().getResource(""); JarURLConnection juc = (JarURLConnection) a.openConnection(); JarFile jf = juc.getJarFile(); Enumeration<JarEntry> je = jf.entries(); while (je.hasMoreElements()) { JarEntry jar = je.nextElement(); if(jar.getName().endsWith(".class")){ String classPath = jar.getName().replaceAll("/", "."); ls.add(classPath.substring(0,classPath.length()-".class".length())); } } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { List<String> ls = new ArrayList<String>(); new JarTest().getClassPath(ls); for(String s:ls){ System.out.println(s); } } }