87
Alexis Hassler Le classpath n'est pas mort... ElsassJUG Janvier 2015 mais presque

ElsassJUG - Le classpath n'est pas mort

Embed Size (px)

Citation preview

Page 1: ElsassJUG - Le classpath n'est pas mort

Alexis Hassler

Le classpath n'est pas mort...

ElsassJUGJanvier 2015

mais presque

Page 2: ElsassJUG - Le classpath n'est pas mort

"Classpath is dead!"

Mark Reinhold JavaOne 2009

Page 3: ElsassJUG - Le classpath n'est pas mort

ClasspathClassloader

Mort ?

Succession

Page 4: ElsassJUG - Le classpath n'est pas mort

Alexis Hassler

Développeur, formateur Java

Indépendant

Co-leader du

Page 5: ElsassJUG - Le classpath n'est pas mort

Classpath

Page 6: ElsassJUG - Le classpath n'est pas mort

String hello = "Bonjour Devoxx";

MyStuff var;

Chercher les classes

CLASSPATH

Page 7: ElsassJUG - Le classpath n'est pas mort

-classpath

java -cp hello-lib.jar HelloWorld

Page 8: ElsassJUG - Le classpath n'est pas mort

Manifest

Manifest-Version: 1.0

Class-Path: hello-lib.jar

Main-Class: HelloWorld

Page 9: ElsassJUG - Le classpath n'est pas mort

Connaître le classpath

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

Page 10: ElsassJUG - Le classpath n'est pas mort

Erreurs

java.lang.NoClassDefFoundError

java.lang.ClassNotFoundException

Page 11: ElsassJUG - Le classpath n'est pas mort

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

Page 12: ElsassJUG - Le classpath n'est pas mort

Classpath

Géré par des classloaders

Page 13: ElsassJUG - Le classpath n'est pas mort

Classloader

Page 14: ElsassJUG - Le classpath n'est pas mort

java.lang.ClassLoader

loadClass(String name) : Class<?>

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

getParent() : ClassLoader

Page 15: ElsassJUG - Le classpath n'est pas mort

Classloader

sun.misc.Launcher$AppClassLoader

CLASSPATH

MyStuff.class.getClassLoader()

Page 16: ElsassJUG - Le classpath n'est pas mort

Bootstrap Classloader

null

classloader.getClass().getClassLoader()

Page 17: ElsassJUG - Le classpath n'est pas mort

Bootstrap Classloader

BootstrapClassLoader

Page 18: ElsassJUG - Le classpath n'est pas mort

ExtensionCl

asspath

sun.misc.Launcher$ExtClassLoader

sun.misc.Launcher$AppClassLoader

Délégation

BootstrapClassLoader

Parentfirst

Parent first

System ClassLoader

Extension ClassLoader

Page 19: ElsassJUG - Le classpath n'est pas mort

Délégation

java -cp hello-lib.jar ...

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

ClasspathSystem ClassLoader

Page 20: ElsassJUG - Le classpath n'est pas mort

Délégation

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

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

Extension

Extension ClassLoader

Page 21: ElsassJUG - Le classpath n'est pas mort

Délégation

Ext != Endorsed

Page 22: ElsassJUG - Le classpath n'est pas mort

Délégation

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

BootstrapClassLoader

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

Page 23: ElsassJUG - Le classpath n'est pas mort

bootclasspath

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

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

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

Page 24: ElsassJUG - Le classpath n'est pas mort

Endorsed

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

Endorsed

BootstrapClassLoader

Page 25: ElsassJUG - Le classpath n'est pas mort

Endorsed

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

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

Page 26: ElsassJUG - Le classpath n'est pas mort

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

Page 27: ElsassJUG - Le classpath n'est pas mort

classloader-demo

DémonstrationBootstrapClassLoader

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

System ClassLoader

Page 28: ElsassJUG - Le classpath n'est pas mort

classloader-demo

DémonstrationBootstrapClassLoader

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

Page 29: ElsassJUG - Le classpath n'est pas mort

URLClassloader

java.net.URLClassLoader

sun.misc.Launcher$AppClassLoader

sun.misc.Launcher$ExtClassLoader

URLURLURL

Page 30: ElsassJUG - Le classpath n'est pas mort

URLClassloader

System ClassLoader

Bootstrap ClassLoader

URL ClassLoader

URL ClassLoader

URL ClassLoader

Parentfirst

Parentfirst

Parentfirst

Page 31: ElsassJUG - Le classpath n'est pas mort

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

Page 32: ElsassJUG - Le classpath n'est pas mort

Démonstration

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

classloader-demo

message-main

message-common

message-printer

message-main

Page 33: ElsassJUG - Le classpath n'est pas mort

classloader-demo

message-main

message-common

message-printer

message-main

Démonstration

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

message-mainClasspa

th

URLClasslo

ader

Page 34: ElsassJUG - Le classpath n'est pas mort

Démonstration

classloader-demo

message-common

message-printer

message-main

message-main

System ClassLoader ParentFirst ClassLoader

Page 35: ElsassJUG - Le classpath n'est pas mort

FLTM Classloader

Fait Le Toi-Même

Page 36: ElsassJUG - Le classpath n'est pas mort

Usages

Application Servers

JRebel

Javassist, CGLib,...

Page 37: ElsassJUG - Le classpath n'est pas mort

Tomcat

System

Bootstrap

Common

Webapp1

Webapp2

Webapp3

Local First

Page 38: ElsassJUG - Le classpath n'est pas mort

JBoss AS 5

System

Bootstrap

Common

Web App

Ent App

Web Module

EJB Module

Local First

Repo First

Page 39: ElsassJUG - Le classpath n'est pas mort

Erreurs

ClassCastException

MyStuff cannot be cast to MyStuff

WTF ?

Page 40: ElsassJUG - Le classpath n'est pas mort

Erreurs

URL ClassLoader

URL ClassLoader

MyStuff var = MyStuffFactory.build();

return new MyStuff() ;

Page 41: ElsassJUG - Le classpath n'est pas mort

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

Page 42: ElsassJUG - Le classpath n'est pas mort

Démonstration

classloader-demo

message-common

message-printer

message-main

message-main

System ClassLoader ParentFirst ClassLoader

Page 43: ElsassJUG - Le classpath n'est pas mort

Démonstration

classloader-demo

message-common

message-printer

message-main

message-main

System ClassLoader LocalFirst ClassLoader

Page 44: ElsassJUG - Le classpath n'est pas mort

Mort ?

Page 45: ElsassJUG - Le classpath n'est pas mort

http://www.ironmaidenwallpaper.com/

Page 46: ElsassJUG - Le classpath n'est pas mort

Dépendances

Maven, Gradle,...

Page 47: ElsassJUG - Le classpath n'est pas mort

Dépendances

Classpath

Page 48: ElsassJUG - Le classpath n'est pas mort

Runtime

Classpath

A plat

Fichiers jarjuste du stockage

pas ou peu de métadonnée

Page 49: ElsassJUG - Le classpath n'est pas mort

Runtime

Hiérarchique applications server

Page 50: ElsassJUG - Le classpath n'est pas mort

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

Page 51: ElsassJUG - Le classpath n'est pas mort

message-main

message-common

Démonstration

message-printer

classloader-demo

slf4j-api 1.5.11

slf4j-api 1.7.2

Page 52: ElsassJUG - Le classpath n'est pas mort

Succession

Page 53: ElsassJUG - Le classpath n'est pas mort

Granularité

Classpath

Application

Page 54: ElsassJUG - Le classpath n'est pas mort

Granularité

Application Web / JavaEE

Application Monolithique

Page 55: ElsassJUG - Le classpath n'est pas mort

Granularité

Application Web / JavaEE

Librairies partagéesApplication

Page 56: ElsassJUG - Le classpath n'est pas mort

Modularité

Application Web / JavaEE

Application

Page 57: ElsassJUG - Le classpath n'est pas mort

Modularité

Visibilité

Import

Export

Dépendancestransitives

Page 58: ElsassJUG - Le classpath n'est pas mort

1999

Java embarquéJava SEJava serveur

Page 59: ElsassJUG - Le classpath n'est pas mort

OSGi

BundleFichier jar

META-INF/MANIFEST.MF

Import / export de packages

Page 60: ElsassJUG - Le classpath n'est pas mort

Bundle-Name = Simple Bundle

Bundle-SymbolicName = simple-bundle

Bundle-Description = Simple Bundle.

Bundle-Version = 1.0.1

Export-Package = fr.sewatech.mystuff.services

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

OSGi

Page 61: ElsassJUG - Le classpath n'est pas mort

OSGi

OS + Hardware

Java Execution Environment

Applications(bundles)

Module

Life Cycle

Services

Page 62: ElsassJUG - Le classpath n'est pas mort
Page 63: ElsassJUG - Le classpath n'est pas mort

JBoss Modules

Sous-projet de Wildfy

Inspiré de Jigsaw

Base de JBoss OSGi

Page 64: ElsassJUG - Le classpath n'est pas mort

JBoss Modules

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

my.main.module.name

Java SE

Page 65: ElsassJUG - Le classpath n'est pas mort

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 66: ElsassJUG - Le classpath n'est pas mort

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 67: ElsassJUG - Le classpath n'est pas mort

<?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 68: ElsassJUG - Le classpath n'est pas mort

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

Page 69: ElsassJUG - Le classpath n'est pas mort

WildFly

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

Page 70: ElsassJUG - Le classpath n'est pas mort

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

WildFly

message.war

Page 71: ElsassJUG - Le classpath n'est pas mort

WildFly

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

<jboss-deployment-structure>

<deployment>

<dependencies>

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

</dependencies>

</deployment>

</jboss-deployment-structure>

message.war

Page 72: ElsassJUG - Le classpath n'est pas mort

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

Page 73: ElsassJUG - Le classpath n'est pas mort

Tomcat

Classloading

WEB-INF/classes, WEB-INF/lib

WebappClassLoader

$CATALINA_HOME/lib

SystemClassLoader

CommonClass Loader

Page 74: ElsassJUG - Le classpath n'est pas mort

Tomcat

Module ?

WEB-INF/classes, WEB-INF/lib

SystemClassLoader

CommonClass Loader

WebappClassLoader

$CATALINA_HOME/lib

ModuleClassLoader

modules

Page 75: ElsassJUG - Le classpath n'est pas mort

Tomcat

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

Page 76: ElsassJUG - Le classpath n'est pas mort

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

Page 77: ElsassJUG - Le classpath n'est pas mort

Cible

Applications complexes

Beaucoup de réutilisation

Page 78: ElsassJUG - Le classpath n'est pas mort

Développement / déploiement

Artefacts ≠ ModulesNotions différentes

Outillage diffcile

Page 79: ElsassJUG - Le classpath n'est pas mort

Jigsaw

Projet OpenJDK

Intégré au JDK 7

9 (2016)

8 (2012)

(2008)

. . .

Page 80: ElsassJUG - Le classpath n'est pas mort

Jigsaw

Modularité du JDKCorba pour Hello World ?

Swing pour Tomcat ?

Page 81: ElsassJUG - Le classpath n'est pas mort

Jigsaw

Modularité des applicationsmodule-info.java

module message-main @ 1.0 {

exports fr.sewatech.message;

requires fr.sewatech.message-common @ 1.1;

class fr.sewatech.message.Main;

}

Page 82: ElsassJUG - Le classpath n'est pas mort

Jigsaw

JEP 200: The Modular JDKJEP 201: Modular Source Code

JEP 220: The Modular Run-Time Images

JEP xxx: The JDK Module System

JSR 376: Java Platform Module System

Page 83: ElsassJUG - Le classpath n'est pas mort

Jigsaw

rt.jar tools.jar

Page 84: ElsassJUG - Le classpath n'est pas mort

Jigsaw

Extension

sun.misc.Launcher$ExtClassLoader

sun.misc.Launcher$AppClassLoader

BootstrapClassLoader

Parentfirst

Parent first

System ClassLoader

Extension ClassLoader

Page 85: ElsassJUG - Le classpath n'est pas mort

J'imagine qu'il est tentant,

si le seul outil que vous avez est un marteau, de traiter tout problème comme si c'était un clou.

Abraham MaslowPaul Watzlawick

Page 86: ElsassJUG - Le classpath n'est pas mort

?

Page 87: ElsassJUG - Le classpath n'est pas mort

@AlexisHassler

http://alexis-hassler.com

[email protected]

http://sewatech.fr