在Java中扫描jar包中的文件

最近在做一个功能,需要扫描某个包下所有类,根据类的注解去做相关的初始化处理。在本地源代码环境下正常运行,打成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);
                }
            }
        }
    }
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值