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

问题描述

我在应用服务器上运行多个网络应用,每个网络应用 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 应用程序中的线程之间同步,但不与不同 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 文件(以及引导类路径中的其他文件),然后查看由以下文件指定的目录和 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/web 应用程序的类
  4. /WEB-INF/lib/*.webapp的jar
  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 容器为每个 Web 应用程序都有一个类加载器,这些类加载器委托给管理公共类的其他类加载器.实际上,这意味着某些类只会为整个容器加载一次(例如 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 可以配置为允许单个 web 应用程序热加载".这需要停止一个 web 应用程序,为其创建一个新的类加载器,然后重新启动它.

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.

跟进

那么……同步静态方法不会保护对类已多次加载的共享资源的访问?

这取决于细节,但可能不会.(或者换一种方式来看,如果一个类实际上被加载了多次,那么该类的每个加载"的static方法将访问不同的集合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.)

如果您真的希望单个应用程序类实例由同一容器中的多个 web 应用程序共享,最简单的方法是将该类放入 $CATALINA_HOME/lib 或等效项中.但是你也应该问问自己这是否是好的系统设计.考虑组合 web 应用程序,或使用请求转发等代替共享数据结构.单例模式在 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.

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

09-12 07:56