具有多个应用程序的Tomcat上的类加载器行为 [英] Classloader behaviour on Tomcat with multiple applications

查看:100
本文介绍了具有多个应用程序的Tomcat上的类加载器行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Tomcat 5.5服务器上,我在系统类路径中放了一个类(并修改catalina.bat来选择它),或者如果我将类放在共享的lib目录中。现在,如果我有两个不同的应用程序使用相同的类,它们的WEB-INF lib / classes目录中没有该类,则它们使用该类的相同实例。我理解一个类加载器将委托给它的父类加载器的概念,如果它找不到它就找到它,所以在这种情况下,由于该类不存在于WEB-INF / classes或WEB-INF / lib中WebAppX类加载器将分别尝试共享,公共和系统类加载器。

On a Tomcat 5.5 server, I put a class in the system classpath (and modify catalina.bat to pick it), or if I put class in the shared lib directory. Now if I have two different applications using the same class which do not have the class in their WEB-INF lib/classes directories, they use the same instance of the class. I understand the concept that a classloader will delegate to it's parent classloader for finding a class if it can't find it, so in this case, since the class is not present in the WEB-INF/classes or WEB-INF/lib the WebAppX classloader will try the shared, common and system classloader respectively.

然而,这对我来说似乎很奇怪,两个不同的应用程序可以使用此方法共享上下文。有人能帮助我理解为什么会这样。例如在下面的代码中,两个servlet分别部署在单独的战争中,而CommonCounter是共享的,他们可以读取另一个增加的计数器值。

However this somehow seems weird to me that two different applications can share a context using this method. Could someone help me understand why this is so. e.g. in below code the two servlets are each deployed in separate wars while CommonCounter is shared, and they can read the counter values incremented by the other.

编辑
对我而言,两个独立的应用程序可以以这种方式共享上下文。实际上,如果它们具有相同的类实例,它们甚至可以在两个不同的应用程序中实现多线程/同步,这看起来非常违反直觉。

package com.test;
public class CommonCounter {

    public static int servlet1;
    public static int servlet2;
}




public class Servlet1 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        CommonCounter.servlet1++;
        System.out.println("Other one had "+CommonCounter.servlet2+" hits");
    }   
}



public class Servlet2 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        CommonCounter.servlet2++;
        System.out.println("Other one had "+CommonCounter.servlet1+" hits");
    }   
}


推荐答案

As评论说,你已经正确地解释了为什么你观察你观察到的行为。

As comments say, you've correctly explained why you observe the behavior you observe.

关键是ClassLoader的结构。一个JVM中的两个ClassLoader完全可以加载一个类,因此包含静态字段的独立,独立副本。 static为ClassLoader而不是JVM创建了全局。我想,Tomcat无法容纳带有共享库的容器级ClassLoader,并以某种方式强制每个应用程序ClassLoader分别加载共享库。

The key is how ClassLoaders are structured. It's entirely possible for two ClassLoaders within one JVM to each load a class and therefore contains separate, independent copies of the static fields. "static" makes something 'global' to a ClassLoader, not a JVM. Tomcat, I suppose, could not hold a container-level ClassLoader with shared libraries, and somehow force each app ClassLoader to load shared libraries separately.

但对于其他常见的类,如J2EE API和实现,这会有点浪费。原则上,类不应该依赖于这个ClassLoader结构。

But that'd be a bit wasteful for other common classes like J2EE APIs and implementation. And in principle, classes shouldn't depend on this ClassLoader structure anyway.

这就是为什么你不应该将应用程序依赖项放在Tomcat的共享库文件夹中。这就是'解决方案'。它将您的应用程序与容器的特定设置和部署联系起来,这违反了J2EE Web应用程序的原则。只需在WEB-INF / lib中为每个应用程序放置依赖项副本。

This is why you should not put application dependencies in Tomcat's shared library folders. That is the 'solution'. It ties your application to the container's specific setup and deployment, which is against the principle of J2EE web apps. Just put copies of dependencies in WEB-INF/lib for each application.

您观察到的行为是不这样做的另一个原因:应用程序之间的隔离程度较低。它并没有让我觉得反直觉的行为,但我想这只是因为我已经习惯了Tomcat如何运作并思考这些事情。

The behavior you observe is another reason not to do this: apps become less isolated from one another. It doesn't strike me as counter-intuitive behavior, but that's I suppose just because I am used to how Tomcat works and thinks about these things.

这篇关于具有多个应用程序的Tomcat上的类加载器行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆