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

Preview:

DESCRIPTION

En 2009, la mort du classpath a été annoncée. Les classloaders à plat ou hiérarchiques devaient être remplacés par des systèmes modulaires et tous nos problèmes de dépendances devaient se résoudre d'eux-même. Quatre ans plus tard, le classpath vit toujours et pour quelques années encore. Dans la première partie de cette session, nous reviendrons sur le fonctionnement des classloaders du JDK et les problèmes infernaux posés par le classpath. Nous verrons aussi comment les serveurs d'applications, comme Tomcat, gèrent leur classloaders de façon hiérarchique, afin d'isoler les applications entre elles. Dans la deuxième partie, nous parlerons de modularité et de son impact sur la gestion des dépendances, à l'exécution des applications. Des solutions existent déjà, comme OSGi et Jigsaw, d'autres émergent, comme JBoss Modules. Nous vous montrerons comment ce dernier fonctionne, dans JBoss AS 7, en autonome, ou même dans Tomcat.

Citation preview

Alexis Hassler

Le classpath n'est pas mort...

MarsJUGseptembre 2013

mais presque

"Class�path is dead!"

Mark Reinhold

JavaOne 2009

Classpath

Classloader

Mort ?

Successeur

Alexis Hassler

Développeur, formateur Java

Indépendant

Co-leader du

Classpath

Chercher les classes

String hello = "Bonjour Devoxx";

MyStuff var;

CLASSPATH

-classpath

java -cp hello-lib.jar HelloWorld

Manifest

Manifest-Version: 1.0

Class-Path: hello-lib.jar

Main-Class: HelloWorld

Connaitre le classpath

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

Erreurs

java.lang.NoClassDefFoundError

java.lang.ClassNotFoundException

Classpath

Géré par des classloaders

Classloader

java.lang.ClassLoader

loadClass(String name) : Class<?>

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

getParent() : ClassLoader

Classloader

MyStuff.class.getClassLoader()

sun.misc.Launcher$AppClassLoader

CLASSPATH

Bootstrap Classloader

classloader.getClass().getClassLoader()

null

Bootstrap Classloader

BootstrapClassLoader

ExtensionCl

asspath

sun.misc.Launcher$ExtClassLoader

sun.misc.Launcher$AppClassLoader

Délégation

BootstrapClassLoader

Parent first

Parent first

System ClassLoader

Extension ClassLoader

Délégation

java -cp hello-lib.jar ...

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

ClasspathSystem ClassLoader

Délégation

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

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

Extension

Extension ClassLoader

Délégation

Ext != Endorsed

Délégation

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

BootstrapClassLoader

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

bootclasspath

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

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

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

Endorsed

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

Endorsed

BootstrapClassLoader

Endorsed

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

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

27 au 29 mars 2013

Démonstration

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

classloader-demo

DémonstrationBootstrapClassLoaderSystem ClassLoader

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

classloader-demo

DémonstrationBootstrapClassLoader

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

URLClassloader

java.net.URLClassLoader

sun.misc.Launcher$AppClassLoader

sun.misc.Launcher$ExtClassLoader

URLURLURL

URLClassloader

System ClassLoader

Bootstrap ClassLoader

URL ClassLoader

URL ClassLoader

URL ClassLoader

Parent first

Parent first

Parent first

FLTM Classloader

Fait Le Toi-Même

Usages

Application ServersJRebel

Javassist, CGLib,...

Tomcat

System

Bootstrap

Common

Webapp1

Webapp2

Webapp3

Local First

JBoss AS 5

System

Bootstrap

Common

Web App

Ent App

Web Module

EJB Module

Local First

Repo First

Erreurs

ClassCastExceptionMyStuff cannot be cast to MyStuff

WTF ?

Erreurs

URL ClassLoader

URL ClassLoader

MyStuff var = MyStuffFactory.build();

return new MyStuff() ;

27 au 29 mars 2013

Démonstration

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

classloader-demo

message-main

message-common

Démonstration

message-printer

classloader-demo

message-main

message-common

Démonstration

message-printer

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

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

Démonstration

classloader-demo

message-common

message-printer

message-main

message-main

System ClassLoader ParentFirst ClassLoader

Démonstration

System ClassLoader LocalFirst ClassLoader

classloader-demo

message-common

message-printer

message-main

message-main

Mort

Jar

HELL

http://www.ironmaidenwallpaper.com/

Dépendances

Maven, Gradle,...

Dépendances

Classpath

Runtime

A plat

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

Classpath

Runtime

Hiérarchique applications server

27 au 29 mars 2013

Démonstration

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

message-main

message-common

Démonstration

message-printer

classloader-demo

slf4j-api 1.5.11

slf4j-api 1.7.2

Remplaçant

Application

Granularité

Classpath

Application Monolithique

Granularité

Application Web / JavaEE

Librairies partagéesApplication

Granularité

Application Web / JavaEE

Application

Modularité

Application Web / JavaEE

Modularité

Visibilité

Import

Export

Dépendancestransitives

1999

Java embarquéJava SEJava serveur

OSGi

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

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

OSGi

OS + Hardware

Java Execution Environment

Applications(bundles)

Module

Life Cycle

Services

OSGi

Apporte de la valeur=> applications hautement dynamiques

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

Jigsaw

Projet OpenJDK

Intégré au JDK 7

9 (2016)

8 (2012)

(2008)

. . .

Jigsaw

Modularité des applications

Modularité du JDK

Jigsaw

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

RepositoryTéléchargement automatique des modules

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;

}

JBoss Modules

Sous-projet de JBoss AS 7

Inspiré de Jigsaw

Base de JBoss OSGi

JBoss Modules

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

my.main.module.name

Java SE

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

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>

<?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>

27 au 29 mars 2013

Démonstration

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

JBoss AS 7

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

bin Scripts de démarrage

bundles Composants OSGi

modules Modules JBoss

standalone Profil standalone

domain Profil domain

JBoss AS 7

message.war

Tomcat

WEB-INF/classes, WEB-INF/lib

System ClassLoader

CommonClass Loader

WebappClassLoader

$CATALINA_HOME/lib

Classloading

Tomcat

WEB-INF/classes, WEB-INF/lib

System ClassLoader

CommonClass Loader

WebappClassLoader

$CATALINA_HOME/lib

Module ?

ModuleClassLoader

modules

Tomcat

A suivre...

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

27 au 29 mars 2013

Démonstration

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

Cible

Applications complexes

Beaucoup de réutilisation

Développement / déploiement

Artefacts ≠ ModulesNotions différentesOutillage difficile

En attendant Jigsaw ?

Merci

Recommended