APP CLASS Loader
Author: robbin (MSN: robbin_fan AT hotmail DOT com)
Copyright Notice: This article is strictly forbidden, if there is a reprint request, please contact the author.
Java itself is a very simple, very delicate language, so the principle behind Java is also very simple, and it is two points:
1, JVM memory management
Understand this, all and object-related issues can solve
2, JVM Class Loader
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, inherited levels different from App Server, a web app class loader:
Its Load Class ranges the library files under web-inf / lib and the Class files 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.