Java 提供模块而不发布时的Tomcat类加载顺序
我正在将tomcat与eclipse一起使用 根据tomcat的文档:Java 提供模块而不发布时的Tomcat类加载顺序,java,eclipse,tomcat,Java,Eclipse,Tomcat,我正在将tomcat与eclipse一起使用 根据tomcat的文档: 从web应用程序的角度来看,类或资源加载按以下顺序查看存储库: JVM系统类加载器类的引导类(描述 (上图) /WEB应用程序的WEB-INF/类 /WEB应用程序的WEB-INF/lib/*.jar 通用类加载器类(如上所述) 因此,当加载类时,tomcat将在WEB-INF/lib之前查找WEB-INF/classes。 我们可以在WEB-INF/lib中覆盖jar文件中的某些类,tomcat将获取被覆盖的类 但是现
从web应用程序的角度来看,类或资源加载按以下顺序查看存储库:
- JVM系统类加载器类的引导类(描述 (上图)
- /WEB应用程序的WEB-INF/类
- /WEB应用程序的WEB-INF/lib/*.jar
- 通用类加载器类(如上所述)
编辑:
在这个文件夹f:\eclipse\u projects\.metadata.plugins\org.eclipse.wst.server.core\tmp0\conf 存在一个server.xml文件,其中包含以下内容:
<Resources className="org.eclipse.jst.server.tomcat.loader.WtpDirContext"
extraResourcePaths=""
virtualClasspath="F:\eclipse_projects\ALS7C3\bin"/>
<Loader className="org.eclipse.jst.server.tomcat.loader.WtpWebappLoader"
useSystemClassLoaderAsParent="false"
virtualClasspath="F:\eclipse_projects\ALS7C3\bin"/>
似乎在选中“不发布服务模块”选项的情况下运行tomcat时,eclipse将使用自己的加载程序。该加载程序包含在jar文件中,当您在eclipse中启动tomcat时,该文件将复制到f:\eclipse\u projects\.metadata.plugins\org.eclipse.wst.server.core\tmp0\lib**。
以下是**org.eclipse.jst.server.tomcat.loader.WtpDirContext的部分源代码:
public Object lookup(String name) throws NamingException {
if (name.startsWith("/WEB-INF/") && name.endsWith(".tld")) {
String tldName = name.substring(name.lastIndexOf("/") + 1);
if (virtualMappings != null && virtualMappings.containsKey(tldName)) {
return new FileResource(virtualMappings.get(tldName));
}
} else if (tagfileMappings != null && name.startsWith("/META-INF/tags")
&& (name.endsWith(".tag") || name.endsWith(".tagx"))) {
// already loaded tag file
return new FileResource(tagfileMappings.get(name));
}
Object retSuper;
NamingException superEx;
try {
retSuper = super.lookup(name);
return retSuper;
} catch (NamingException ex) {
retSuper = null;
superEx = ex;
}
if (mappedResourcePaths != null) {
// Perform lookup using the extra resource paths
for (Map.Entry<String, List<String>> mapping : mappedResourcePaths.entrySet()) {
String path = mapping.getKey();
List<String> dirList = mapping.getValue();
if (name.equals(path)) {
for (String resourcesDir : dirList) {
File f = new File(resourcesDir);
if (f.exists() && f.canRead()) {
if (f.isFile()) {
return new FileResource(f);
}
else {
// TODO Handle directory
}
}
}
}
path += "/";
if (name.startsWith(path)) {
String res = name.substring(path.length());
for (String resourcesDir : dirList) {
File f = new File (resourcesDir + "/" + res);
if (f.exists() && f.canRead()) {
if (f.isFile()) {
return new FileResource(f);
}
else {
// TODO Handle directory
}
}
}
}
}
}
throw superEx;
}
公共对象查找(字符串名称)引发NamingException{
if(name.startsWith(“/WEB-INF/”)&&name.endsWith(“.tld”)){
字符串tldName=name.substring(name.lastIndexOf(“/”)+1);
if(virtualappings!=null&&virtualappings.containsKey(tldName)){
返回新的文件资源(virtualappings.get(tldName));
}
}else if(tagfileMappings!=null&&name.startsWith(“/META-INF/tags”)
&&(name.endsWith(“.tag”)| name.endsWith(“.tagx”)){
//已加载标记文件
返回新的FileResource(tagfileMappings.get(name));
}
对象检索;
NamingException superEx;
试一试{
retSuper=super.lookup(名称);
返回超级;
}捕获(NamingException-ex){
retSuper=null;
superEx=ex;
}
if(mappedResourcePath!=null){
//使用额外的资源路径执行查找
对于(Map.Entry映射:MappedResourcePath.entrySet()){
字符串路径=mapping.getKey();
List dirList=mapping.getValue();
if(name.equals(path)){
for(字符串资源dir:dirList){
文件f=新文件(resourcesDir);
如果(f.exists()&&f.canRead()){
if(f.isFile()){
返回新的文件资源(f);
}
否则{
//TODO句柄目录
}
}
}
}
路径+=“/”;
if(name.startsWith(path)){
String res=name.substring(path.length());
for(字符串资源dir:dirList){
文件f=新文件(resourcesDir+“/”+res);
如果(f.exists()&&f.canRead()){
if(f.isFile()){
返回新的文件资源(f);
}
否则{
//TODO句柄目录
}
}
}
}
}
}
扔超级;
}
看起来,如果它将首先处理jsp标记库,然后调用super.lookup,如果在super.lookup中找不到,它将尝试加载virtualClasspath中的资源,“F:\eclipse\u projects\ALS7C3\bin”在我的示例中,在为模块提供服务而不发布时,eclipse将在这里输出类文件
所以,我想,如果我可以覆盖org.eclipse.jst.server.tomcat.loader.WtpDirContext的lookup方法,我可以得到我想要的,但是这个jar文件包含在org.eclipse.jst.server.tomcat.core.jar中,它们都是经过签名的
我不知道如何覆盖这样一个jar文件
任何人都可以提供帮助吗?以下是我在eclipse/tomcat中使用热部署的方法:
如果您更改了配置文件,可以尝试使用新的tomcat。覆盖这些类的解决方案是在workspace项目中修改
服务器\??-config\catalina.properties
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
属性common.loader
是Tomcat common ClassLoader的类路径设置。Webtools插件将org.eclipse.jst.server.tomcat.core.jar复制到
${catalina.base}/lib
。
您可以覆盖这些类并用新路径替换
${catalina.base}/lib、${catalina.base}/lib/*.jar
为什么要重写类?程序不应该依赖于类加载的行为。实现不同。@Keerthi为了方便在deve