Updated (09/12/2014): The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly specify that certain packages should always be loaded from the application, rather than being loaded by the system classloader. To understand the default class loader structure in WLS 12.1.3, read here.System (D) | FilteringClassLoader (filterList := x.y.*) (C) | App (B) | Web (A) |
Running any application on a JVM or an application server (e.g., WebLogic Server), the main question a designer faces is:
- Which class is getting loaded from which source
In this article, we will look at two classloader hierarchies:
- Java Classloader Hierarchy
- Applied to regular Java applications running from command line
- Application Classloader Hierarchy
- We will look at one such hierarchy implemented by WebLogic's Classloading Framework
Three Principles of Java Classloader Operation
Classloader hierarchy plays an important role when locating and loading classes into memory. There are only three basic principles to understand:- Delegation Principle:
- If a class is not loaded already, the classloaders delegate the request to load that class to their parent classloaders (see also [11]).
- In other words, a child classloader loads a class only if its parent fails to load it
- See customization section for an exception that is supported by WebLogic Server to override this default behavior by setting the prefer-web-inf-classes element to true in the weblogic.xml descriptor file.
- If a class is not loaded already, the classloaders delegate the request to load that class to their parent classloaders (see also [11]).
- Visibility Principle:
- Classes loaded by parent classloaders are visible to child classloaders but not vice versa
- A classloader cannot access any classes loaded by a sibling classloader.
- Uniqueness Principle:
- When a classloader loads a class, the child classloaders in the hierarchy will never reload that class.
Java Classloader Hierarchy
Regular Java applications running from command line involve three classloaders:
- Bootstrap classloader (root)
- Created by the JVM for loading its internal classes and the java.* packages (i.e., core Java libraries under
/lib directory) included within the JVM - Written in native code
- Endorsed-standards override mechanism allows a jar file containing a newer implementation of an endorsed standard or standalone API be installed into a run-time image by placing it in one of the directories named by the system property (i.e., java.endorsed.dirs), or by placing it in the default lib/endorsed directory if the system property is not defined.
- Such jar files are prepended to the JVM's bootstrap class path at run time, thereby overriding any definitions stored in the run-time system itself.
- Created by the JVM for loading its internal classes and the java.* packages (i.e., core Java libraries under
- Extensions classloader (child of bootstrap classloader)
- Loads any JARs placed in the extensions directory (
/lib/ext or any other directory specified by the java.ext.dirs system property) of the JDK - Implemented by the sun.misc.Launcher$ExtClassLoader class
- Extension classes cannot override the JDK classes loaded by the bootstrap loader but they are loaded in preference to classes defined by the system loader and its descendants.
- Loads any JARs placed in the extensions directory (
- System classloader (child of extensions classloader)
- Loads code found on java.class.path, which maps to the system CLASSPATH variable.
- Implemented by the sun.misc.Launcher$AppClassLoader class
- Any custom classloader created by an application, including WebLogic's classloaders, are all descendants of this system classpath classloader
- Can be programmatically accessible as ClassLoader.getSystemClassLoader()
- Is also known as application class loader
WebLogic's Classloading Framework
WebLogic's standard classloading framework needs to achieve two main goals:- Maintain application independence
- Classes used by application A must never come in conflict with any classes used by application B
- Redeploying application A must have no effect on classes used by application B
- Hot-deploy or hot-redeploy
- Within an application, it must allow you to redeploy web applications without having to redeploy the EJBs
- It is more common to change JSP files and servlets than to change the EJB tier. With proper design, a separate classloader can be created for each servlet and JSP page. This allows you to reload individual servlets and JSPs easily, without the need for redeploying the web application or affecting any of the EJBs.
Java classloaders do not have any standard mechanism to undeploy or unload a set of classes, nor can they load new versions of classes. To achieve the second goal, each application in WebLogic Server has a hierarchy of classloaders (see the Figure below) that are offspring of the system classloader. These hierarchies allow applications or parts of applications to be individually reloaded without affecting the rest of the system. To find out more details on this, read WebLogic Server Application Classloading.
Customization
Even with good support from either Java classloading framework or WebLogic's application classloading framework, it often comes times that you need to have better control over which modules are reloadable, which classes are visible between modules, etc.There are multiple solutions to your customization needs:
- You can configure a web application classloader so that it doesn't use the default parent delegation scheme by setting the prefer-web-inf-classes element to true in the weblogic.xml descriptor file. See details here.
- The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly specify that certain packages should always be loaded from the application, rather than being loaded by the system classloader. See details here.
- You can create custom classloader hierarchies for an application allowing for better control over class visibility and reloadability. You achieve this by defining a classloader-structure element in the weblogic-application.xml deployment descriptor file. See details here.
Wrap-up
More often than not, you want class definitions (which are stable) shared across applications. To facilitate sharing, you would place them at higher level of the classloading hierarchy (for example, getting loaded at system classloader instead of at application classloader).If it is common to change some modules, a separate classloader can be created for them and place them at the tip of the classloading tree. This allows you to reload individual modules easily, without the need for redeploying their parent applications.
When loading a resource dynamically, you can choose from at least three classloaders: the system classloader, the current classloader, and the current thread context classloader. Which classloader is the right one? You can read [8] to find the answer.
References
- Classloader
- JRebel
- Understanding WebLogic Server Application Classloading
- WebLogic: The Definitive Guide
- WebLogic Server 11g for ADF/Forms Developers
- Classloaders and J2EE (good)
- 3 ways to resolve NoClassDefFoundError in Java
- Find a way out of the ClassLoader maze
- Professional Oracle WebLogic Server by Robert Patrick, Gregory Nyberg, and Philip Aston
- VM Class Loading
- Using 3rd party JDBC Jar Files
- The general precedence of jar files in the classpath is the following:
- system classpath >> DOMAIN_HOME/lib >> APP-INF/lib >> WEB-INF/lib
- Note that the above doesn't consider library-ref or prefer-application-packages (see article for details).
- WebLogic class loader - analysis and configuration options (good)
- JEP 220: Modular Run-Time Images
- In JDK 9, both endorsed-standards override mechanism and extension mechanism will be removed.
No comments:
Post a Comment