Understanding ClassLoaders

Post on 14-Apr-2017

236 views 0 download

Transcript of Understanding ClassLoaders

Understanding classloaders

What will you learn

● How classloaders work● reasons, Class and Classloader basics, semantics, Java SE/EE

delegation mechanism, ClassLoader API

● Modern classloaders● Implementation of simple classloader● Pitfalls

Reasons for ClassLoaders

● when you need to load classes from different places that just classpath

● applets● plugin systems

● when you need support for running the same library with multiple versions within the same JVM

● module systems

● necessary for implementing "hotswap" functionality● web containers & application servers

● JNI native libraries

java.lang.Class overview

● represents a type (class, interface, enum, annotation, primitive marker) in the JVM

● allocates memory in both heap and permanent generation

● is always referenced by every object instance of the class

● holds a reference to its ClassLoader● is able to load resources

java.lang.Class

● can be acquired● by class literal String.class● from object object.getClass();● through ClassLoader Class.forName(String name);

Class identity

● "every Class is uniquely identified by its fully qualified name"

● starting from Java 1.2 not true any more● because of security reasons

● JLS 4.3.4 (When reference types are the same)● both are class or interface types● both are defined by the same classloader● both have the same binary name

Class identity

● changes added higher complexity resulting in interesting new classloading options as well as new problems and pitfalls

ClassLoader overview

● instance of java.lang.ClassLoader● responsible for loading classes● knows how to transform raw data (bytes) into

instance of Class● holds a strong reference to all classes it loads● has an optional parent for delegating

ClassLoader references

● starting from Java 1.2, 4 types of references on JVM:● strong reference● soft reference● weak reference● phantom reference

ClassLoader lazy loading principle

public class Foo { public static void main(String[] args) { pack.Bar bar = new pack.Bar(); bar.coolMethod(); }}

ClassLoader lazy loading principle

public class Foo { public static void main(String[] args) { pack.Bar bar = new pack.Bar(); bar.coolMethod(); }}

ClassLoader lazy loading principle

public class Foo { public static void main(String[] args) { pack.Bar bar = new pack.Bar(); bar.coolMethod(); }}

semantically causes similar call to

Foo.class.getClassLoader().loadClass("pack.Bar");

ClassLoader delegation mechanism

● ClassLoader has a parent ClassLoader● parent ClassLoader should be consulted first

● "parent first delegation model"● the reason is to avoid loading the same class several times● every ClassLoader except OSGi and Web App ClassLoader

● exact delegation depends on ClassLoader implementation

Java SE delegation mechanism

Java SE delegation mechanism

Java SE delegation mechanism

Java SE delegation mechanism

Java EE delegation mechanism

● no Java EE specification provides a standard for class loading

● however, Java EE defines the visibility and sharing of classes between different modules

● Web Application ClassLoader is different from all others

● instead of first asking its parent, it will first look itself for the class and then ask the parent

● each WAR of an EAR gets its own ClassLoader● this allows separate namespaces for applications in the same

container

Java EE delegation mechanism

Java EE delegation mechanism

Java EE delegation mechanism

Java EE delegation mechanism

Java EE delegation mechanism

Java EE delegation mechanism

ClassLoader API

● public Class<?> loadClass(String name);

● protected Class<?> findClass(String name);

● protected final Class<?>

defineClass(String name, byte[] b, inf off, int len);

● public ClassLoader getParent();

● public URL getResource(String name);

● public InputStream getResourceAsStream(String name);

● public Enumeration<URL> getResources();

Showcase

● OpenJDK java.lang.ClassLoader source code examination

● flow of 3 dependent ClassLoaders

● simple ClassLoader implementation● ClassNotFoundException vs NoClassDefFoundError

Modern ClassLoaders

● because tree hierarchy is not enough● in terms of isolation, performance, restrictions

● modern way● each JAR has its own ClassLoader● ClassLoaders are siblings, with one central repository● each JAR explicitly decalres packages it exports and imports● repository can find relevant ClassLoaders by package● libraries packed into separate modules

● examples● OSGi, NetBeans module system, JBoss Modules

Showcase

● Multiparent ClassLoaders● solving multiple versions of the same library problem

Common problems

● too many various errors can be thrown● AbstractMethodError, IllegalAccessError,

IncompatibleClassChangeError, LinkageError, NoClassDefFoundError, NoSuchFieldError, NoSuchMethodError, OutOfMemoryError

● and exceptions too● ClassCastException, ClassNotFoundException

● possible deadlocks● most of them are caused by invalid synchronization of

classes between IDE and deployed packages

Common problems

● many of them can be tracked by using tools● URLClassLoader.getURLs();● ClassLoader.getResource(String);● javap tool● java -verbose:class

Common pitfalls + code samples

● ClassCastException● because of Java 1.2 changes in ClassLoader architecture

● OutOfMemoryError (both Heap and Permgen)● often during HotDeploy● because ClassLoaders are leaking● because there are too many different classes

● Singletons (and not only them)● because of static attributes

Interesting projects

● JRebel● Javaleon● HotSwap● Tattletale● OSGi● NetBeans module system● JBoss Modules● Project jigsaw

Thank you for attention

Martin Skurla

crazyjavahacking.org

crazyjavahacking@gmail.com