Java ClassLoader
java.lang.ClassNotFoundException
Xuefeng.Wu
明明就在这里啊!
ClassNotFoundException
When
 Class.forName()
 findSystemClass()
 loadClass()
 NoClassDefFoundError: compile time
Run time
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Key JVM Components
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Default class loader
sun.misc.Launcher$ExtClassLoader
sun.misc.Launcher$AppClassLoader
CLASSPATH environment variable,
-classpath or -cp command line option,
Class-Path attribute of Manifest file inside JAR
Tools: jps, jinfo
ClassLoader works
MyClassLoader
DEMO:MyClassLoader
Three principles
 Delegation principles
 Visibility Principle
 Uniqueness Principle
Child ClassLoader can see class loaded by Parent ClassLoad
but vice-versa is not true.
According to this principle a class loaded by Parent
should not be loaded by Child ClassLoader again.
DEMO:demo. ExplicitlyLoadClassByExtension
Is it easy?
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Eclipse-OSGi
OSGi Class Loader
Demo
 Run Plugin_ListAll_Normal
 Jinfo
Demo
 Debug Plugin_ListAll_Normal
Demo
 Debug HelloWorld in remote project
Issue & fix
 Try to find csdm/client/StartUp.class is exist.
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Maven
 System Classloader: Classworlds classloading
framework

 Core Classloader:
 Plugin Classloaders
 Custom Classloaders
boot the classloader graph: ${maven.home}/boot
down the graph contains the core requirements of
Maven:
${maven.home}/lib
each plugin has its own classloader
that is a child of Maven's core classloader
plugins/plugin
Demo: jetty plugin
 mvn jetty:run @ remote
a limit on how long you can make your
command line
 Isolaed Classloader: your classpath
isn't really correct. try to escape the confines of an
isolated classloader.
 Manifest-Only JAR:your app may be confused if it
finds only our booter.jar there!
Demo: surefire plugin
 mvn -Dtest=* test
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Spring
String bean = readerBeanClass()
Class clz = classLoader.loadClass(bean)
clz .newInstance()
Spring ResourceLoader
 ClassPathXmlApplicationContext
 DefaultResourceLoader.
 setClassLoader(ClassLoader classLoader)
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader();
reader.setBeanClassLoader([Class LoaderB here!]);
DefaultListableBeanFactory factory = new DefaultListableBeanFactory(reader);
reader.loadBeanDefinitions([xml resource here!]);
Default: thread context class loader: Thread.currentThread().getContextClassLoader()
Issue & fix
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Agenda
 JVM class and execute
 Core ClassLoader and MyClassLoader
 Tools: jps, jinfo
 Eclipse-OSGi
 Maven
 Spring
 Dynamic Classes and Method (Reflect, Java 8)
 Other: MethodNotDef
Other: MethodNotDef
 Jar version
Class.forName(“...HelloWorld")
public class com.carestreamhealth.pas.RemoteWS.utils.HelloWorld {
public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.ClassNotFoundException;
Code:
0: ldc #19 // String
com.carestreamhealth.pas.RemoteWS.utils.HelloWorld
2: invokestatic #21 // Method
java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
5: pop
6: return
}
getClassLoader().loadClass(“..HelloWorld")
public class com.carestreamhealth.pas.RemoteWS.utils.HelloWorld {
public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.ClassNotFoundExce
ption, java.lang.InstantiationException, java.lang.IllegalAccessException;
Code:
0: ldc #1 // class
com/carestreamhealth/pas/RemoteWS/utils/HelloWorld
2: invokevirtual #23 // Method
java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
5: ldc #29 // String
com.carestreamhealth.pas.RemoteWS.utils.HelloWorld
7: invokevirtual #31 // Method
java/lang/ClassLoader.loadClass:(Ljava/lang/String;)Ljava/lang/Class;
10: pop
11: return
}
new HelloWorld
public class com.carestreamhealth.pas.RemoteWS.utils.HelloWorld {
public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class com/carestreamhealth/pas/Re
moteWS/utils/HelloWorld
3: invokespecial #16 // Method "<init>":()V
6: return
}
Call Site-VM Operation
JVM Spec: 5.3 Creation and Loading
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
Dynamic Classes and Method (Reflect, Java
8)
 invokedynamic
http://www.slideshare.net/CharlesNutter/jax-2012-invoke-dynamic-keynote
Java bytecode:
Understanding bytecode makes you a
better programmer
Example:
http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
Java Class:
http://en.wikipedia.org/wiki/Java_class_file
Java bytecodes:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
Java class loader

Java class loader

  • 1.
  • 2.
  • 3.
  • 4.
    When  Class.forName()  findSystemClass() loadClass()  NoClassDefFoundError: compile time Run time
  • 5.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 6.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 7.
  • 8.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 9.
    Default class loader sun.misc.Launcher$ExtClassLoader sun.misc.Launcher$AppClassLoader CLASSPATHenvironment variable, -classpath or -cp command line option, Class-Path attribute of Manifest file inside JAR
  • 10.
  • 11.
  • 12.
  • 13.
    Three principles  Delegationprinciples  Visibility Principle  Uniqueness Principle Child ClassLoader can see class loaded by Parent ClassLoad but vice-versa is not true. According to this principle a class loaded by Parent should not be loaded by Child ClassLoader again. DEMO:demo. ExplicitlyLoadClassByExtension
  • 14.
  • 15.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    Demo  Debug HelloWorldin remote project
  • 21.
    Issue & fix Try to find csdm/client/StartUp.class is exist.
  • 22.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 23.
    Maven  System Classloader:Classworlds classloading framework   Core Classloader:  Plugin Classloaders  Custom Classloaders boot the classloader graph: ${maven.home}/boot down the graph contains the core requirements of Maven: ${maven.home}/lib each plugin has its own classloader that is a child of Maven's core classloader plugins/plugin
  • 24.
    Demo: jetty plugin mvn jetty:run @ remote
  • 25.
    a limit onhow long you can make your command line  Isolaed Classloader: your classpath isn't really correct. try to escape the confines of an isolated classloader.  Manifest-Only JAR:your app may be confused if it finds only our booter.jar there!
  • 26.
    Demo: surefire plugin mvn -Dtest=* test
  • 27.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 28.
    Spring String bean =readerBeanClass() Class clz = classLoader.loadClass(bean) clz .newInstance()
  • 29.
    Spring ResourceLoader  ClassPathXmlApplicationContext DefaultResourceLoader.  setClassLoader(ClassLoader classLoader) XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(); reader.setBeanClassLoader([Class LoaderB here!]); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(reader); reader.loadBeanDefinitions([xml resource here!]); Default: thread context class loader: Thread.currentThread().getContextClassLoader()
  • 30.
  • 31.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 32.
    Agenda  JVM classand execute  Core ClassLoader and MyClassLoader  Tools: jps, jinfo  Eclipse-OSGi  Maven  Spring  Dynamic Classes and Method (Reflect, Java 8)  Other: MethodNotDef
  • 33.
  • 34.
    Class.forName(“...HelloWorld") public class com.carestreamhealth.pas.RemoteWS.utils.HelloWorld{ public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.lang.ClassNotFoundException; Code: 0: ldc #19 // String com.carestreamhealth.pas.RemoteWS.utils.HelloWorld 2: invokestatic #21 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 5: pop 6: return }
  • 35.
    getClassLoader().loadClass(“..HelloWorld") public class com.carestreamhealth.pas.RemoteWS.utils.HelloWorld{ public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.lang.ClassNotFoundExce ption, java.lang.InstantiationException, java.lang.IllegalAccessException; Code: 0: ldc #1 // class com/carestreamhealth/pas/RemoteWS/utils/HelloWorld 2: invokevirtual #23 // Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader; 5: ldc #29 // String com.carestreamhealth.pas.RemoteWS.utils.HelloWorld 7: invokevirtual #31 // Method java/lang/ClassLoader.loadClass:(Ljava/lang/String;)Ljava/lang/Class; 10: pop 11: return }
  • 36.
    new HelloWorld public classcom.carestreamhealth.pas.RemoteWS.utils.HelloWorld { public com.carestreamhealth.pas.RemoteWS.utils.HelloWorld(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>": ()V 4: return public static void main(java.lang.String[]); Code: 0: new #1 // class com/carestreamhealth/pas/Re moteWS/utils/HelloWorld 3: invokespecial #16 // Method "<init>":()V 6: return }
  • 37.
  • 38.
    JVM Spec: 5.3Creation and Loading http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
  • 39.
    Dynamic Classes andMethod (Reflect, Java 8)  invokedynamic http://www.slideshare.net/CharlesNutter/jax-2012-invoke-dynamic-keynote
  • 40.
    Java bytecode: Understanding bytecodemakes you a better programmer Example: http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/ Java Class: http://en.wikipedia.org/wiki/Java_class_file Java bytecodes: http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

Editor's Notes

  • #13 package demo;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;/** * Created with IntelliJ IDEA. * User: 19002850 * Date: 13-5-20 * Time: 下午4:35 * To change this template use File | Settings | File Templates. */public class MyClassLoader extends ClassLoader { private static final int BUFFER_SIZE = 8192; protected synchronized Class loadClass(String className, boolean resolve) throws ClassNotFoundException { log(&quot;Loading class: &quot; + className + &quot;, resolve: &quot; + resolve); // 1. is this class already loaded? Class cls = findLoadedClass(className); if (cls != null) { return cls; } // 2. get class file name from class name String clsFile = className.replace(&apos;.&apos;, &apos;/&apos;) + &quot;.class&quot;; // 3. get bytes for class byte[] classBytes = null; try {InputStream in = getResourceAsStream(clsFile); byte[] buffer = new byte[BUFFER_SIZE];ByteArrayOutputStream out = new ByteArrayOutputStream();int n = -1; while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {out.write(buffer, 0, n); }classBytes = out.toByteArray(); } catch (IOException e) { log(&quot;ERROR loading class file: &quot; + e); } if (classBytes == null) { throw new ClassNotFoundException(&quot;Cannot load class: &quot; + className); } // 4. turn the byte array into a Class try {cls = defineClass(className, classBytes, 0, classBytes.length); if (resolve) {resolveClass(cls); } } catch (SecurityException e) { // loading core java classes such as java.lang.String // is prohibited, throws java.lang.SecurityException. // delegate to parent if not allowed to load classcls = super.loadClass(className, resolve); } return cls; } private static void log(String s) {System.out.println(s); }}
  • #14 package demo;import java.util.logging.Level;import java.util.logging.Logger;/** * Java program to demonstrate How ClassLoader works in Java, * in particular about visibility principle of ClassLoader. * * @author Javin Paul */public class ExplicitlyLoadClassByExtension { public static void main(String args[]) { try { //printing ClassLoader of this classSystem.out.println(&quot;-------------&quot;);System.out.println(&quot;ExplicitlyLoadClassByExtension.getClass().getClassLoader() : &quot; + ExplicitlyLoadClassByExtension.class.getClassLoader()); //trying to explicitly load this class again using Extension class loaderSystem.out.println(&quot;ExplicitlyLoadClassByExtension.getClass().getClassLoader().getParent() : &quot; + ExplicitlyLoadClassByExtension.class.getClassLoader().getParent());Class.forName(&quot;demo.ExplicitlyLoadClassByExtension&quot;, true , ExplicitlyLoadClassByExtension.class.getClassLoader().getParent()); } catch (ClassNotFoundException ex) {Logger.getLogger(ExplicitlyLoadClassByExtension.class.getName()).log(Level.SEVERE, null, ex); } }}