当同一个类存在于同一服务器上的不同应用程序中时,类加载如何工作? [英] How does class loading work when the same class exists in different applications on the same server?

查看:145
本文介绍了当同一个类存在于同一服务器上的不同应用程序中时,类加载如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用服务器上运行多个网络应用,每个网络应用WAR文件都包含相同jar文件的副本。

I have multiple web-apps running on an app server and each web-app WAR file contains a copy of the same jar file.

这是否意味着该jar文件中的类将在JVM中多次加载,对于它存在的每个WAR文件一次?接下来,如果我在这样的类中有一个静态同步方法,它是否只在它存在的web-app中的线程之间同步,而不是在不同jar文件中的同一个类中的同一方法同步WAR文件? (希望这个问题有道理,必要时会澄清)。

Does this mean that a class in that jar file will be loaded multiple times in the JVM, once for each WAR file it exists in? Following on from that, if I have a static synchronized method in such a class, is it only synchronized among threads within the web-app it exists in but not synchronized against the same method in the same class in a different jar file in a different WAR file? (Hope the question makes sense, will clarify if necessary).

如果是这种情况,我认为最好的解决方案是从每个WAR文件中删除jar文件并部署它到服务器上的共享类路径文件夹?

If this is the case I presume the best solution is to remove the jar file from each WAR file and deploy it to a shared classpath folder on the server?

推荐答案

Java类加载器通常通过在一个或多个地方查找类来工作一个固定的序列。例如,从命令行运行应用程序时加载应用程序的类加载器首先在 rt.jar 文件(以及bootclasspath中的其他文件)中查找,然后在类路径指定的目录和JAR文件。

A Java classloader typically works by looking for classes in one or more places in a fixed sequence. For instance, the classloader that loads your application when you run it from the command line looks first in the rt.jar file (and others on the bootclasspath), and then in the directories and JAR files specified by your classpath.

webapp类加载原则上类似,但在实践中有点复杂。对于特定的webapp,webapp的类加载器按以下顺序查找类。例如,Tomcat 6按以下顺序查找类:

A webapp classloading is similar in principle, but a bit more complicated in practice. For a particular webapp, a webapp's classloader looks for classes in the following order. For example Tomcat 6 looks for classes in this order:


  1. JVM的引导类

  2. 系统类加载器类(描述此处

  3. / WEB-INF / webapp的类

  4. / WEB-INF / lib / * .abar of webapp

  5. $ CATALINA_HOME / lib

  6. $ CATALINA_HOME / lib / * .jar

  1. Bootstrap classes of your JVM
  2. System class loader classes (described here)
  3. /WEB-INF/classes of the webapp
  4. /WEB-INF/lib/*.jar of the webapp
  5. $CATALINA_HOME/lib
  6. $CATALINA_HOME/lib/*.jar

当然,一旦类加载器找到了它正在寻找的类,就不会再看了。因此,顺序中稍后具有相同名称的类将不会被加载。

Of course, once the classloader has found the class it is looking for, it looks no further. So classes with the same name later in the order won't get loaded.

复杂的是Web容器为每个webapp都有一个类加载器,这些类加载器委托给管理公共类的其他类加载器。实际上,这意味着某些类只会为整个容器加载一次(例如1.和2.),而其他类可能会被不同的类加载器多次加载。

The complication is that the web container has one classloader for each webapp, and these classloaders delegate to other classloaders that manage the common classes. In practice, this means that some classes will only ever be loaded once for the entire container (e.g. 1. and 2.) and others may get loaded multiple times by different classloaders.

(当一个类被多次加载时,它会产生不同的 Class 对象和不同的类静态。就JVM而言,类的版本是不同的类型,你不能从一个版本转换为另一个版本。)

(When a class is loaded more than once, it results in distinct Class objects and distinct class statics. The versions of the class are different types as far as the JVM is concerned and you cannot typecast from one version to the other.)

最后,Tomcat可以配置为允许个人webapps是热门。这需要停止一个webapp,为它创建一个新的类加载器,然后重新启动它。

Finally, Tomcat can be configure to allow individual webapps to be "hot loaded". This entails stopping a webapp, creating a new classloader for it, and restarting it.

FOLLOWUP


所以...同步静态方法不会保护对多次加载类的共享资源的访问?

So ... synchronizing a static method will not protect access to a shared resource where the class has been loaded multiple times?

这取决于细节,但可能不会。 (或者看看是否有另一种方式,如果一个类实际已多次加载,那么每个加载的静态方法class将访问一组不同的 static 字段。)

It depends on the details, but it probably won't. (Or to look at if another way, if a class has actually been loaded multiple times, then a static method of each "load" of the class will access a different set of static fields.)

如果你真的想要一个单例应用程序类实例由同一容器中的多个webapp共享,如果将类放入 $ CATALINA_HOME / lib 或等效项,则最简单。但你也应该问问自己这是不是很好的系统设计。考虑组合webapps,或使用请求转发等而不是共享数据结构。单例模式往往在webapps中很麻烦,而这种风格更是如此。

If you really want a singleton application class instance to be shared by multiple webapps in the same container, it is simplest if you put the class into $CATALINA_HOME/lib or the equivalent. But you also should ask yourself if this is good system design. Consider combining the webapps, or to using request forwarding etc instead of a shared data structure. The singleton pattern tends to be troublesome in webapps, and this flavor is even more so.

这篇关于当同一个类存在于同一服务器上的不同应用程序中时,类加载如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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