Transcript
Page 1: MarsJUG - Le classpath n'est pas mort, mais presque

Alexis Hassler

Le classpath n'est pas mort...

MarsJUGseptembre 2013

mais presque

Page 2: MarsJUG - Le classpath n'est pas mort, mais presque

"Class�path is dead!"

Mark Reinhold

JavaOne 2009

Page 3: MarsJUG - Le classpath n'est pas mort, mais presque

Classpath

Page 4: MarsJUG - Le classpath n'est pas mort, mais presque

Classloader

Page 5: MarsJUG - Le classpath n'est pas mort, mais presque

Mort ?

Page 6: MarsJUG - Le classpath n'est pas mort, mais presque

Successeur

Page 7: MarsJUG - Le classpath n'est pas mort, mais presque

Alexis Hassler

Développeur, formateur Java

Indépendant

Co-leader du

Page 8: MarsJUG - Le classpath n'est pas mort, mais presque

Classpath

Page 9: MarsJUG - Le classpath n'est pas mort, mais presque

Chercher les classes

String hello = "Bonjour Devoxx";

MyStuff var;

CLASSPATH

Page 10: MarsJUG - Le classpath n'est pas mort, mais presque

-classpath

java -cp hello-lib.jar HelloWorld

Page 11: MarsJUG - Le classpath n'est pas mort, mais presque

Manifest

Manifest-Version: 1.0

Class-Path: hello-lib.jar

Main-Class: HelloWorld

Page 12: MarsJUG - Le classpath n'est pas mort, mais presque

Connaitre le classpath

System.getProperty("java.class.path");

Page 13: MarsJUG - Le classpath n'est pas mort, mais presque

Erreurs

java.lang.NoClassDefFoundError

java.lang.ClassNotFoundException

Page 14: MarsJUG - Le classpath n'est pas mort, mais presque

Classpath

Géré par des classloaders

Page 15: MarsJUG - Le classpath n'est pas mort, mais presque

Classloader

Page 16: MarsJUG - Le classpath n'est pas mort, mais presque

java.lang.ClassLoader

loadClass(String name) : Class<?>

getResource(String name) : URLgetResources(String name) : Enumeration<URL>getResourceAsStream(String name) : InputStream

getParent() : ClassLoader

Page 17: MarsJUG - Le classpath n'est pas mort, mais presque

Classloader

MyStuff.class.getClassLoader()

sun.misc.Launcher$AppClassLoader

CLASSPATH

Page 18: MarsJUG - Le classpath n'est pas mort, mais presque

Bootstrap Classloader

classloader.getClass().getClassLoader()

null

Page 19: MarsJUG - Le classpath n'est pas mort, mais presque

Bootstrap Classloader

BootstrapClassLoader

Page 20: MarsJUG - Le classpath n'est pas mort, mais presque

ExtensionCl

asspath

sun.misc.Launcher$ExtClassLoader

sun.misc.Launcher$AppClassLoader

Délégation

BootstrapClassLoader

Parent first

Parent first

System ClassLoader

Extension ClassLoader

Page 21: MarsJUG - Le classpath n'est pas mort, mais presque

Délégation

java -cp hello-lib.jar ...

System.getProperty("java.class.path");

ClasspathSystem ClassLoader

Page 22: MarsJUG - Le classpath n'est pas mort, mais presque

Délégation

java -Djava.ext.dirs=~/.java7/ext ...

System.getProperty("java.ext.dirs");

Extension

Extension ClassLoader

Page 23: MarsJUG - Le classpath n'est pas mort, mais presque

Délégation

Ext != Endorsed

Page 24: MarsJUG - Le classpath n'est pas mort, mais presque

Délégation

java -Xbootclasspath:hello-rt.jar ...

BootstrapClassLoader

System.getProperty("sun.boot.class.path");

Page 25: MarsJUG - Le classpath n'est pas mort, mais presque

bootclasspath

●java -Xbootclasspath:hello-rt.jar ...

●java -Xbootclasspath/a:hello-lib.jar ...

●java -Xbootclasspath/p:hello-lib.jar ...

Page 26: MarsJUG - Le classpath n'est pas mort, mais presque

Endorsed

java -Djava.endorsed.dirs=~/.java7/endorsed ...

Endorsed

BootstrapClassLoader

Page 27: MarsJUG - Le classpath n'est pas mort, mais presque

Endorsed

APIs standards hors JCPorg.omg (CORBA), org.w3c.dom, org.xml.sax (XML)

APIs standaloneJAXP, JAXB, Scripting, Compiler API,...

Page 28: MarsJUG - Le classpath n'est pas mort, mais presque

27 au 29 mars 2013

Démonstration

http://github.com/hasalex/classpath-demo

Page 29: MarsJUG - Le classpath n'est pas mort, mais presque

classloader-demo

DémonstrationBootstrapClassLoaderSystem ClassLoader

java -cp cl-demo.jar fr.sewatech.classpath.Count

Page 30: MarsJUG - Le classpath n'est pas mort, mais presque

classloader-demo

DémonstrationBootstrapClassLoader

java -Xbootclasspath/p:lib/cl-demo.jar fr.sewatech.classpath.Count

Page 31: MarsJUG - Le classpath n'est pas mort, mais presque

URLClassloader

java.net.URLClassLoader

sun.misc.Launcher$AppClassLoader

sun.misc.Launcher$ExtClassLoader

URLURLURL

Page 32: MarsJUG - Le classpath n'est pas mort, mais presque

URLClassloader

System ClassLoader

Bootstrap ClassLoader

URL ClassLoader

URL ClassLoader

URL ClassLoader

Parent first

Parent first

Parent first

Page 33: MarsJUG - Le classpath n'est pas mort, mais presque

FLTM Classloader

Fait Le Toi-Même

Page 34: MarsJUG - Le classpath n'est pas mort, mais presque

Usages

Application ServersJRebel

Javassist, CGLib,...

Page 35: MarsJUG - Le classpath n'est pas mort, mais presque

Tomcat

System

Bootstrap

Common

Webapp1

Webapp2

Webapp3

Local First

Page 36: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss AS 5

System

Bootstrap

Common

Web App

Ent App

Web Module

EJB Module

Local First

Repo First

Page 37: MarsJUG - Le classpath n'est pas mort, mais presque

Erreurs

ClassCastExceptionMyStuff cannot be cast to MyStuff

WTF ?

Page 38: MarsJUG - Le classpath n'est pas mort, mais presque

Erreurs

URL ClassLoader

URL ClassLoader

MyStuff var = MyStuffFactory.build();

return new MyStuff() ;

Page 39: MarsJUG - Le classpath n'est pas mort, mais presque

27 au 29 mars 2013

Démonstration

http://github.com/hasalex/classpath-demo

Page 40: MarsJUG - Le classpath n'est pas mort, mais presque

classloader-demo

message-main

message-common

Démonstration

message-printer

Page 41: MarsJUG - Le classpath n'est pas mort, mais presque

classloader-demo

message-main

message-common

Démonstration

message-printer

java -cp cl-demo.jar:msg-main.jar fr.sewatech.classpath.HelloViaMvnRepo

Page 42: MarsJUG - Le classpath n'est pas mort, mais presque

Démonstration

java -cp cl-demo.jar:msg-main.jar fr.sewatech.classpath.HelloViaMvnRepo

classloader-demo

message-main

message-common

message-printer

message-main

Classpa

thMaven

Reposito

ry

ClassL

oader

Page 43: MarsJUG - Le classpath n'est pas mort, mais presque

Démonstration

classloader-demo

message-common

message-printer

message-main

message-main

System ClassLoader ParentFirst ClassLoader

Page 44: MarsJUG - Le classpath n'est pas mort, mais presque

Démonstration

System ClassLoader LocalFirst ClassLoader

classloader-demo

message-common

message-printer

message-main

message-main

Page 45: MarsJUG - Le classpath n'est pas mort, mais presque

Mort

Page 46: MarsJUG - Le classpath n'est pas mort, mais presque

Jar

HELL

http://www.ironmaidenwallpaper.com/

Page 47: MarsJUG - Le classpath n'est pas mort, mais presque

Dépendances

Maven, Gradle,...

Page 48: MarsJUG - Le classpath n'est pas mort, mais presque

Dépendances

Classpath

Page 49: MarsJUG - Le classpath n'est pas mort, mais presque

Runtime

A plat

Fichiers jarjuste du stockagepas ou peu de métadonnée

Classpath

Page 50: MarsJUG - Le classpath n'est pas mort, mais presque

Runtime

Hiérarchique applications server

Page 51: MarsJUG - Le classpath n'est pas mort, mais presque

27 au 29 mars 2013

Démonstration

http://github.com/hasalex/classpath-demo

Page 52: MarsJUG - Le classpath n'est pas mort, mais presque

message-main

message-common

Démonstration

message-printer

classloader-demo

slf4j-api 1.5.11

slf4j-api 1.7.2

Page 53: MarsJUG - Le classpath n'est pas mort, mais presque

Remplaçant

Page 54: MarsJUG - Le classpath n'est pas mort, mais presque

Application

Granularité

Classpath

Page 55: MarsJUG - Le classpath n'est pas mort, mais presque

Application Monolithique

Granularité

Application Web / JavaEE

Page 56: MarsJUG - Le classpath n'est pas mort, mais presque

Librairies partagéesApplication

Granularité

Application Web / JavaEE

Page 57: MarsJUG - Le classpath n'est pas mort, mais presque

Application

Modularité

Application Web / JavaEE

Page 58: MarsJUG - Le classpath n'est pas mort, mais presque

Modularité

Visibilité

Import

Export

Dépendancestransitives

Page 59: MarsJUG - Le classpath n'est pas mort, mais presque

1999

Java embarquéJava SEJava serveur

Page 60: MarsJUG - Le classpath n'est pas mort, mais presque

OSGi

BundleFichier jarMETA-INF/MANIFEST.MFImport / export de packages

Page 61: MarsJUG - Le classpath n'est pas mort, mais presque

Bundle-Name = Simple Bundle

Bundle-SymbolicName = simple-bundle

Bundle-Description = Simple Bundle.

Export-Package = fr.sewatech.mystuff.services

Import-Package = org.osgi.framework;version=1.3

Bundle-Version = 1.0.1

OSGi

Page 62: MarsJUG - Le classpath n'est pas mort, mais presque

OSGi

OS + Hardware

Java Execution Environment

Applications(bundles)

Module

Life Cycle

Services

Page 63: MarsJUG - Le classpath n'est pas mort, mais presque

OSGi

Apporte de la valeur=> applications hautement dynamiques

Apporte de la complexité=> outils pour gérer la complexité

Page 64: MarsJUG - Le classpath n'est pas mort, mais presque

Jigsaw

Projet OpenJDK

Intégré au JDK 7

9 (2016)

8 (2012)

(2008)

. . .

Page 65: MarsJUG - Le classpath n'est pas mort, mais presque

Jigsaw

Modularité des applications

Modularité du JDK

Page 66: MarsJUG - Le classpath n'est pas mort, mais presque

Jigsaw

Dépendance à une partie du JDKPlus besoin de Corba pour Hello WorldPlus besoin de Swing pour Tomcat

RepositoryTéléchargement automatique des modules

Page 67: MarsJUG - Le classpath n'est pas mort, mais presque

Jigsaw

module-info.java

module message-main @ 1.0 {

exports fr.sewatech.message;

requires fr.sewatech.message-common @ 1.1;

class fr.sewatech.message.Main;

}

Page 68: MarsJUG - Le classpath n'est pas mort, mais presque
Page 69: MarsJUG - Le classpath n'est pas mort, mais presque
Page 70: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss Modules

Sous-projet de JBoss AS 7

Inspiré de Jigsaw

Base de JBoss OSGi

Page 71: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss Modules

java -jar jboss-modules.jar -mp path/to/modules

my.main.module.name

Java SE

Page 72: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss Modules

hibernate-infinispan-4.1.6.Final.jar

module.xml

hibernate-core-4.1.6.Final.jar

hibernate-entitymanager-4.1.6.Final.jar

modules

com

fr

org

...

org

hibernate

main

Page 73: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss Modules

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.1"

name="fr.sewatech.conference.classloader-demo">

<main-class name="fr.sewatech.classpath.Hello"/>

<resources>

<resource-root path="classloader-demo-1.0-SNAPSHOT.jar"/>

</resources>

<dependencies>

<module name="fr.sewatech.conference.message-main" />

</dependencies>

</module>

Page 74: MarsJUG - Le classpath n'est pas mort, mais presque

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.1" name="org.hibernate">

<resources>

<resource-root path="hibernate-core-4.0.0.Final.jar"/>

<resource-root path="hibernate-commons-annotations-4.0.1.Final.jar"/>

<resource-root path="hibernate-entitymanager-4.0.0.Final.jar"/>

</resources>

<dependencies>

<module name="javax.api"/>

<module name="javax.persistence.api"/>

<module name="javax.transaction.api"/>

<module name="org.apache.commons.collections"/>

<!-- ... -->

</dependencies>

</module>

Page 75: MarsJUG - Le classpath n'est pas mort, mais presque

27 au 29 mars 2013

Démonstration

http://github.com/hasalex/classpath-demo

Page 76: MarsJUG - Le classpath n'est pas mort, mais presque

JBoss AS 7

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

Page 77: MarsJUG - Le classpath n'est pas mort, mais presque

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

JBoss AS 7

message.war

Page 78: MarsJUG - Le classpath n'est pas mort, mais presque

Tomcat

WEB-INF/classes, WEB-INF/lib

System ClassLoader

CommonClass Loader

WebappClassLoader

$CATALINA_HOME/lib

Classloading

Page 79: MarsJUG - Le classpath n'est pas mort, mais presque

Tomcat

WEB-INF/classes, WEB-INF/lib

System ClassLoader

CommonClass Loader

WebappClassLoader

$CATALINA_HOME/lib

Module ?

ModuleClassLoader

modules

Page 80: MarsJUG - Le classpath n'est pas mort, mais presque

Tomcat

A suivre...

https://github.com/hasalex/tomcat-modules

Page 81: MarsJUG - Le classpath n'est pas mort, mais presque

27 au 29 mars 2013

Démonstration

http://github.com/hasalex/classpath-demo

Page 82: MarsJUG - Le classpath n'est pas mort, mais presque

Cible

Applications complexes

Beaucoup de réutilisation

Page 83: MarsJUG - Le classpath n'est pas mort, mais presque

Développement / déploiement

Artefacts ≠ ModulesNotions différentesOutillage difficile

Page 84: MarsJUG - Le classpath n'est pas mort, mais presque

En attendant Jigsaw ?

Page 85: MarsJUG - Le classpath n'est pas mort, mais presque

Merci