JBoss/Migration

L'objectif de cet article n'est pas de fournir un guide de migration (pour cela, cf la documentation JBoss), mais plutôt de partager une expérience de migration vers JBoss 7.0.2.

Répertoire de déploiement

L'application que je migre me sert de support pour les exercices d'une formation JPA. Je n'ai donc pas besoin d'une configuration JBoss évoluée et je garde la configuration par défaut proposée par Eclipse, à savoir "standalone".

Configuration de la data source

La configuration des data sources est assez différentes des versions antérieures de JBoss.

Pour commencer, il faut installer le driver JDBC, dans mon cas celui de MySQL. Deux possibilités : soit on installe le driver dans le répertoire de déploiement, soit on l'installe comme module. J'opte pour la seconde option, bien que la première solution soit plus simple. A cette fin, il faut copier le driver mysql-connector-java-5.1.18-bin.jar dans le répertoire AS7_HOME/modules/com/mysql/main (le répertoire AS7_HOME/modules/com existe déjà, il faut créer le sous-répertoire mysql/main). Dans ce répertoire on ajoute aussi le fichier module.xml :

	<?xml version="1.0" encoding="UTF-8"?>
	<module xmlns="urn:jboss:module:1.0" name="com.mysql">
 	  <resources>
		<resource-root path="mysql-connector-java-5.1.18-bin.jar"/>
	  </resources>
	  <dependencies>
		<module name="javax.api"/>
		<module name="javax.transaction.api"/>
	  </dependencies>
	</module>

Dans un deuxième temps, on déclare la data source dans le fichier standalone.xml situé dans le répertoire AS7_HOME/standalone/configuration.

On ajoute la déclaration de la data source dans l'élément <datasources> existant (par défaut, une datasource H2 est déjà configurée) :

	<datasource jndi-name="java:jboss/datasources/LibrairieDS" pool-name="LibrairieDS" enabled="true" jta="true" use-java-context="true" use-ccm="true">
		<connection-url>
			jdbc:mysql://localhost:3306/librairie
		</connection-url>
		<driver>
			com.mysql
		</driver>
		<transaction-isolation>
			TRANSACTION_READ_COMMITTED
		</transaction-isolation>
 		<pool>
			<prefill>
				false
			</prefill>
			<use-strict-min>
				false
			</use-strict-min>
			<flush-strategy>
				FailingConnectionOnly
			</flush-strategy>
		</pool>
 		<security>
 			<user-name>
 				myuser
 			</user-name>
 			<password>
 				mypassword
 			</password>
  		</security>
  	</datasource>
               

Il faut aussi déclarer le driver MySQL dans l'élément <drivers> existant (juste en dessous de <datasources>) :

	<driver name="com.mysql" module="com.mysql">
		<xa-datasource-class>
			com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
		</xa-datasource-class>
	</driver>

Le fichier persistence.xml

Le nom de la data source déclarée a évolué pour être en conformité avec les standards de nommage JEE6 (avec JBoss 6, j'utilisais le nom jdbc/LibrairieDS). Je dois donc changer ce nom dans le fichier de configuration JPA :

	<jta-data-source>java:jboss/datasources/LibrairieDS</jta-data-source>

Lookup entity manager

Je profite de cette migration pour adapter aux normes JEE 6 les noms de référence au PU démarré automatiquement par le serveur (ajout du préfixe "persistence" dans le nom). Je modifie donc le fichier web.xml :

Entity manager factory :

	<persistence-unit-ref>
		<persistence-unit-ref-name>persistence/librairie-emf</persistence-unit-ref-name>
		<persistence-unit-name>librairie</persistence-unit-name>
	</persistence-unit-ref>

Entity manager :

	<persistence-context-ref>
		<persistence-context-ref-name>persistence/librairie-em</persistence-context-ref-name>
		<persistence-unit-name>librairie</persistence-unit-name>
	</persistence-context-ref>

Lookup entity manager factory :

	InitialContext ctx = new InitialContext();
	EntityManagerFactory emf = (EntityManagerFactory) ctx.lookup("java:comp/env/persistence/librairie-emf");

Lookup entity manager :

	InitialContext ctx = new InitialContext();
	EntityManager em = (EntityManager) ctx.lookup("java:comp/env/persistence/librairie-em");

Désactivation Envers

JBoss 7.0.2 fonctionne avec Hibernate 4.0 CR2 qui active le framework Envers par défaut, même si l'applicatif ne l'utilise pas (pas d'annotation Envers dans mon code). J'avais donc une erreur au déploiement de l'application, du fait des tables spécifiques Envers manquantes dans ma base de données. Je désactive donc Envers dans persistence.xml en ajoutant la propriété suivante :

 <property name="hibernate.listeners.envers.autoRegister" value="false"/>

Commons logging

Afin d'éviter un ClassNotFoundException sur les classes de commons-logging lors du déploiement, j'ajoute la ligne suivante dans le fichier MANIFEST.MF des modules concernés :

 Dependencies: org.apache.commons.logging

Modification de l'EAR

Dans l'application que j'utilise à des fins de TP, je déploie des composants de service métier de différentes façons. Dans un premier temps, ces composants sont simplement instanciés dans la couche cliente (un backing bean JSF). Dans un deuxième temps, les composants sont déployés sous la forme d'EJB. Avec JBoss 6, le jar qui contient ces composants pouvait être placé à la racine de l'EAR, quelle que soit l'option retenue (EJB ou pas EJB). Ce n'est pas conforme aux standards quant à la structure de l'EAR, mais JBoss 6 le tolère, et c'était bien pratique. Avec JBoss 7, plus de tolérance : les jar EJB doivent être placés à la racine de l'EAR, et les jar non EJB doivent être situés dans le sous répertoire lib.