最近在做一个功能,需要扫描某个包下所有类,根据类的注解去做相关的初始化处理。在本地源代码环境下正常运行,打成jar包给其他模块引入,运行时报错(URI is not hierarchical)。
本地测试代码:获取jar包中的文件:
public static void main(String[] args) throws IOException {
ClassPathResource classPathResource = new ClassPathResource("com.alibaba.druid".replace(".", "/"));
File file = new File(classPathResource.getURI());
System.out.println(file);
}
报错:
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:418)
at com.yuncheng.viewengine.translator.TranslatorFactory.main(TranslatorFactory.java:273)
文件和jar包中的文件获取方式有所区别,改成以下方式获取:
private static void scanForRegister() throws IOException {
String packageName = "com.alibaba.druid";
String packageDirName = packageName.replace('.', '/');
Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
// 循环迭代下去
while (dirs.hasMoreElements()) {
// 获取下一个元素
URL url = dirs.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上
if ("file".equals(protocol)) {
// 获取包的物理路径
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
fileScan(new File(filePath), packageName);
} else if ("jar".equals(protocol)) {
// 如果是jar包文件
// 定义一个JarFile
try {
// 获取jar
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
// 从此jar包 得到一个枚举类
Enumeration<JarEntry> entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/开头的
if (name.charAt(0) == '/') {
// 获取后面的字符串
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾 是一个包
if (idx != name.length() - 1 && !entry.isDirectory()) {
// 如果是一个.class文件 而且不是目录
if (name.endsWith(".class")) {
// 去掉后面的".class" 获取真正的类名
name = name.replace("/", ".");
String className = name.substring(0, name.length() - 6);
// 注册
classNameRegister(className);
}
}
}
}
} catch (IOException e) {
log.error("translator scan failed", e);
}
}
}
}