24 décembre 2007

Quelle est la différence entre ClassNotFoundException et NoClassDefFoundError

En tant que développeurs Java, nous avons tous rencontré ces deux exceptions. Ceci dit, elles sont souvent confondues, car elles signalent toutes les deux qu'une classe n'a pu être chargée.
Premièrement, ClassNotFoundException est une Exception alors que NoClassDefFoundError est de type Error.

D'après la javadoc ClassNotFoundException est renvoyée lorsqu'une application essaye de charger dynamiquement une classe à travers son nom, en utilisant entre autre la méthode Class.forName(), mais la classe n'est pas trouvée dans le CLASSPATH.

Exemple

Soit la classe suivante :

public class A {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("ClasseQuiNexistePas");
}
}

Son exécution prévoquera l'exception suivante :


Exception in thread "main" java.lang.ClassNotFoundException: ClasseQuiNexistePas
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at A.main(A.java:6)



NoClassDefFoundError est renvoyée lorsque une Classe A ne trouve pas une autre classe B delaquelle elle dépend, alors qu'au moment de la compilation la classe B est présente.

Exemple
Soit les deux classes A et B :

class A {
public static void main(String[] args) {
B b = new B();
}
}

public class B { }


Compilez les deux classes, ensuite supprimer le fichier B.class et lancer la classe A (java A)

Résultat

Exception in thread "main" java.lang.NoClassDefFoundError: B
at test2.A.main(A.java:6)

5 juillet 2007

Transactions Distribuées en dehors d’un container Java EE

Il est possible d'utiliser les transactions distribuées en dehors d'un serveur d'application Java EE, par exemple dans Tomcat ou dans une application Java autonome, et ce, grâce à des implémentations JTA telles que JBossTS, Atomikos ou Bitronix Transaction Manager.

21 mai 2007

Trouver l’explication d’une erreur Oracle

Si vous êtes en face d'un code erreur de la base de données Oracle (de type ora-XXXXX), tapez le nom d'erreur en tant qu'un sous domaine du site ora-code.com et vous aurez le texte expliquant la cause de l'erreur.

Par exemple, pour le code erreur ora-00906 le lien est http://ora-00906.ora-code.com.

Il y a même une rubrique qui indique l'action a entreprendre pour régler le problème. ça peut servir ....

21 mars 2007

Ericsson sort son “Mobile JSF Kit”

Ericsson vient d'annoncer la disponibilité de son "Mobile JSF Kit". C'est un kit de développement constitué d'une nouvelle bibliothèque JSF,nommée MobileFaces, de la documentation et d'exemples d'utilisation.

D'après la présentation accompagnant ce Kit, MobileFaces est une surcouche de JSF compatible avec n'importe quelle implémentation de JSF. Le framework détecte le type de client(mobile ou pc) et fait le rendu en conséquence (cf. schéma, source Ericsson). Il également noté que MobilesFaces est open source mais je n'ai pas vu de licence qui le confirme.

JSF s'étend désormais aux mobiles et tien donc ses promesses! Reste à vérifier à tester la qualité de cette bibilothèque.

Vous pouvez télécharger le Mobile JSF Kit ici
, mais il faut s'enregistrer au préalable.

17 mars 2007

Le Value Object

L'une des utilité des designs patterns est d'avoir un langage commun entre les développeurs,
ce n'est malheureusement pas le cas pour le pattern Value Object qui est souvent utilisé dans des contextes différents,
le rendant ainsi sujet à diverses interprétations.Dans un contexte J2EE, Value Object est synonyme de Data Transfert Object,
alors que dans un contexte Programmation Orienté Objet, il a une tout autre signification.Le but de cet article est de faire la lumière sur les Value Objects en donnant une définition claire et non ambiguë et en expliquant l'origine de la confusion.
Dans un modèle de domaine reposant sur les Pojos, on retrouve les entités métiers qui sont caractérisées par leur identité, lorsque l'entité est persistée à l'aide d'un ORM tel que Hibernate ou JDO, son identité correspond généralement à la clé primaire. D'un autre coté, on retrouve aussi des objets, simples, qui sont cette fois-ci, caractérisés par leur valeur et non par leur identité : ce sont les Value Objects.

Quel est le rôle des Values Object dans le modèle objet ?

Comme je l'ai précisé plus haut, un value object est un objet qui est définit par la valeur de ces attributs, cela veut dire que deux instances qui ont les même valeurs sont égales et interchangeables.
Le rôle principal d'un value object est d'encapsuler des données plutôt que de fournir un comportement.

Exemples

Prenons l'exemple d'une tâche désigné par l'objet Tache, dont l'intervalle d'exécution est représenté par l'objet Intervalle. L'objet Intervalle a deux attributs dateDebut et dateFin, et il est possible de retarder une tâche d'un certain nombre de jours grâce à la méthode retarder(int nbrJours).



L'objet Intervalle est un value object, car il est centré sur les données (dates de début et de fin de l'exécution de la tâche) et il n'a pas un vrai comportement.
Si je veux, par exemple, savoir si deux tâches ont le même intervalle d'exécution, j'écrirai de façon intuitive le code suivant :
if (tache1.getIntervalle().equals(tache2.getIntervalle())) {

faireQuelqueChose();

}

Il y a des exemples connus de values object. On retrouve, hormis l'intervallede temps, un salaire, une Somme d'argent, une adresse, etc. Dans l'API standard de Java, les objets String, Integer et tous les objets représentant les types primitifs sont considérés comme des values objets.

Propriétés des values objects

1 Un value object doit surcharger les méthodes equals() et de hashcode()
Les méthodes equals() et hashcode() permettent de dire si deux instances sont égales. Par défaut, elles sont calculées sur la base de l'adresse mémoire de l'objet.

Pour les values objects ces deux méthodes sont basées sur les valeurs de attributs de l'objet.
En parallèle, les méthodes equals() et hashcode() des entités métier persistantes sont basées sur les valeurs des attributs constituant la clé primaire.
2 Un value object doit être immuable
Un object value doit être immuable et ce pour éviter le phénomène de « l'aliasing ». Un aliasing se produit dans le cas suivant :
A et B partagent une propriété x, si B modifie x alors cette modification se répercute sur l'objet A, ce qui provoque des effets indésirables. Voici un exemple concret repris de [1] :

La méthode retarder() permet de retarder une tâche un certain nombre de jours :
void retarder(int nbrJours) {
this.intervalle.setDateDebut(this.intervalle.getDateDebut() + nbrJours);
}

Quel est le problème dans le code suivant ?

Tache tache1 = new Tache();

Tache tache2 = new Tache();

tache1.setIntervalle(new Intervalle("4 mars 2007", "29 mars 2007");

tache2.setIntervalle(tache1.getIntervalle());

tache2.retarder(5);

En observant le code attentivement, on remarque que la tache1 a également été retardée de cinq jours, et ce de manière totalement inaperçue et involontaire!

Pour corriger l'exemple précédent, on interdit la modification des attributs de l'objet, et on créé à la place un nouvel objet avec les nouvelles valeurs. La méthode retarder() deviendrait :
void retarder(int nbrJours) {
this.intervalle = new Intervalle(this.intervalle.getDateDebut() + nbrJours);
}
Sachez enfin, que rendre un objet immuable a des propriétés intéressantes, notamment le partage du même objet entre plusieurs threads sans recourir à la synchronisation. Elles rendent le design robuste et améliorent les performances [2][3].

On comprend maintenant pourquoi, par exemple, la classe java.lang.String est immuable. En effet, une fois l'objet créé il n'est plus modifiable, il peut être partagée sans aliasing et sans aucun problème de multi-threading car les méthodes telles que substring() ou concat() retournent toujours un nouvel objet.
3 Un value object peut être persisté sous certaines conditions
Bien entendu, un value object peut être persisté. Cependant, il ne doit pas correspondre à une ligne entière dans une table [4]. Les colonnes qui correspondent à ses attributs, s'ajoutent aux colonnes d'une entité persistante. Hibernate offre cette possibilité via le mécanisme de component [5].

Pourquoi la confusion entre un value object et un DTO

Pour rappel, un Data Transfert Object est utilisé dans les architectures distribuées, pour transporter les données entre la couche cliente et la couche métier (représentée par des EJB). Le but est de recevoir et d'envoyer un paquet de données (DTO) en un seul appel plutôt que des faire de multiples appels distants très coûteux en performance. Le seul point commun entre un value object et un DTO c'est qu'ils sont tous les deux centrés sur les données.
L'origine de la confusion vient, en réalité, des premières versions des J2EE Core patterns de sun. En effet, en 2001 le DTO était appelé Value Object. Il ne l'est plus maintenant fort heuresement!

Références

26 février 2007

Lambda Probe, une console d’administration pour Tomcat

J'ai récemment découvert un outil de monitoring et de gestion pour le serveur d'application Apache Tomcat, il se nomme Lambda Probe.L'outil est riche en fonctionnalités mais il se distingue aussi par son interface agréable.

Enfin, si vous voulez vous forger une opinion, vous pouvez essayer la démo sur le site http://lambdaprobe.org/.

Bonne nouvelle! J'ai testé Lambda Probe sur JBoss 4.0.2, ça marche et ça nous change de la JMX-Console!

17 février 2007

Woodstock : Un nouvel arrivant dans la famille des Composants JSF

D'après ici et Sun rend publique et Open Source un projet de Composants JSF/Ajax nommé Woodstock. La version actuelle est la 4.0.1, elle repose sur JSF 1.2Apparament cette bibliothèque est utilisée dans la console d'administration de GlassFish v2 M4