moon-util工具

使用monn-util工具包实现解析自定义表达式报错如下:java.nio.file.NoSuchFileException: com/moon/core

1.报错信息如下(太长了只截图了重要部分):

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.ExceptionInInitializerError
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ExceptionInInitializerError: null 
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)
        at org.springframework.web.servlet.mc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
        ... 42 common frames omitted
Caused by: java.lang.IllegalStateException: java.nio.file.NoSuchFileException: com/moon/core
        at com.moon.core.lang.ThrowUtil.runtime(ThrowUtil.java:128)
        at com.moon.core.lang.PackageScanner.scanFromUrl(PackageScanner.java:65)
        at com.moon.core.lang.PackageScanner.scanOf(PackageScanner.java:40)
        at com.moon.core.lang.PackageScanner.scan(PackageScanner.java:29)

        at com.moon.runner.core.IGetLoad.<clinit>(IGetLoad.java:28)
        ... 106 common frames omitted
Caused by: java.nio.file.NoSuchFileException: com/moon/core
        at com.sun.nio.zipfs.ZipPath.getAttributes(ZipPath.java:666)
        at com.sun.nio.zipfs.ZipFileSystemProvider.readAttributes(ZipFileSystemProvider.java:294)
        at java.nio.file.Files.readAttributes(Files.java:1737)
        at java.nio.file.FileTreeWalker.getAttributes(FileTreeWalker.java:219)

2.分析问题

2.1 首先我们看报错信息,是读取com/moon/core包的时候未找到文件,接着我们分析报错位置PackageScanner.scanFromUrl

重要的是下面这段代码:

看图中分为两块:

(1)项目里引用moon-util的包,然后把你的项目编译成jar运行,这时候图中的url.getPath()为 

window: file:/F\\xxx\xxx\\你项目的jar!\BOOT-INF/\ib\moon-util-0.0.45.jar!/com/coom/core
linux: file:/usr/local/xxx/xxx/你项目的jar!\BOOT-INF/\ib\moon-util-0.0.45.jar!/com/coom/core

注意:BOOT-INF文件夹下的文件是受限制的  不能通过file去读取 

经过图中标记位置的执行

window:F\\xxx\xxx\\你项目的jar

linux:usr/local/xxx/xxx/你项目的jar

接着往下运行的时候 他会去解析的路径下去找com/coom/core下的所有文件(看(2)就明白了为什么这个解析的地址不对),因为你项目里没有com/coom/core包所以报出异常

(2)直接在本地idea启动项目url.getPath()为file:/F\\xxx\xxx\maven\moon-util-0.0.45.jar!/com/coom/core
经过解析得出F\\xxx\xxx\maven\moon-util-0.0.45.jar 可以直接读取出jar里面的包

3.得出结论:

(1) jar方式运行 解析的地址不对

(2) jar方式运行 读取不到里面的monn-util-0.0.45.jar文件


4.解决问题

1.jar方式运行 解析的地址不对

String target = url.getPath().replaceFirst("file:/", "").replaceFirst("!.*", "");

改为

String target = url.getPath().substring(0,url.getPath().lastIndexOf("!"));(这里的地址要用到urlConnection读取BOOT-INF下的jar)

2.jar方式运行 读取不到里面的monn-util-0.0.45.jar文件

List<String> resultClassPaths = new ArrayList<>();// 这里的list看源码得知 这块的逻辑主要是读取moon-util下的com/coom/core下的所有类的路径返回
URL jarUrl = new URL(jar, null, 0, target);
URLConnection jarConn = jarUrl.openConnection();
if (jarConn instanceof JarURLConnection) {
    JarURLConnection result = (JarURLConnection) jarConn;
    JarInputStream jarInputStream = new JarInputStream(result.getInputStream());
    JarEntry entry;
    while ((entry = jarInputStream.getNextJarEntry()) != null) {
        if(entry.getName().contains(packageName) && entry.getName().contains(DOT_CLASS)){
            resultClassPaths.add(entry.getName().replace(DOT_CLASS,"").replace('/', '.'));
        }
    }
}

总结:

    主要修改的部分就是针对于地址的截取,跟jar方式部署读取jar包内BOOT-INF下的文件的方式。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值