gpt4 book ai didi

tomcat加载jar异常问题的分析与解决

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章tomcat加载jar异常问题的分析与解决由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

现象描述:

项目使用springboot启动一个web项目,在启动阶段看到console中出现了异常“1.10.3-1.4.3\hdf5.jar  系统找不到指定的文件”,虽然这些异常不影响项目的正常运行,但作为一个严谨的技术人员,看到这些异常就像见到仇人一样,一定要除之而后快.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
java.io.filenotfoundexception: d:\.m2\repository\org\bytedeco\javacpp-presets\hdf5-platform\1.10.3-1.4.3\hdf5.jar (系统找不到指定的文件。)
  at java.util.zip.zipfile. open (native method)
  at java.util.zip.zipfile.<init>(zipfile.java:225)
  at java.util.zip.zipfile.<init>(zipfile.java:155)
  at java.util.jar.jarfile.<init>(jarfile.java:166)
  at java.util.jar.jarfile.<init>(jarfile.java:130)
  at org.apache.tomcat.util.compat.jrecompat.jarfilenewinstance(jrecompat.java:188)
  at org.apache.tomcat.util.scan.jarfileurljar.<init>(jarfileurljar.java:65)
  at org.apache.tomcat.util.scan.jarfactory.newinstance(jarfactory.java:49)
  at org.apache.tomcat.util.scan.standardjarscanner.process(standardjarscanner.java:374)
  at org.apache.tomcat.util.scan.standardjarscanner.processurls(standardjarscanner.java:309)
  at org.apache.tomcat.util.scan.standardjarscanner.doscanclasspath(standardjarscanner.java:266)
  at org.apache.tomcat.util.scan.standardjarscanner.scan(standardjarscanner.java:229)
  at org.apache.jasper.servlet.tldscanner.scanjars(tldscanner.java:262)
  at org.apache.jasper.servlet.tldscanner.scan(tldscanner.java:104)
  at org.apache.jasper.servlet.jasperinitializer.onstartup(jasperinitializer.java:101)
  at org.apache.catalina.core.standardcontext.startinternal(standardcontext.java:5204)
  at org.apache.catalina.util.lifecyclebase.start(lifecyclebase.java:150)
  at org.apache.catalina.core.containerbase$startchild.call(containerbase.java:1421)
  at org.apache.catalina.core.containerbase$startchild.call(containerbase.java:1411)
  at java.util.concurrent.futuretask.run$$$capture(futuretask.java:266)
  at java.util.concurrent.futuretask.run(futuretask.java)
  at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1149)
  at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:624)
  at java.lang.thread.run(thread.java:748)
 
2019-03-29 18:09:08.303 warn 16940 --- [ost-startstop-1] o.a.tomcat.util.scan.standardjarscanner : failed to scan [ file : /d :/.m2 /repository/org/bytedeco/javacpp-presets/hdf5-platform/1 .10.3-1.4.3 /hdf5-linux-x86 .jar] from classloader hierarchy
 
java.io.filenotfoundexception: d:\.m2\repository\org\bytedeco\javacpp-presets\hdf5-platform\1.10.3-1.4.3\hdf5-linux-x86.jar (系统找不到指定的文件。)
......
2019-03-29 18:09:08.578 warn 16940 --- [ost-startstop-1] o.a.tomcat.util.scan.standardjarscanner : failed to scan [ file : /d :/.m2 /repository/org/bytedeco/javacpp-presets/hdf5-platform/1 .10.3-1.4.3 /hdf5-linux-x86_64 .jar] from classloader hierarchy
 
java.io.filenotfoundexception: d:\.m2\repository\org\bytedeco\javacpp-presets\hdf5-platform\1.10.3-1.4.3\hdf5-linux-x86_64.jar (系统找不到指定的文件。)

项目环境说明 。

  • tomcat:使用springboot内置版本 8.5.29
  • 使用maven进行依赖管理
  • spring boot 版本为2.0.1
  • spring 框架 版本为5.0.5
  • 项目引用了deep learn 4 java(一个非常棒的java的机器学习库)
?
1
2
3
4
5
<dependency>
<groupid>org.deeplearning4j< /groupid >
<artifactid>deeplearning4j-core< /artifactid >
<version>1.0.0-beta3< /version >
< /dependency >

有问题的jar依赖关系 。

tomcat加载jar异常问题的分析与解决

跟踪分析 。

既然是在启动阶段报错,那就找到启动类添加断点,一步步跟踪下到底哪个阶段报的错误,然后再分析出错的原因。我跟踪调试了springboot的代码,找到jar的加载位置。主要的几个类和方法如下所示:

跟踪类org.apache.tomcat.util.scan.standardjarscanner 。

方法doscanclasspath(...) 。

该方法会对所有classloader进行遍历,加载每一个classloader中jar包 。

tomcat加载jar异常问题的分析与解决

上图标红处就是关键代码,其中变量classpathurlstoprocess中存放的是所有待加载的jar信息,主要是jar包路径信息,我们可以看到这里面和我们在maven中看到的jar包是一样的.

tomcat加载jar异常问题的分析与解决

  • 方法processurls(...)

该方法会对当前classloader的所有jar,也就是对classpathurlstoprocess进行堆栈操作,然后处理每一个jar包。关键代码如下所示.

tomcat加载jar异常问题的分析与解决

  • 方法process()

该方法会对每一个jar进行加载及分析处理,该方法中重点关注 。

?
1
processmanifest(jar, iswebapp, classpathurlstoprocess)

tomcat加载jar异常问题的分析与解决

  • 方法 processmanifest

该方法会处理jar中的manifest文件,对manifest文件中的class-path进行分隔处理,对其中的内容作为新的依赖jar再插入到classpathurlstoprocess中(processurls方法会按照堆栈结果加载其中的jar) 。

tomcat加载jar异常问题的分析与解决

原因分析 。

其实问题就是出manifest文件中的classpath,通过分析代码我们知道tomcat除了加载了我们maven管理的jar包之外,还会对jar中的manifest文件进行分析,如果其中存在classpath,他会将其中的内容也添加jar包依赖中,并对这些jar包进行加载.

我们打开其中hdf5-1.10.3-1.4.3.jar的manifest文件作为例子看看错误出在哪里.

tomcat加载jar异常问题的分析与解决

大家注意到了没有,这里的jar包没有路径也没有版本号,这就导致tomcat加载的时候按照hdf5-1.10.3-1.4.3.jar的路径进行加载.

然而我们的工程中在对应位置并不存在这些jar,这也就导致了找不到jar的异常。我们工程中实际上有这些jar,只不过路径和名字不一样。在上图左边大家可以看到maven中其实已经有了这些jar,只不过名字后面多了版本号,路径在各自的maven仓库中.

到这里我们已经将出现问题的原因弄清楚了,接下来我们考虑下怎么解决.

解决方案 。

方案一:

删除manifest中的classpath或者删除manifest文件,这样就避免了加载不存在的jar包。但是每次maven更新的时候可能会覆盖掉你的修改,导致异常再次出现.

方案二:

按照加载提示的路径,将对应jar包复制过去并改名去掉版本号,但这样会造成jar冗余,同样的jar会加载两个.

方案三:

降级tomcat版本,使用8.5.0 或以下版本。8.5.0版本中不会对manifest进行分析加载,这样也就不会出现我们的异常了.

方案四 。

增加一下代码设置不扫描manifest文件.

?
1
2
3
4
5
6
7
8
9
@bean
public tomcatservletwebserverfactory tomcatfactory() {
  return new tomcatservletwebserverfactory() {
   @override
   protected void postprocesscontext(context context) {
    ((standardjarscanner) context.getjarscanner()).setscanmanifest( false );
   }
  };
}

tomcat加载jar异常问题的分析与解决

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我的支持.

原文链接:https://www.jianshu.com/p/7ed2eaffbc18 。

最后此篇关于tomcat加载jar异常问题的分析与解决的文章就讲到这里了,如果你想了解更多关于tomcat加载jar异常问题的分析与解决的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com