ClassLoader of Java

xiaoxiao2021-03-06  114

Understand this point, all and Java-related configuration issues, including all kinds of App Server configuration, application issuance issues can be solved

APP CLASS Loader

| ----- EJB CLASS Loader

| ----- Web App Class Loader

If configured at the App Class Loader level, it is global visible. If you pack it in EJB, then you will not affect the Web Application, and vice versa, if you place hibernate under Web-INF, you will not affect EJB. Putting in EJB Class Loader or placed in the Web App Class Loader is mainly valid within the local area without affecting other applications.

Imagine if you configure multiple virtual domains on a WebLogic, you use www.bruce.com domain names, develop your website, I use www.fankai.com to develop my website, then I don't want our hibernate to interfere with each other, so You can configure Hibernate at the EJB Class Loader level.

Further explain the problem of EJB Class Loader:

First emphasize, Hibernate and EJB, and App Server does not have compatibility issues, they are not related, just like JDBC, I believe that no one will think that JDBC and EJB are not compatible, Hibernate is also the same, it only and JDBC Drivers, and databases have compatibility issues, and EJB, and APP Server is completely unwinding. Anyone who believes that Hibernate and EJB is not compatible, is actually because of the unhappy family of EJB, pushing responsibility to hibernate.

I mentioned the level of Class Loader in front, this is not repeated, in short, let's take a look at the scope of Class Loader:

(Boot strap) Class Loader:

Load jre / lib / rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.jar

EXT CLASS Loader:

Load jre / lib / ext directory, the class under the Load JRE / CLASSES directory

APP Class Loader:

Load classpath variable specified path under the path

The above LOAD path is written in the C source code of JVM, can not change, please see Wang Sen's "Java Deep Adventures"

On a specific App Server, Class Loader will continue to inherit down, and the inherited level will vary depending on the APP Server, but it will not change.

EJB Class Loader:

Inherited from App Class Loader, the inheritance level is different according to App Server, and an EJB Class Loader has a range of Load Class only within JAR or EAR.

Web App Class Loader:

Inherited from App Class Loader, inheritance level is different according to App Server, a Web App Class Loader: Its LOAD Class's library file and the Class file under the web-inf / class directory.

Web App Class Loader is very understanding, everyone is using a lot, a web application on the app server will create an instance of a web app class loader to be responsible for the Load Class, so if you want Hibernate to take effect only within this web application, It is fine to put it on Web-INF / LIB. If you put Hibernate under the path specified by the classpath variable, you also put a copy in web-inf / lib, then the web app class loader is limited by the LOAD range, which will first find the Web-INF / LIB. Hibernate, initialize Hibernate according to its configuration.

If you put Hibernate under the path specified by the classpath variable, you have not put anything in web-inf / lib, then the web app class loader is not found because of the limit of the LOAD, so it will take load hibernate. The responsibility is handed over to the previous level of Class Loader so until App Class Loader, it finds Hibernate, and initializes Hibernate according to its configuration.

EJB Class Loader is slightly complicated, not so easy to understand. APP Server creates an instance of EJB Class Loader for each EJB package file, for example:

(Hello Robbin). JAR

(Hello Bruce). JAR

When you post these two JARs on the App Server, you will create an instance of two EJB Class Loader, and go to LOAD two EJB packets, such as:

CLEJB_ROBBIN is LOAD (Hello Robbin). JAR

Clejb_bruce is Load (Hello Bruce). JAR

Then Clejb_Robbin's LOAD range is limited to Hellorobbin.jar, which does not do any files outside Hellobbin.jar, of course, it is also not Hellobruce.jar.

Speaking here, I believe that everyone should have understood why the EJB specification does not allow EJBs to have IO operations? Because EJB Class Loader can't find files outside the JAR package at all! ! !

If you want to achieve Hellorobbin.jar and Hellobruce.jar, what should I do? They use different EJB Class Loader, which cannot be found to each other. The solution is to use EAR.

Now, Hellorobbin.jar and Hellobruce.jar use Hibernate to see how to pack and release:

Helloejb.ear

| ------ ((Hello Robbin). JAR

| ------ ((Hello Bruce). JAR

| ------ Hibernate2.jar

| ------ Pojo.jar (Define all of the long-lasting objects and HBM files)

| ------ CGLIB-Asm.jar

| ------ Commons-BeanUtils.jar

| ------ Commons-Collections.jar

| ------ Commons-Lang.jar

| ------ Commons-logging.jar

| ------ Dom4j.jar

| ------ odmg.jar

| ------ Log4j.jar

| ------ JCS.jar

| ------ Hibernate.properties

| ------ Log4j.properties | ------ Cache.ccf

| ------ Meta-INF / Application.xml (J2EE specification requirement, what kind of EJB included in the definition EAR package)

In addition, in accordance with the EJB specification requirements, hellorobbin.jar and hellobruce.jar must point out the name of the class library other than the JAR package, which requires definition in the manifest file of the JAR package:

(Hello Robbin). JAR

| ------ Meta-INF / Manifest.mf

MANIFEST.MF must include the following line:

Class-path: log4j.jar hibernate2.jar cglib-asm.jar Commons-beanutils.jar Commons-Collections.jar Commons-lang.jar

Commons-logging.jar Dom4j.jar jcs.jar odmg.jar jcs.jar Pojo.jar

This is OK, after the Helloejb.ear is released on the App Server, App Server creates an EJB Class Loader instance Load EJB in the Load Ear package, and then looks out in the class-path pointed out in the manifest.mf inside the EJB jar package. Class libraries outside the corresponding JAR package.

So an EAR is a bit similar to a web application. The LOAD range of EJB Class Loader is also within the EAR range, which is not files outside EAR. Unless the Hibernate is defined to the path specified by the classpath, in this case, the EJB Class Loader can't find Hibernate, which can only be handed over to the Class Loader of the previous level, and finally find hibernate by app class loader for initialization.

Because EAR is like the Load Class rule, assuming that Robbin and Bruce are running their own websites on the same WebLogic, and we don't want the hibernate configuration inside our program to be chaos the other party, then we can do this:

Robbin's Website:

Robbin.ear

| -------- Robbin.war (Package Web Application)

| -------- Robbin.jar (Packaged Development EJB)

| -------- Hibernate2.jar

..........................

| -------- Meta-INF / Application.xml

Bruce's Website:

Bruce.ear

| -------- Bruce.war (Package Web Application)

| -------- Bruce.jar (put the development of EJB package)

| -------- Hibernate2.jar

..........................

| -------- Meta-INF / Application.xml

This is running on the same app server, you can do not interfere with each other.

####################################################################################

Richardluo published from Dev2Dev @ BEA

Learn from ClassLoader

1, what is ClassLoader?

The Java program is not an executable file, which is required to be loaded into the JVM. ClassLoader works is to load the class in the JVM. Moreover, Java ClassLoader is written in Java language. This means that you can create your own ClassLoaderClassLoader's basic goal is to provide services for classes. When the JVM needs to use classes, it requests this class based on the name, and then ClassLoader tries to return a class object that represents this class. Customized ClassLoader can be created by covering a different phase of this process.

2, some important methods

A) method loadclass

ClassLoader.LoadClass () is the entry point of ClassLoader. The definition of this method is as follows:

Class loadClass (String name, Boolean Resolve);

Name JVM The name of the class, such as foo or java.lang.Object.

The resolve parameter tells the method whether you need to parse classes. Class analysis should be considered before preparing to execute the class. It doesn't always need to be parsed. If JVM only needs to know if this class exists or finds the superclass of this class, then no resolution.

B) method DefineClass

The DefineClass method is the main 诀窍 of ClassLoader. This method accepts arrays consisting of original bytes and converts it to Class objects. The original array contains data that is installed from a file system or network. DefineClass manages many of the complex, mysterious and reliance on the implementation of the JVM - it analyzes the bytecode to the runtime data structure, verification effectiveness, etc. Don't worry, you don't have to write it yourself. In fact, even if you want to do this, you can't overwrite it because it has been marked into final.

C) FindsystemClass

The FindSystemClass method is loaded from the local file system. It looks for class files in the local file system. If there is, use defineClass to convert the original byte into a Class object to convert the file into classes. This is the default mechanism for JVM normally loaded when running a Java application. (ClassLoader changes in Java 2 provides details about the process of this process of Java 1.2.) For custom ClassLoader, only FindsystemClass is used after trying other methods to load classes. The reason is very simple: ClassLoader is responsible for performing special steps to carry out the laying class, not responsible for all classes. For example, even if ClassLoad is loaded from a remote Web site, you still need to load a large number of basic Java libraries on your local machine. These classes are not what we have cared, so JVM is to load them in the default manner: from the local file system. This is the use of FindsystemClass.

D) method resolveclass

As mentioned earlier, it can be loaded into classes in not completely (without parsing), or it can be completely (with parsing). When writing our own loadClass, resolveclass can be called, depending on the value of the LoadClass's Resolve parameter.

E) method FindlineedClass

FindloadedClass acts as a cache: When requesting loadClass to load classes, it calls this method to see if ClassLoad is loaded, which avoids the trouble of reloading existing classes. This method should be called first.

3, how to assemble these methods

1) Call the FindLoadedClass to see if there is a class that has been loaded. 2) If not, then use the special magical way to get the original byte.

3) If there is already original byte, call DefineClass to convert them into a Class object.

4) If there is no original byte, then call FindSystemClass to see if you get the class from the local file system.

5) If the resolve parameter is true, then resolveclass parses the Class object.

6) If there is still no class, return to ClassNotFoundException.

4. Changed between ClassLoader in Java 2

1) LoadClass's default implementation

Customized LoadClass methods typically try to load the requested class. If you write a number of classes, you will find a variable on the same, complex method. The implementation of LoadClass in Java 1.2 embeds the general method of most lookup classes, and allows you to customize it by overwriting the FindClass method, and Findclass will call LoadClass when appropriate. The advantage of this way is that you may not have to override loadClass; as long as you override FindClass, it reduces the workload.

2) New method: Findclass

LoadClass's default implementation call this new method. The use of FindClass contains all special code of your ClassLoader without having to copy other code (for example, when a special method fails, calling the system classloader).

3) New method: getSystemClassLoader

If you override FindClass or LoadClass, getSystemClassLoader enables you to access the system ClassLoader with the actual ClassLoader object (instead of fixed from FINDSYSTEMCLASS.).

4) New method: getParent

In order to delegate the class request to the parent ClassLoader, this new method allows ClassLoader to get its parent ClassLoader. This method can be used when using a special method, custom ClassLoader cannot find classes.

The parent ClassLoader is defined as a ClassLoader that creates the object of the ClassLoader included.

转载请注明原文地址:https://www.9cbs.com/read-125492.html

New Post(0)