Tomcat 的 catalina.properties 配置文件说明及使用配置文件处理异常

说明:
Tomcat的catalina.properties文件位于%CATALINA_HOME%/conf/目录下面,该文件主要配置tomcat的安全设置、类加载设置、不需要扫描的类设置、字符缓存设置四大块。本文介绍主要以 tomcat-9.0.33为例,其他版本类似。
官方文档:tomcat-9.0-doc
使用这个配置文件的类CatalinaProperties。
这个类就是一个属性获取的公共类。它的功能是管理catalina.properties类文件中的配置属性获取,只有一个方法getPropertity(String name).类图和流程图如下:
在这里插入图片描述

一、文件内容组成

catalina.properties中的设置项包括四个部分:
第一部分:安全设置
package.access
package.definition
第二部分:类加载设置
common.loader
server.loader
shared.loader
第三部分:忽略扫描和需要扫描类设置
tomcat.util.scan.DefaultJarScanner.jarsToSkip #不需要扫描
tomcat.util.scan.StandardJarScanFilter.jarsToScan #需要扫描
第四部分:字符缓存设置
tomcat.util.buf.StringCache.byte.enabled
tomcat.util.buf.StringCache.char.enabled
tomcat.util.buf.StringCache.trainThreshold
tomcat.util.buf.StringCache.cacheSize

1、安全设置

Java SecurityManager允许Web浏览器在其自己的沙箱中运行小程序,以防止不受信任的代码访问本地文件系统上的文件,连接到未加载小程序的主机等。以与SecurityManager保护您免受浏览器中运行的不受信任小程序相同的方式,在运行Tomcat时使用SecurityManager可以保护您的服务器免受特洛伊木马servlet,JSP,JSP Bean和标记库的侵害。甚至是无心的错误。
想象一下,如果某人被授权在您的站点上发布JSP,则无意中将以下内容包括在其JSP中:

<% System.exit(1); %>

Tomcat每次执行此JSP时,Tomcat都会退出。使用Java SecurityManager只是系统管理员可以用来保持服务器安全可靠的另一道防线。
catalina.properties文件中关于安全的设置

package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.

具体请查阅官方文档 :
安全管理.
Java SE安全编码准则

2、类加载设置

类加载器的使用方法
像许多服务器应用程序一样,Tomcat安装了各种类加载器(即实现的类java.lang.ClassLoader),以允许容器的不同部分以及容器上运行的Web应用程序可以访问可用类和资源的不同存储库。该机制用于提供Servlet规范2.4版中定义的功能-特别是9.4和9.6节。

在Java环境中,类加载器排列在父子树中。通常,当要求类加载器加载特定的类或资源时,它首先将请求委派给父类加载器,然后仅在父类加载器找不到所请求的类或资源时才在其自己的存储库中查找。请注意,Web应用程序类加载器的模型与此略有不同,如下所述,但是主要原理是相同的。

Tomcat启动时,它将创建一组类加载器,这些类加载器被组织为以下父子关系,其中父类加载器位于子类加载器之上:

        Bootstrap
           |
         System
           |
         Common
        /     \
    Webapp1   Webapp2 ...

具体请查阅官方文档 :
类加载器的使用方法
1、类加载器定义
如上图所示,Tomcat在初始化时会创建以下类加载器:

引导程序 -该类加载器包含Java虚拟机提供的基本运行时类,以及系统扩展目录($JAVA_HOME/jre/lib/ext)中存在的JAR文件中的所有类。 注意:某些JVM可能将其实现为多个类加载器,或者根本不可见(作为类加载器)。

系统 -通常从CLASSPATH环境变量的内容初始化该类加载器。所有这些类对于Tomcat内部类和Web应用程序都是可见的。但是,标准Tomcat启动脚本($CATALINA_HOME/bin/catalina.sh或 %CATALINA_HOME%\bin\catalina.bat)完全忽略CLASSPATH环境变量本身的内容,而是从以下存储库构建System类加载器:

$ CATALINA_HOME / bin / bootstrap.jar —包含用于初始化Tomcat服务器的main()方法,以及它依赖的类加载器实现类。

$ CATALINA_BASE / bin / tomcat-juli.jar或 $ CATALINA_HOME / bin / tomcat-juli.jar —记录实现类。其中包括对java.util.loggingAPI的增强类 ,称为Tomcat JULI,以及由Tomcat内部使用的Apache Commons Logging库的程序包重命名副本。有关更多详细信息,请参见日志记录文档。

如果tomcat-juli.jar是出现在 $ CATALINA_BASE / bin中,它被用来代替一个在 $ CATALINA_HOME / bin中。在某些日志记录配置中很有用

$ CATALINA_HOME / bin / commons-daemon.jar — Apache Commons Daemon项目中的类。此JAR文件在| CLASSPATH创建者 catalina.bat|中不存在。.sh脚本,但从bootstrap.jar的清单文件引用。

通用 -该类加载器包含对Tomcat内部类和所有Web应用程序都可见的其他类。

通常情况下,应用类应该不 放在这里。此类加载器搜索的位置由common.loader$ CATALINA_BASE / conf / catalina.properties中的属性定义。默认设置将按列出的顺序搜索以下位置:

解压后的类和资源 $CATALINA_BASE/lib
JAR文件 $CATALINA_BASE/lib
解压后的类和资源 $CATALINA_HOME/lib
JAR文件 $CATALINA_HOME/lib
默认情况下,这包括以下内容:

注解-api.jar — JavaEE注解类。
catalina.jar — Tomcat的Catalina servlet容器部分的实现。
catalina-ant.jar — Tomcat Catalina Ant任务。
catalina-ha.jar —高可用性软件包。
catalina-ssi.jar —服务器端包含模块。
catalina-storeconfig.jar —从当前状态生成XML配置文件
catalina-tribes.jar —组通信程序包。
ecj-*。jar — Eclipse JDT Java编译器。
el-api.jar — EL 3.0 API。
jasper.jar — Tomcat Jasper JSP编译器和运行时。
jasper-el.jar — Tomcat Jasper EL实现。
jsp-api.jar — JSP 2.3 API。
servlet-api.jar — Servlet 4.0 API。
tomcat-api.jar — Tomcat定义的几个接口。
tomcat-coyote.jar -Tomcat连接器和实用程序类。
tomcat-dbcp.jar —基于程序包重命名的Apache Commons Pool 2和Apache Commons DBCP 2的数据库连接池实现。
tomcat-i18n-**。jar —包含其他语言资源包的可选JAR。由于默认捆绑包还包含在每个单独的JAR中,因此如果不需要消息的国际化,可以安全地删除它们。
tomcat-jdbc.jar —一种替代的数据库连接池实现,称为Tomcat JDBC池。有关更多详细信息,请参见 文档。
tomcat-util.jar -Apache Tomcat的各种组件使用的通用类。
tomcat-websocket.jar — WebSocket 1.1的实现
websocket-api.jar — WebSocket 1.1 API

WebappX —为部署在单个Tomcat实例中的每个Web应用程序创建一个类加载器。/WEB-INF/classesWeb应用程序目录中的所有解压缩类和资源,以及Web应用程序/WEB-INF/lib目录下的JAR文件中的类和资源,对于此Web应用程序均可见,但对其他Web应用程序不可见。

如上所述,Web应用程序类加载器不同于默认的Java委托模型(根据Servlet规范2.4版的建议,第9.7.2节Web应用程序类加载器)。当处理从Web应用程序的WebappX类加载器加载类的请求时,该类加载器将首先在本地存储库中查找,而不是在看前委派。也有例外。属于JRE基类的类不能被覆盖。有一些例外,例如可以使用适当的JVM功能覆盖XML解析器组件,JVM功能是Java <= 8的认可标准重写功能,而Java 9+是可升级的模块功能。最后,对于由Tomcat(Servlet,JSP,EL,WebSocket)实现的规范,Web应用程序类加载器将始终首先委托JavaEE API类。Tomcat中的所有其他类装入器都遵循通常的委托模式。

因此,从Web应用程序的角度来看,类或资源的加载按以下顺序查找以下存储库:

JVM的Bootstrap类
/ WEB-INF /您的网络应用程序类
Web应用程序的/WEB-INF/lib/*.jar
系统类加载器类(如上所述)
通用类加载器类(如上所述)
如果使用配置了Web应用程序类加载器 , 在Tomcat配置文件context.xml中,那么顺序将变为:

JVM的Bootstrap类
系统类加载器类(如上所述)
通用类加载器类(如上所述)
/ WEB-INF /您的网络应用程序类
Web应用程序的/WEB-INF/lib/*.jar
Common的配置是通过 catalina.properties中的common.loader设置的。
2、common.loader设置
通常情况下,common.loader是已经设置好的,不需要修改。
common.loader包括以下路径:

unpacked classes and resources in $CATALINA_BASE/lib
JAR files in $CATALINA_BASE/lib
unpacked classes and resources in $CATALINA_HOME/lib
JAR files in $CATALINA_HOME/lib

Tomcat可以通过catalina.properties的server和shared设置,为webapp提供公用类库。
使一些公用的、不需要与webapp放在一起的设置信息单独保存,在更新webapp的war的时候无需更改webapp的设置。
通用 -该类加载器包含使Tomcat内部类和所有Web应用程序都可见的其他类。

通常情况下,应用类应该不 放在这里。此类加载器搜索的位置由common.loader在$ CATALINA_BASE / conf / catalina.properties中的属性定义。默认设置将按照列出的顺序搜索以下位置:
解压后的类和资源 $CATALINA_BASE/lib
JAR文件 $CATALINA_BASE/lib
解压后的类和资源 $CATALINA_HOME/lib
JAR文件 $CATALINA_HOME/lib
默认情况下,这包括以下内容:

annotations-api.jar —  JavaEE注解类。
catalina.jar — Tomcat的Catalina servlet容器部分的实现。
catalina-ant.jar — Tomcat Catalina Ant任务。
catalina-ha.jar —高可用性软件包。
catalina-ssi.jar —服务器端包含模块。
catalina-storeconfig.jar —从当前状态生成XML配置文件
catalina-tribes.jar —组通信程序包。
ecj-*。jar — Eclipse JDT Java编译器。
el-api.jar — EL 3.0 API。
jasper.jar — Tomcat Jasper JSP编译器和运行时。
jasper-el.jar — Tomcat Jasper EL实现。
jsp-api.jar — JSP 2.3 API。
servlet-api.jar — Servlet 4.0 API。
tomcat-api.jar — Tomcat定义的几个接口。
tomcat-coyote.jar — Tomcat连接器和实用程序类。
tomcat-dbcp.jar —基于Apache Commons Pool 2和Apache Commons DBCP 2的程序包重命名副本的数据库连接池实现。
tomcat-i18n-**。 jar-包含其他语言资源包的可选JAR。由于默认捆绑包还包含在每个单独的JAR中,因此如果不需要消息的国际化,可以安全地删除它们。
tomcat-jdbc.jar —一种替代的数据库连接池实现,称为Tomcat JDBC池。有关更多详细信息,请参见 文档。
tomcat-util.jar -Apache Tomcat的各种组件使用的通用类。
tomcat-websocket.jar — WebSocket 1.1的实现
websocket-api.jar — WebSocket 1.1 API

这些都是系统和工具类,比如数据库的驱动类库、log 类库可以放到此处,web应用的jar 不要放到common.loader 中。
3、server.loader 和 shared.loader
在common.loader 加载完后,tomcat启动程序会检查 catalina.properties文件中配置的server.loader和shared.loader是否设置
如果设置,读取 tomcat下对应的server和shared这两个目录的类库。
server和shared是对应tomcat目录下的两个目录,默认的Tomcat下这两个属性是没有配置值的。
设置方法:

server.loader=${catalina.base}/server/classes,${catalina.base}/server/lib/*.jar
shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar

同时需要在tomcat目录下创建 server和shared目录结构并将公用的、应用类放到里面。
Bootstrap—>System—>/WEB-INF/classes—> /WEB-INF/lib/*.jar—> Common—>Server—>Shared

3、忽略扫描和需要扫描类设置

配置文件中默认的一些类tomcat已经设置。
如果有jar包冲突的可以这个中添加忽略
tomcat.util.scan.DefaultJarScanner.jarsToSkip
如果有jar包需要扫描可以在中添加
tomcat.util.scan.StandardJarScanFilter.jarsToScan
官方文档:
The Jar Scanner Component
The Jar Scan Filter Component

4、字符缓存设置

根据需要设置字符的缓存策略。
默认设置

 tomcat.util.buf.StringCache.byte.enabled=true 
#tomcat.util.buf.StringCache.char.enabled=true
#tomcat.util.buf.StringCache.trainThreshold=500000
#tomcat.util.buf.StringCache.cacheSize=5000

5、小结

Tomcat可以通过catalina.properties的server和shared设置,为webapp提供公用类库。
使一些公用的、不需要与webapp放在一起的设置信息单独保存,在更新webapp的war的时候无需更改webapp的设置。
Tomcat 遵循的规范如下:

  • EL 2.2 API.
  • JSP 2.2 API.
  • Servlet 3.0 API

二、Tomcat启动抛出异常java.lang.IllegalStateException:…too low setting for -Xss…

具体异常信息:

...
Caused by: java.lang.IllegalStateException: 
Unable to complete the scan for annotations for web application [/xxx-xxx] due to a StackOverflowError. 
Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies. 
The class hierarchy being processed was [org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector]
                at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2186)
                ...

根据其中的异常信息是线程栈空间被耗尽,需要调整Xss参数,
线程栈的默认大小依赖于操作系统、JVM 版本和供应商,
Sparc 64-bit JVM默认为1024 kb。
但真正的问题不是出在这里,继续查看错误信息:[org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector],这个是重点,因为tomcat启动会去扫描jar包,所以ASN1EncodableVector和DEREncodableVector的bcprov-*. jar包下产生了循环继承,所以形成死循环,造成内存溢出,所以问题就出在了jar版本冲突上
这个类出现在bcprov-*.jar(bcprov-jdk15on-1.5.3.jar或其他版本)这个jar包中。
处理方法1
在tomcat的conf目录里面catalina.properties的文件,
在tomcat.util.scan.DefaultJarScanner.jarsToSkip中添加bcprov-*.jar的过滤就可以解决了,*代表版本。
处理方法2
改为同一版本,例如都使用bcprov-jdk15on-1.5.3.jar或其他版本

三、catalina.home与 catalina.base区别

Tomcat目录结构如下:
bin (运行脚本)、conf (配置文件)、 lib (核心库文件) 、logs (日志目录)、temp (临时目录)、
webapps (自动装载的应用程序的目录)、work (JVM临时文件目录[java.io.tmpdir])
其中只有 bin 和 lib 目录被多个tomcat示例公用,其它目录conf、logs、temp、webapps和work 每个Tomcat实例必须拥有其自己独立的备份。
catalina.home和catalina.base的用途:
catalina.home(安装目录):指向公用信息的位置,就是bin和lib的父目录。
catalina.base(工作目录):指向每个Tomcat目录私有信息的位置,就是conf、logs、temp、webapps和work的父目录。
简单的说,CATALINA_HOME是Tomcat的安装目录,CATALINA_BASE是Tomcat的工作目录。如果我们想要运行Tomcat的 多个实例,但是不想安装多个Tomcat软件副本。那么我们可以配置多个工作 目录,每个运行实例独占一个工作目录,但是共享同一个安装目录。
Tomcat每个运行实例需要使用自己的conf、logs、temp、webapps、work和shared目录,因此CATALINA_BASE就 指向这些目录。 而其他目录主要包括了Tomcat的二进制文件和脚本,CATALINA_HOME就指向这些目录。
如果我们希望再运行另一个Tomcat实例,那么我们可以建立一个目录,把conf、logs、temp、webapps、work和shared拷贝 到该目录下,然后让CATALINA_BASE指向该目录即可。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值