-
单个 tomcat 下运行多个 war 应用, 问题与解决方法
公司内有两个 Java web 应用,最近需要去客户处展示,需要安装在一台笔记本电脑上。
两个 Java web 应用,都有些年头了,最初使用 Java 1.6 开发,现使用 Java 8 重新编译。
有一台 16G 内存、500G 硬盘的笔记本,惠普战66。尝试将两个Java web 应用安装在此电脑里同一个 tomcat 内。
想着很简单,打包成 war 文件(分别是 zsso.war, pkg.war), 复制到 C:\java\apache-tomcat-9.0.52\webapps 目录下,改些配置文件,启动 tomcat 的 bin\startup.bat , 应该就行了。
其中,zsso.war 是公司的一个单点登录软件产品,自带用户登录、权限配置等功能。此次是 pkg.war 更改时间紧张,不想再去动权限配置功能,想着可以借用 zsso.war 的功能,节省点开发时间,就算免费送客户一套单点登录系统好了。节省了开发时间,也是好的。
结果运行报错,pkg 能启动起来,zsso 启动失败,tomcat 自带的 docs, examples, host-manager,manager,ROOT 几个应用也启动失败。报错信息相同,均为 XML 解析的 class 找不到:
复制代码
1 org.apache.catalina.LifecycleException: Failed to initialize component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/zsso]]
2 at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112)
3 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:140)
4 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
5 at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
6 at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
7 at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
8 at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
9 at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
10 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
11 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
12 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
13 at java.base/java.lang.Thread.run(Thread.java:832)
14 Caused by: javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found
15 at java.xml/javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:194)
16 at java.xml/javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:147)
17 at java.xml/javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:226)
18 at java.xml/javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:219)
19 at org.apache.tomcat.util.digester.Digester.getFactory(Digester.java:474)
20 at org.apache.tomcat.util.digester.Digester.getParser(Digester.java:665)
21 at org.apache.catalina.startup.ContextConfig.init(ContextConfig.java:730)
22 at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:310)
23 at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
24 at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:395)
25 at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:108)
26 ... 11 more
27 Caused by: java.lang.ClassNotFoundException: org/apache/xerces/jaxp/SAXParserFactoryImpl
28 at java.base/java.lang.Class.forName0(Native Method)
29 at java.base/java.lang.Class.forName(Class.java:427)
30 at java.xml/javax.xml.parsers.FactoryFinder.getProviderClass(FactoryFinder.java:119)
31 at java.xml/javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:183)
32 ... 21 more
复制代码
查 tomcat 文档,http://tomcat.apache.org/tomcat-9.0-doc/class-loader-howto.html,里面专门有一章节 "XML Parsers and Java"。虽然没看明白,这个与我们此次报错有什么关联。但猜测,Java 中的 XML 解析相关类,与 class loader 紧密相关。
经调查,pkg.war 中使用了 SAX XML 解析,而 zsso.war 中没有使用。
推测 pkg.war 中使用了 SAX XML 解析,用了某个特定方式,导致影响了 zsso.war,也影响了 tomcat 自带的几个 web 应用及示例。
查找代码,有如下:
复制代码
1 System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
2
3 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
4 parserFactory.setValidating(false);
5 parserFactory.setNamespaceAware(false);
6
7 RefrenceHandler mySaxParser = new RefrenceHandler();
8 SAXParser parser = parserFactory.newSAXParser();
9 parser.parse(refIs, mySaxParser);
复制代码
经测试,去掉第一行代码,问题解决。
最后回顾:
代码行:
System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
影响了 tomcat 中的多个 war 应用,也影响了 tomcat 自带的几个 web 应用及示例。
之前 Java 1.6 时,需要此行代码。最新的 Java 8 ,不需要此行代码。
因此,Java web 代码中,应避免/减少使用 System.setProperty(...);
======欢迎转载,转载请注明出处, https://www.cnblogs.com/jacklondon/
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比