NSY102 1 Cnam Paris jean-michel Douin, douin au cnam point fr version du 3 Juin 2013 NSY102...
Transcript of NSY102 1 Cnam Paris jean-michel Douin, douin au cnam point fr version du 3 Juin 2013 NSY102...
NSY1021
Cnam Parisjean-michel Douin, douin au cnam point fr
version du 3 Juin 2013
NSY102Conception de logiciels Intranet
JVM.class et instances de Class, chargeur de classes
OSGiOpen Services Gateway Initiative
NSY1022
Principale Bibliographie
• ClassLoader• http://java.sun.com/developer/technicalArticles/Networking/classloaders/index.html• http://www.ibm.com/developerworks/edu/j-dw-javaclass-i.html
• OSGi• www.osgi.org • http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html• http://www.aqute.biz/OSGi/Tutorial• http://www.aqute.biz/OSGi/Presentations• www.riawork.org/docs/Introduce.OSGi.ppt• http://javasymposium.techtarget.com/images/TSSJS_E_Presentations/
Colyer_Adrian_Spring-OSGi.pdf• http://t-templier.developpez.com/tutoriel/java/osgi/osgi1/
• École d’été ICAR 2006• http://www-adele.imag.fr/users/Didier.Donsez/cours/osgi_icar2006.pdf• http://www2.lifl.fr/icar/Preface/preface.html
NSY1023
Sommaire
• Du « classLoader » de la JVM vers OSGi– JVM
• Objectifs, architecture• Le fichier généré ".class" en annexe• Le chargeur de ".class"
– Instances de java.lang.Class
– Supervision possible avec JMX …
» Voir Java Management eXtension
• Limites, Critiques
– OSGi (Open Services Gateway initiative) et SOA (Services Oriented Architecture)
• Chargement, déchargement,• mise à jour, liaison dynamique des imports
– Eclipse et ses plug-in, Spring, …
NSY1024
Objectifs
TINI,SunSPOT
Sun
"Test.class"local ou distant
1100 1010 1111 1110 1011 1010 1011 11100000 0011 0001 1101 ............................
% java Test > java Test
javac Test.java
public class Test{ public void .....}
java TestOu un navigateurMuni d’une JVM
NSY1025
Architecture
• Java Virtual Machine– Chargeur de classes et l’exécutif– Extrait de http://www.techniques-ingenieur.fr/dossier/machine_virtuelle_java/H1588
Chargeur
dynamique
de classes
Mémoire
d ’objets
et
ramasse-miettes
Librairies
natives
- fichiers
- Thread
réseau,internet
machine locale
disque, prom, ...
Machine hôte, système d’exploitation
Interpréteur
des
instructions
Code et
données
des classes
Environnements
et
Piles
d’exécution
Exécutif
NSY1026
Chargeurs de classe
• Chargement dynamique des .class– Au fur et à mesure, en fonction des besoins
• Chargement paresseux, tardif, lazy
• Le chargeur – Engendre des instances de java.lang.Class– Maintient l’arbre d’héritage
• Plusieurs chargeurs de classes peuvent co-exister
• Les instances de la classe java.lang.Class– « Sont des instances comme les autres » – Gérées par le ramasse-miettes
NSY1027
Sommaire : Classes et java.lang.Class
• Le fichier .class– Format en annexe
– Est-ce bien nécessaire de le détailler ?,• le format du .class en annexe
• Le chargeur de .class
– Les chargeurs de classes de .class en classe Class
NSY1028
Sommaire suite
• A chaque classe un .class, nous avons– Classes anonymes, dynamicProxy, …
• Chargeur de classe, au fur et à mesure– Du « .class » en instance de java.lang.Class
1100 1010 1111 1110 1011 1010 1011 11100000 0011 0001 1101 ............................
Le fichier Exemple.class
super
Une instance de la classe Class
Chargeur
Mémoire des objets
NSY1029
Classe Class, getClass
• Méthode Class<?> getClass()– Héritée de la classe Object
– Exemple e = new Exemple();– Class<?> c = e.getClass();
e
Descripteur etattributs de e
Descripteur de la classe Exemplee.getClass() == Exemple.class
java.lang.Object
Graphe d’héritage
super
Object.class
c
NSY10210
Introspection
• Classe Class et Introspection – java.lang.Class;– java.lang.reflect.*;
Les méthodesConstructor[] getConstructorsField[] getFieldsField[] getDeclaredFieldsMethod[] getMethodsMethod[] getDeclaredMethods…. get ….
• static Class<?> forName(String name);• static Class<?> forName(String name, boolean init, ClassLoader cl);• ClassLoader getClassLoader()
NSY10211
Chargement d’une classe, ClassLoader
• Implicite et tardif– Exemple e;
// pas de chargement
– Exemple e = new Exemple(); // chargement (si absente)
– Class<Exemple> classe = Exemple.class; // chargement (si absente)
• Équivalent à Class<?> classe = Class.forName("Exemple") ;
• Explicite et immédiat– String unNomdeClasse = XXXXX– Class.forName(unNomDeClasse)
– Class.forName(unNomDeClasse, unBooléen, unChargeurDeClasse)
– unChargeurDeClasse.loadClass ( unNomDeClasse )
NSY10212
ClassLoader de base
• ClassLoader– Par défaut celui de la JVM
• Bootstrap ClassLoader en natif (librairies de base, rt.jar)• Extension ClassLoader en Java ( lib/ext)• Application/System ClassLoader par défaut
• Bootstrap parent-de Extension parent-de Application
– ClassLoader prédéfinis ?– Écrire son propre ClassLoader ?
NSY10213
ClassLoader prédéfinis
• SecureClassLoader– la racine
• URLClassLoader
• RMIClassLoader– En distribué
• Téléchargement des « .class » nécessaires
NSY10214
URLClassLoader : un exemple
• Chargement distant de fichier .class et exécution
– Depuis cette archive• http://jfod.cnam.fr/progAvancee/classes/utiles.jar
– Ou bien un .class à cette URL• http://jfod.cnam.fr/progAvancee/classes/
1. Création d’une instance de URLClassLoader2. Son parent est le classLoader par défaut3. Class<?> classe = forName(nom,init,urlClassLoader)
1. nom le nom de la classe2. init : exécution des blocs statiques retardée ou non
4. Recherche de la méthode main par introspection
urlClassLoader
NSY10215
URLClassLoader : un exemple
public class Exemple1{
URL urlJars = new URL("http://jfod.cnam.fr/progAvancee/classes/utiles.jar"); URL urlClasses = new URL("http://jfod.cnam.fr/progAvancee/classes/"); // par défaut le classloader parent est celui de la JVM URLClassLoader classLoader; classLoader = URLClassLoader.newInstance(new URL[]{urlJars,urlClasses});
Class<?> classe = Class.forName(args[0], true, classLoader);
//introspection ici pour l’exécution de la méthode main Method m = classe.getMethod("main", new Class[] {String[].class }); String[] paramètres = new String[args.length-1]; System.arraycopy(args,1,paramètres,0,args.length-1); m.invoke(null, new Object[]{paramètres});
}
java Exemple1 UneClasse param1 param2 param3
NSY10216
Écrire son propre chargeur de classe
• ClassLoader est une classe abstraite– Il suffit de redéfinir certaines méthodes
Class<?> loadClass(String name, boolean resolve) Recherche si cette classe ne serait pas présente chez le parentAppel de defineClass qui créée l’instance et l’installe dans
l’arborescence
Class<?> findClass(String name)est appelée par loadClass
NSY10217
Un exemple de Sun
class NetworkClassLoader extend ClassLoader { String host; int port; Map<String,Class<?>> cache = new Hashtable <String,Class<?>>(); private byte loadClassData(String name)[] { // load the class data from the connection }public synchronized Class loadClass(String name, boolean resolve) { Class<?> c = cache.get(name); if (c == null) { byte data[] = loadClassData(name); c = defineClass(data, 0, data.length); cache.put(name, c); } if (resolve) resolveClass(c); // édition des liens return c;}}
en détail ici http://www.ddj.com/mobile/184404484
http://www.koders.com/java/fid182AD13B5471AEF4962D6F58F527AA50E12C3B4C.aspx
NSY10218
Questions ?
• Plusieurs ClassLoader peuvent-ils co-exister ?– Espaces de noms disjoints
• La même classe peut donc être chargée dans deux « ClassLoaders » différents
• Chargement et déchargement de classe, comment faire?– Préambule :
• Les instances de la classe Class sont gérées par le ramasse-miettes
– Déchargement de classe « volontaire », par programme ?– par exemple une mise à jour !– Option non prévue ?
• À suivre…
• Comment en écrire un ?– Les exemples présentés sont en http://jfod.cnam.fr/progAvancee/classes/
NSY10219
Ecrire son propre chargeur : loadClass
public class MyClassLoader extends ClassLoader{
public MyClassLoader(){ super(MyClassLoader.class.getClassLoader()); // le parent } protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{ Class classe = findLoadedClass(name); if (classe == null) { byte[] classBytes = loadClassBytes(name); // page suivante if (classBytes == null){ return findSystemClass(name); }
classe = defineClass(name, classBytes, 0, classBytes.length); if (classe == null) throw new ClassNotFoundException(name); } if (resolve) resolveClass(classe); // recherche de tous les .class return classe; }
NSY10220
LoadClassBytes : lecture sur disque du .class
private byte[] loadClassBytes(String name){ // paquetage = répertoire
String cname = name.replace('.', '/') + ".class"; FileInputStream in = null; try{
in = new FileInputStream(cname); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int ch; while ((ch = in.read()) != -1){
byte b = (byte)(ch); buffer.write(b); } in.close(); return buffer.toByteArray(); }catch (IOException e){
if (in != null){ try {in.close(); } catch (IOException e2) { }
} return null; }}
NSY10221
ClassLoader(s)
page suivante
urlClassLoader
myClassLoader1
myClassLoader1 myClassLoader2
myClassLoader1
page d’après
NSY10222
L’exemple revisité
public class Exemple1{
URL urlJars = new URL("http://jfod.cnam.fr/progAvancee/classes/utiles.jar");
URL urlClasses = new URL("http://jfod.cnam.fr/progAvancee/classes/"); URL[] urls = new URL[]{urlJars, urlClasses}; ClassLoader loader = new MyClassLoader(); URLClassLoader classLoader; classLoader = URLClassLoader.newInstance(urls,loader);
Class<?> classe = Class.forName(args[0], true, classLoader);
Method m = classe.getMethod("main", new Class[] {String[].class }); String[] paramètres = new String[args.length-1]; System.arraycopy(args,1,paramètres,0,args.length-1); m.invoke(null, new Object[]{paramètres});
}
java Exemple1 UneClasse param1 param2 param3
note pour un fichier ce serait URL urlFichier = new File("").toURI().toURL();
classLoader
loader
NSY10223
myClassLoader1 & myClassLoader2
• myClassLoader1
UneClasse
java.lang.Class
• myClassLoader2
UneClasse
java.lang.Class
myClassLoader1 myClassLoader2
NSY10224
Exemple
ClassLoader loader1 = new MyClassLoader();
ClassLoader loader2 = new MyClassLoader();
Class<?> classe1 = Class.forName(args[0], true, loader1);
System.out.println("classe1 : " + classe1);
Class<?> classe2 = Class.forName(args[0], true, loader2);
System.out.println("classe2 : " + classe2);
System.out.println(" == " + (classe1==classe2));
Deux instances distinctes de UneClasse.class
NSY10225
Connaître son ClassLoader
• ClassLoader cl = getClass().getClassLoader(); – Le « ClassLoader » de cette classe
• ClassLoader ccl = Thread.currentThread().getContextClassLoader();
– Le « ClassLoader » installé par le créateur du Thread– ( setContextClassLoader(ClassLoader) )
NSY10226
Chercher une classe chez le voisin
• Chercher une classe depuis un autre ClassLoader– ClassLoader cl = Thread.currentThread().getContextClassLoader();– Thread.currentThread().setContextClassLoader(loader2);
– // attention appel ici de loadClass …
Class<?> cl_B = null;Cl_B = Thread.currentThread().getContextClassLoader(). loadClass("UnNomDeClasse");
– Thread.currentThread().setContextClassLoader(cl);
NSY10227
Cas des applettes
• Le navigateur a donc son propre URLClassLoader– Le serveur délivre les .class, en général au protocole HTTP
• Le navigateur installe un URLClassLoader par applette
NSY10228
Cas de Java Web Start
• Une utilisation de la classe URLClassLoader– Avec toutes les informations dans un fichier de description – Exemple : http://jfod.cnam.fr/NSY102/jsubmitter.jnlp
• JNLP Java Nework Launch Protocol• Téléchargement de la dernière version à chaque nouvelle exécution côté client
<jnlp spec="1.0+" codebase="http://jfod.cnam.fr/jnews/" href="http://jfod.cnam.fr/jnews/jsubmitter.jnlp">
<information> </information>
<security> </security>
<resources>
<java version="1.6+"/>
<jar href="http://jfod.cnam.fr/jnews/jsubmitter.jar"/>
</resources>
<application-desc main-class="submitter.JSubmitter"/>
</jnlp>
À essayer
console> javaws http://jfod.cnam.fr/jnews/jsubmitter.jnlp console> javaws -viewer
NSY10229
Déchargement de classe
• Impossible – Bootstrap, Extension et Application
• Possible si– Création d’un nouveau chargeur– Mais attention aux références du programme …
• Ou ayez confiance envers le ramasse-miettes
NSY10230
Conclusion intermédiaire
• Chargeur dynamique de classe– Instance comme les autres– Gérée par le ramasse miettes
• La suite :
– Une pause/démonstration …
• jmx, jconsole • Une proposition de chargeur : un tp ?
NSY10231
Pause
• Combien de classes chargées pour dire « bonjour » toutes les secondes ? …
public class Bonjour{ public static void main(String[] args) throws Exception{ while(true){ System.out.println("bonjour"); Thread.sleep(1000); } }}
• Bonjour + jconsole = 1200 !!!
• Bonjour seule = 313 classes ! (JMX fait la différence …)
NSY10232
JMX, jconsole
NSY10233
Un exemple : la classe Chargeur de classe
• http://jfod.cnam.fr/NSY102/tp_classloader/tp_classloader.html
NSY10234
Exemple-suite : les fonctionnalités élémentaires…
public interface ChargeurDeClassesI{
public Class<?> chargerUneClasse(String nom)
throws Exception;
public ChargeurDeClassesI retirerUneClasse(String nom)
throws Exception;
public int nombreDeClassesChargees();
public Set<String> lesClassesChargees();
}
NSY10235
Exemple-suite : un usage
ClassLoadingMXBean classLoading = ManagementFactory.getClassLoadingMXBean();
classLoading.setVerbose(false);// true si vérification à la console
ChargeurDeClassesI cc = new ChargeurDeClassesImpl();
cc.chargerUneClasse("question1.A");
cc.chargerUneClasse("question1.C");// 2 classes chargées : A et C
ChargeurDeClassesI cc1 = cc.retirerUneClasse("question1.C");
cc=null; System.gc();
// 2 classes "déchargées" par le ramasse-miettes : A et C, de cc System.out.println("UnloadedClassCount() : " + classLoading.getUnloadedClassCount());
cc1.chargerUneClasse("question1.D"); System.out.println(" les Classes Chargees : " + cc1.lesClassesChargees());
NSY10236
Exemple-suite une mise à jour
// exemple d’une mise à jour
ChargeurDeClassesI unChargeur = new ChargeurDeClassesImpl();
unChargeur.chargerUneClasse("question1.A");
unChargeur.chargerUneClasse("question1.C");
unChargeur = unChargeur.retirerUneClasse("question1.A");
System.gc();
unChargeur.chargerUneClasse("question1.A"); System.out.println("UnloadedClassCount() : " + classLoading.getUnloadedClassCount());
NSY10237
Exemple-suite : une trace
• Avec classLoading.setVerbose(true); en mode bavard un extrait …
NSY10238
Critiques fondées
• Le déchargement d’une classe engendre une nouvelle instance d’un classloader !
– Apparenté « usine à gaz » …
• Si la classe déchargée est utilisée par d’autres classes ?– Retrait d’une classe mère, que deviennent les classes filles ?– Et les références sur la classe mère ?
• Factorisation du code ?, comment ?
• Mise à jour, déploiement …• Plug-in ?• Outil prédéfini ?• Canevas/Framework existant ?
• JSR 291 (Java Dynamic module) ? OSGi
NSY10239
OSGi
• Open Services Gateway Initiative • OSGi Alliance : marque déposée
– The OSGi Alliance à but non lucratif fondé en Mars 1999
• Consortium d’entreprises
• www.osgi.org
– Eclipse et ses plug-in– Spring– JBoss …
NSY10240
OSGi framework
• OSGi ?– Un canevas orienté service (SOA, Service Oriented Architecture)
– Chargement/déchargement de classes Java
– Dynamiquement,
– Dépendance des librairies, des services en fonction des versions .
• Pourquoi faire ?– Set top box, voiture, contrôle industriel, domotique … (au début 1999)– Gestion de serveurs/services à distance
– Administrable à distance• http, jmx, …
NSY10241
OSGi
• OSGi ou l’usage de classloader(s)– Chaque plug-in/bundle a son propre classloader
• Ses classes donc sont privées
– Le partage de classes est lié aux clauses d’import et d’export• Si la classe est importée le Bundle ira la chercher dans le ClassLoader
du bundle propriétaire si elle bien exportée• Un échange de classes contrôlé
– Extrait de www.osgi.org• An OSGi Framework is a network of class loaders that delegate by the package name. The class
loaders are parameterized by the manifest headers.
• Any dependencies between bundles are resolved by the OSGi Framework
• Notez que – La suite de ce support n’est qu’une brève introduction à OSGi– L’exemple est celui de javaworld http://www.javaworld.com/javaworld/jw-
03-2008/jw-03-osgi1.html
NSY10242
The OSGi Framework Architecture,
• Plusieurs applications se partagent une seule JVM– Application = Bundle
• Gestion du chargement de classe – Prise en compte de la version
• Communication inter-bundles prise en charge par OSGi
• Cycle de vie (install, start, stop, update, etc).– Voir Inversion de contrôle (souvenirs …)
• Sécurité– Stratégie fournie par les bundles
NSY10243
OSGi http://en.wikipedia.org/wiki/Image:Osgi_layer.png
NSY10244
OSGi est un SOA Service Oriented Architectures
• Séparation du contrat de l’implémentation
– Interface/implements
• Découverte à l’exécution des implémentations du contrat
• Composants réutilisables– Bundles
• Relation de dépendance des composants exprimée en contrats/interfaces
– Injection de dépendance
Service Contract
Componentprovides
uses
NSY10245
Bundle• Unité de déploiement• Une archive java et son manifest• C’est une directive du manifest qui autorisera l’import/export …
–figure extraite de http://dsrg.mff.cuni.cz/teaching/seminars/2002-05-07-Adamek-OSGi.pdf
NSY10246
Directives comme import export
• Bundle com.acme.a
• Import-Package javax.com• Export-Package javax.servlet
• Bundle com.elmer.fudd
• Import-Package javax.servlet• Export-Package javax.com
NSY10247
Graphe d’état du Bundle
INSTALLED
RESOLVED
UNINSTALLED
ACTIVE
STOPPING
STARTING
start
stop
• En pointillé : le FrameWork
install
uninstall
uninstall resolve
NSY10248
BundleActivator
• Un Bundle implémente BundleActivator, start, stop
public class UnBundle
implements BundleActivator{
public void start(BundleContext contexte){
…
}
public void stop(BundleContext contexte){
…
}
}
NSY10249
Un exemple de manifest
• Manifest-Version: 1.0• Bundle-ManifestVersion: 2• Bundle-Name: SensorActivator2• Bundle-SymbolicName: sensor.SensorActivator2• Bundle-Version: 1.0.0• Bundle-Vendor: NSY102• Bundle-Activator: SensorActivator• Import-Package: org.osgi.framework;version="1.3"
• Bundle-Name: et Bundle-SymbolicName: uniques
NSY10250
Le Bundle demande un service, SOA…
Un Service : une interface ici ServiceI;Peu importe l’implémentation et surtout peu importe le bundle fournisseur
public class UnBundleDemandeur implements BundleActivator{ private ServiceReference reference;
private ServiceI service;
public void start(BundleContext contexte){ reference = context.getServiceReference(ServiceI.class.getName()); service = (ServiceI) contexte.getService(reference);
}
public void stop(BundleContext contexte){ …}}
NSY10251
Le manifest
• Le fichier manifest contient la clause
• Import-Package: service, org.osgi.framework;version="1.3"
NSY10252
Le Bundle propose un service, SOA…
Un Service : une interface ServiceI, une implémentation ServiceImpl;
public class UnBundleFournisseur implements BundleActivator{
private ServiceRegistration registration;
public void start(BundleContext contexte){ ServiceI service = new ServiceImpl(); registration = context.registerService(ServiceI.class.getName(),
service, null);
}
public void stop(BundleContext contexte){ registration.unregister();
}
}
NSY10253
manifest
• Export-Package: service• Import-Package: org.osgi.framework;version="1.3"
NSY10254
Services : résumé et questions
• Les classloader s’échangent les classes/services
• Une directive du manifest–Export package
• Plusieurs implémentations du même service ?–Propriété SERVICE_RANKING
• Interrogation de la présence d’un service par critères ?– filtrage sur les propriétés installées par les services
• méthode de Bundle Context, interrogation du frame work•getServiceReferences("sensor.humidity", null);
– ( en syntaxe LDAP sensor=* …)
NSY10255
Le service s’appelle désiré
• Un Bundle désire être averti de la présence d’un service• Il suffit d’hériter de la classe ServiceTracker
–Création d’un listener, installation d’un filtre de notifications
•addingService•removedService
–la méthode addingService sera appelée à chaque ajout de service
–Voir • http://www.eclipsezone.com/eclipse/forums/t91059.rhtml
NSY10256
Gestion de versions intégrée
• A l’exécution, découverte du service le plus récent
• Le fichier manifest renseigne la version du service
• Update du bundle
NSY10257
BundleContext
public interface BundleContext {void addBundleListener(BundleListener listener);void addFrameworkListener(FrameworkListener listener);void addServiceListener(ServiceListener listener); void addServiceListener(ServiceListener listener, String filter); Filter createFilter(String filter);ServiceReference[] getAllServiceReferences(String clazz, String filter);Bundle getBundle();Bundle getBundle(long id);Bundle[] getBundles();File getDataFile(String filename); String getProperty(String key);Object getService(ServiceReference reference); ServiceReference getServiceReference(String clazz); ServiceReference[] getServiceReferences(String clazz, String filter); Bundle installBundle(String location); Bundle installBundle(String location, InputStream input); ServiceRegistration registerService(String[] clazzes,Object service,
Dictionary properties); ServiceRegistration registerService(String clazz, Object service,
Dictionary properties); void removeBundleListener(BundleListener listener); void removeFrameworkListener(FrameworkListener listener); void removeServiceListener(ServiceListener listener); boolean ungetService(ServiceReference reference);
}
NSY10258
The OSGi Implementations
• Open source implementations
– Apache Felix choisi pour les exemples
– Eclipse Equinox
– Gatespace Knopflerfish
• Felix : http://felix.apache.org/site/downloads.cgi• Voir http://www.aqute.biz/
NSY10259
Une Démonstration
• Hello, OSGi, Part 1 : Bundles for beginners – Javaworld Mars 2008
http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html
• avec felix, conteneur OSGi OpenSource– HelloActivator– HelloServiceActivator– HelloClientActivator– ….– …
– Le répertoire avec ces exemples est ici (le javaworld.jar est un projet bluej)• http://jfod.cnam.fr/NSY102/OSGI/
• Si besoin, voir les tutoriaux de D.Donsez et H. Cervantes pour l’installation de felix• http://www-adele.imag.fr/users/Didier.Donsez/cours/exemplesosgi/tutorialosgi.htm• http://www.humbertocervantes.net/osgitutorial/main.htm• http://oscar-osgi.sourceforge.net/tutorial/
NSY10260
Un bundle, (avec blueJ)
• La démonstration reflète cette présentation – http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html Part1– Voir Part2 par curiosité
• Avec bluej Le répertoire /lib/userlib/ contient felix.jar– Ou localement pour ce projet vous pouvez placer felix.jar dans le répertoire ./+libs/
1. Compilation et génération de l’archive sous bluej
2. Remplacement du fichier MANIFEST par le « bon » pour OSGi
3. Utilisation de felix
• Apprêtez-vous à modifier le fichier MANIFEST des archives !– Pratique sous windows avec WinRAR
NSY10261
Démonstration
• Avec felix
– install file:/h:/OSGi/HelloActivator.jar
– start XX
– ps
– update
– Projet bluej : javaworld.jar
NSY10262
Felix : installation, prémisse
• Avoir déballé l’archive• java -jar bin/felix.jar• Nom de profile : ici hello
– Persistance du framework entre deux exécutions
NSY10263
Prémisse suite, les bundles en place
• commande – ps
NSY10264
install start HelloWorld
• install file:/h:/osgi/HelloActivator.jar
• start 4
NSY10265
HelloActivator
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class HelloActivator implements BundleActivator{
public void start(BundleContext context){
System.out.println(" bonjour bonjour ");
}
public void stop(BundleContext context){
System.out.println(" au revoir ");
}
}
NSY10266
Le manifest
• Manifest-Version: 1.0• Bundle-ManifestVersion: 2• Bundle-Name: HelloActivator• Bundle-SymbolicName: HelloActivator• Bundle-Version: 1.0.0• Bundle-Vendor: NSY102• Bundle-Activator: HelloActivator• Import-Package: org.osgi.framework;version="1.3"
NSY10267
Les autres archives selon la même procédure
• HelloActivator1.jar• HelloActivator2.jar• HelloClientActivator.jar• HelloService.jar• HelloServiceTracker.jar
• Toujours extraites de l’article– http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html Part1– Lire la deuxième partie
• javaworld.jar l’archive bluej
NSY10268
Conclusion/discussion
• ClassLoader– Java Dynamic module– De bas niveau
• OSGi– SOA Service Oriented Architecture– Une plate-forme toute prête de chargement et déchargement– Gestion des versions
NSY10269
Annexe . Class
• Le fichier généré ".class"
• Utile/inutile ?
NSY10270
Le fichier généré ".class"
• Prémisses
• Format du fichier généré• Le constant pool• Informations sur l'interface(s) utilisée(s) par cette classe• Description des champs des variables de classe ou d'instances• Description des méthodes• Description de ce fichier
Table des symboles, sans choix d'implantation .
NSY10271
Prémisses
• Compatibilité binaire chapitre 13 Java Specification• Gestion de projets et internet• Quelles sont les contraintes de compatibilité binaire ?
• ? Peut-on ajouter de nouvelles méthodes ou variables d'instance d'une classe tout en garantissant l'exécution d'une application antérieure ?
Forme symbolique du .class
NSY10272
Prémisses
• ajout de nouveaux champs• ajout de nouvelles classes dans un package• modification du type de déclaration• modification du graphe d'héritage• ...
Forme symbolique du .class
NSY10273
Format du ".class" : description informelle
• ClassFile { – u4 magic; – u2 minor_version; – u2 major_version; – u2 constant_pool_count;– cp_info *constant_pool;– u2 access_flags;– u2 this_class;– u2 super_class;– u2 interfaces_count;– u2 *interfaces;– u2 fields_count;– field_info *fields;– u2 method_count;– method_info *methods;– u2 attributes_count;– attribute_info *attributes;
}
Entête du fichier
Symboles et signatures
"type" de la classe, son nom,le nom de la super-classe
les interfaces
Variables de la classe ou d'instances
Les méthodes de classe ou d’instances
Description de ce fichier
NSY10274
Entête
• 0xCAFE 0xBABE• 3• 45
Vérification de la Compatibilité
NSY10275
Le constant_pool
• cp_info *constant_pool;• typedef struct {• u1 tag;• u1 *info;• }cp_info;
• Exemple : si pool_constant[i] est un entier
alors pool_constant[i].tag == 3);
pool_constant[i]->info == valeur de cet entier
#define CONSTANT_Class 7#define CONSTANT_Fieldref 9#define CONSTANT_Methodref 10#define CONSTANT_String 8#define CONSTANT_Integer 3#define CONSTANT_Float 4#define CONSTANT_Long 5#define CONSTANT_Double 6#define CONSTANT_InterfaceMethoderef 11#define CONSTANT_NameAndType 12#define CONSTANT_Asciz 1#define CONSTANT_Utf8 1
typedef struct{ u1 tag; u4 bytes; }CONSTANT_Integer_info;
u1 : un octet, u4 : 4 octets
NSY10276
Un exemple « primitif »
class bulbe{
public static void main( String args[]){
int [] n = new int[6];
n[0]=0;n[1]=2;n[2]=1;n[3]=3;n[4]=4;n[5]=1;
boolean sorted = false;
while(!sorted){
sorted = true;
for(int i = 0; i < 5; i++){
if (n[i] > n[i + 1]){
int temp = n[i];
n[i] = n[i + 1];
n[i + 1] = temp;
sorted = false;
}
}
}}}
NSY10277
Un exemple de constant_pool
pool_count : 31[ 1] tag: 7 name_index: 9[ 2] tag: 7 name_index: 20[ 3] tag: 10 class_index: 2 name_and_type_index: 4[ 4] tag: 12 class_index: 24 descriptor_index: 28[ 5] tag: 1 length: 4 this[ 6] tag: 1 length: 1 Z[ 7] tag: 1 length: 13 ConstantValue[ 8] tag: 1 length: 7 Lbulbe;[ 9] tag: 1 length: 5 bulbe[10] tag: 1 length: 18 LocalVariableTable[11] tag: 1 length: 4 temp[12] tag: 1 length: 10 Exceptions[13] tag: 1 length: 10 bulbe.java[14] tag: 1 length: 15 LineNumberTable[15] tag: 1 length: 1 I[16] tag: 1 length: 10 SourceFile[17] tag: 1 length: 14 LocalVariables[18] tag: 1 length: 4 Code[19] tag: 1 length: 4 args[20] tag: 1 length: 16 java/lang/Object[21] tag: 1 length: 4 main
NSY10278
Suite du constant_pool
• [22] tag: 1 length: 22 ([Ljava/lang/String;)V• [23] tag: 1 length: 4 trie• [24] tag: 1 length: 6 <init>• [25] tag: 1 length: 6 sorted• [26] tag: 1 length: 1 n• [27] tag: 1 length: 2 [I• [28] tag: 1 length: 3 ()V• [29] tag: 1 length: 1 i• [30] tag: 1 length: 19 [Ljava/lang/String;
• pool_constant[0] est réservé
Forme symbolique du .class …
NSY10279
access_flag, this_class, super_class
• #define ACC_PUBLIC 0x0001 • #define ACC_FINAL 0x0010 • #define ACC_SUPER 0x0020 /* obsolète */• #define ACC_INTERFACE 0x0200 • #define ACC_ABSTRACT 0x0400
• this_class– Indice dans le constant_pool, (nom de la classe) Indice 1 pour l'exemple ( tag 7)
• super_class– Indice dans le constant_pool, (nom de la super classe), Indice 2 pour l'exemple ( tag 7) soit java/lang/Object
NSY10280
field_info
• typedef struct{• u2 access_flags;• u2 name_index; /* indices */• u2 descriptor_index; /* dans le constant_pool */• u2 attributes_count;• ConstantValue_attribute *attributes;• }field_info;
• typedef struct{• u2 attribute_name_index;• u4 attribute_length;• u2 constantvalue_index;• } ConstantValue_attribute;
NSY10281
Lecture des descripteurs de "Field"
• FieldType ::= BaseType | ObjectType | ArrayType• BaseType
• B byte• C char• D double• F float• I int• J long• S short• Z boolean
• ObjectType• L<classname>;
• ArrayType• [ table
Exemples :double m[] [] --> [[D
Strings args[] --> [Ljava/lang/String;
NSY10282
Field
• Fields– recense tous les champs d'une classe– Statiques
• fields[i].access_flag & ACC_STATIC == ACC_STATIC
– ou locaux à chaque instance
– Note d'implantation :• Les types B,C,F,I,L et [ occupent un mot machine (32 bits)• Les types D et J occupent 2 mots
NSY10283
method_info
• typedef struct{• u2 access_flags;• u2 name_index;• u2 descriptor_index;• u2 attributes_count;• Code_attribute *attributes;• }method_info;
NSY10284
method_info.Code_attribute
• typedef struct{• u2 start_pc;• u2 end_pc;• u2 handler_pc;• u2 catch_type;• } exception_info;
• typedef struct{• u2 attribute_name_index;• u4 attribute_length;• u2 max_stack;• u2 max_locals;• u4 code_length;• u1 *code;• u2 exception_table_length;• exception_info *exception_table;• u2 attributes_count;• attribute_info *attributes;• } Code_attribute;
NSY10285
Sur l'exemple
• method_count: 2• method.access_flags: 0x9 /* c’est la méthode main */• method.name_index: 21• method.descriptor_index: 22• method.attributes_count: 1• attribute_name_index: 18• attribute_length: 297• code : 10,6,bc,a,........3e,b1, /* le byte code 297 octets */
• Soit dans le constant_pool [18] tag: 1 length: 4 Code [21] tag: 1 length: 4 main [22] tag: 1 length: 22
([Ljava/lang/String;)V
•
NSY10286
Lecture des descripteurs de "method"
• MethodDescriptor ::= ( FieldType *) ReturnDescriptor• ReturnDescriptor ::= FieldType | V
• V si le type retourné est void
Exemples :Object m(int i, double d, Thread T)--> (IDLjava/lang/Thread;)Ljava/lang/Object;
void main( String args[]) --> ([Ljava/lang/String;)V
NSY10287
méthodes d'initialisation
• <init>V– Constructeur par défaut de chaque instance– Sur l'exemple "bulbe.<init>V" est bien présent
• <clinit>V– méthode d'initialisation d'une classe (bloc static)– exécutée une seule fois au chargement de celle-ci
NSY10288
method_info.Code_attribute.attributes
• typedef struct{• u2 attribute_name_index;• u4 attribute_length;• u2 line_number_table_length;• line_number_info
*line_number_table;• }LineNumberTable_attribute;
• --> informations destinées au débogueur symbolique
NSY10289
ClassFile.attributes
• typedef struct{• u2 attribute_name_index;• u4 attribute_length;• u2 sourcefile_index;• } SourceFile_attribute;
• Sur l'exemple• analyse de 'attributes'• attributes_count: 1• source_attribute.name_index : 16• source_attribute.length : 2• source_attribute.sourcefile_index : 13
constant_pool[13] tag: 1 length: 10 bulbe.java[16] tag: 1 length: 10 SourceFile
NSY10290
Pause …
Forme symbolique du .class
• Usage d’un décompilateur du « .class » en « .java »– Par exemple
• http://www.kpdus.com/jad.html• http://members.fortunecity.com/neshkov/dj.html
• Obfuscator– Par exemple
• http://proguard.sourceforge.net/
NSY10291
Avant - Après
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
class bulbe{
bulbe(){ }
public static void main(String args[]) { int ai[] = new int[6]; ai[0] = 0;ai[1] = 2;ai[2] = 1; ai[3] = 3;ai[4] = 4;ai[5] = 1; boolean flag = false; while(!flag){ flag = true; int i = 0; while(i < 5) { if(ai[i] > ai[i + 1]) { int j = ai[i]; ai[i] = ai[i + 1]; ai[i + 1] = j; flag = false; } i++; }}}}
class bulbe{
public static void main(String args[]){
int [] n = new int[6];
n[0]=0;n[1]=2;n[2]=1;
n[3]=3;n[4]=4;n[5]=1;
boolean sorted = false;
while(!sorted){
sorted = true;
for(int i = 0; i < 5; i++){
if (n[i] > n[i + 1]){
int temp = n[i];
n[i] = n[i + 1];
n[i + 1] = temp;
sorted = false;
}
}
}}}
NSY10292