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);
}
}
}