使用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下的文件的方式。