public class BootstrapCLTest { public static void main(String[] args) { BootstrapCLTest bootstrapCLTest = new BootstrapCLTest(); bootstrapCLTest.go(); } private void go() { System.out.println("1 " + String.class.getClassLoader()); System.out.println("2 " + ClassLoader.getSystemClassLoader ()); System.out.println("3 " + this.getClass().getClassLoader()); System.out.println("4 " + Thread.currentThread().getContextClassLoader()); System.out.println("5 " + Thread.currentThread().getContextClassLoader().getParent()); System.out.println("6 " + Thread.currentThread().getContextClassLoader().getParent().getParent()); } }
you get this (parentesis are mine):
1 null (=bootstrap CL) 2 sun.misc.Launcher$AppClassLoader@1bd06bf (=application CL) 3 sun.misc.Launcher$AppClassLoader@1bd06bf (=application CL) 4 sun.misc.Launcher$AppClassLoader@1bd06bf (=application CL) 5 sun.misc.Launcher$ExtClassLoader@1061299 (=extension CL) 6 null (=bootstrap CL)
that is, in this simple case the SystemClassLoader == ApplicationClassLoader == ContextClassLoader
The first null is because the String class is loaded by the Bootstrap classloader, which is NOT represented as a ClassLoader object. The Bootstrap will then load the Extension CL, who in turn loads the Application CL.
Running a similar code in a JSP is more interesting, because here the JEE container (WebLogic in this case) will add its own CL:
System.out.println("1 " + String.class.getClassLoader()); System.out.println("2 " + ClassLoader.getSystemClassLoader ()); System.out.println("3 " + this.getClass().getClassLoader()); System.out.println("4 " + Thread.currentThread().getContextClassLoader()); System.out.println("5 " + Thread.currentThread().getContextClassLoader().getParent()); System.out.println("6 " + Thread.currentThread().getContextClassLoader().getParent().getParent()); System.out.println("7 " + Thread.currentThread().getContextClassLoader().getParent().getParent().getParent()); System.out.println("8 " + Thread.currentThread().getContextClassLoader().getParent().getParent().getParent().getParent()); System.out.println("9 " + Thread.currentThread().getContextClassLoader().getParent().getParent().getParent().getParent().getParent()); System.out.println("10 " + Thread.currentThread().getContextClassLoader().getParent().getParent().getParent().getParent().getParent().getParent());
the result is:
1 null 2 sun.misc.Launcher$AppClassLoader@fc5b01 3 weblogic.servlet.jsp.JspClassLoader@1bfdb6f finder: weblogic.utils.classloaders.CodeGenClassFinder@137e701 annotation: 4 weblogic.utils.classloaders.ChangeAwareClassLoader@1cc3dd4 finder: weblogic.utils.classloaders.CodeGenClassFinder@11f2691 annotation: _auto_generated_ear_@CLTestWeb 5 weblogic.utils.classloaders.FilteringClassLoader@1d16e3 finder: weblogic.utils.classloaders.CodeGenClassFinder@1c9a7b5 annotation: _auto_generated_ear_@CLTestWeb 6 weblogic.utils.classloaders.GenericClassLoader@ceb98d finder: weblogic.utils.classloaders.CodeGenClassFinder@217181 annotation: _auto_generated_ear_@ 7 weblogic.utils.classloaders.FilteringClassLoader@1a308be finder: weblogic.utils.classloaders.CodeGenClassFinder@92f8f0 annotation: 8 weblogic.utils.classloaders.GenericClassLoader@1865594 finder: weblogic.utils.classloaders.CodeGenClassFinder@fcfe6b annotation: 9 sun.misc.Launcher$AppClassLoader@fc5b01 10 sun.misc.Launcher$ExtClassLoader@1353d27that is, WebLogic inserts 2 layers of GenericClassLoader or ChangeAwareClassLoader plus FilteringClassLoader between the War Application and the System Classloader.
See also http://www.javamonamour.org/2015/09/playing-with-cat-and-classloaders.html
No comments:
Post a Comment