vendredi 28 octobre 2011

Knowledgeblackbelt


Si vous souhaitez valider vos connaissances en Java, il existe un autre moyen que la certification.
Il s'agit de Knowledgeblackbelt.
Le principe est simple : vous passez des examens et si vous réussissez vous obtenez des points et ces points vous permettent d'obtenir des ceintures.
L'avantage c'est qu'il y a beaucoup d'examens (JAVA SE, Design Pattern, JPA ...).Un autre avantage, c'est qu'il y a des cours encadrés par un coach.Ainsi, vous pouvez poser pleins de questions !


mercredi 24 août 2011

The content of element type must match

Problem :

J'ai eu l'erreur suivante :
The content of element type "filter" must match  "(icon?,filter-name,display-name?,description?,filter-class,init-param*)".

Voici un extrait du fichier web.xml :
<filter> 
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class> 
</filter> 


Solution :

En faite, la solution est dans le message.On doit déclarer les balises de  filter-mappings dans un certain ordre.
Il faut mettre en premier filter-name puis url-pattern ou servlet name.
So you have to correct like that :

<filter> 
    <filter-name>richfaces</filter-name>
    <display-name>RichFaces Filter</display-name>   
    <filter-class>org.ajax4jsf.Filter</filter-class> 
</filter> 

Une remarque importante :

Cette erreur est apparue car j'avais mis dans le fichier web.xml la dtd 2.3 :

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

Cependant, il ne s'agit pas de la dernière dtd. Apparement, pour corriger l'erreur, il faut écrire le début de son web.xml comme ceci :


<?xml version="1.0"?>
<web-app version="2.5" 
     xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

vendredi 19 août 2011

GWT et Eclipse : Unable to find a module

Problème :

Lors du lancement de mon application, j'ai l'erreur suivante :


Loading modules
   de.toolforge.googlechartwrapper.googlechartwrapper
      [ERROR] Unable to find 'de/toolforge/googlechartwrapper/googlechartwrapper.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?
[ERROR] shell failed in doStartup method

Cependant, je n'ai aucune référence à ce module dans mon code (C'est un module que j'ai effacé).

Solution :

Run -> Run Configurations
Puis il faut aller dans votre application google dans l'onglet Arguments.

Il faut ensuite effacer le module qui pose problème.Dans mon cas :   de.toolforge.googlechartwrapper.googlechartwrapper

jeudi 18 août 2011

GWT : Erreur de compilation avec une Map



Problème :

Dans votre code, vous déclarez Map&lt;Integer, Integer&gt; map = new HashMap&lt;Integer, Integer&gt;
et lors de la compilation vous avez l'erreur suivante :

         [ERROR] Line 23: No source code is available for type com.google.gwt.dev.util.collect.HashMap&lt;K,V&gt;; did you forget to inherit a required module?


Solution :

Les collections du tpe Map fonctionne avec des Objects.Or la class Object n'est pas serializable.
Il faut donc créer une classe qui va contenir votre map en lui passant @gwt.typeArgs &lt;java.lang.Integer,java.lang.Integer&gt;
dans les commentaires pour définir ce que va contenir votre map :


public class ChartData implements IsSerializable {


 /**
  * This field is a Map that must always contain Strings as its keys and
  * values.
  * 
  * @gwt.typeArgs &lt;java.lang.Integer,java.lang.Integer&gt;
  */
 public Map data;
 
 public ChartData() {
 }
}


Ensuite vous pouvez utiliser votre map comme ceci :

CharData charData = new CharData();
charData.data.put(12,13);

Référence :
http://www.gwtapps.com/doc/html/com.google.gwt.doc.DeveloperGuide.RemoteProcedureCalls.SerializableTypes.html

mardi 16 août 2011

[WARN] Candidate class for JDOQL single-string query (Class) could not be resolved Class



Problème :

[WARN] Candidate class for JDOQL single-string query (User) could not be resolved User

Solution :

Je n'avais pas encore instancié ma classe User.En fait, J'appelais ma méthode avec une fonction statique comme ceci :
User.myMethod();

Et dans my Method, je faisais ma requête :


PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(User.class);


Pour résoudre le problème, j'ai fait ceci :


User myUser = new User();
myUser.myMethod(); // myMethod n'est plus statique

vendredi 12 août 2011

Comment logger avec GWT ?


Dans votre fichier test.gwt.xml file, il faut ajouter :

 &lt;inherits name="com.google.gwt.logging.Logging"/&gt;
  &lt;set-property name="gwt.logging.logLevel" value="INFO"/&gt;          # To change the default logLevel
  &lt;set-property name="gwt.logging.enabled" value="TRUE"/&gt; 

Dans votre fichier java :

  • Import du logger :

import java.util.logging.Logger;

  • Déclaration de la variable logger :

private static final Logger logger = Logger.getLogger(WeightManager.class.getName());

  • Appel des méthodes de logs :

logger.info("========&gt;TEST !!!!");




Remarque : Cela fonctionne uniquement dans la partie client.Je ne sais pas encore comment faire des logs dans la partie server.

dimanche 7 août 2011

JBOSS 7 et JEE 6 un bon moyen de mettre à jour ses connaissances


Si vous souhaitez tester les nouveautés de JEE6 de manière simple et rapide, je vous conseil de télécharger JBOSS 7 et les exemples de la documentation (appli hello world, login ...).La documentation est bien faite et en plus vous utiliserez Maven 3.

vendredi 5 août 2011

Java 7 disponible pour le plugin compiler de Maven




Ce matin j'ai essayé de compiler mon projet avec Maven et le jdk7 et cela marche !



mercredi 3 août 2011

Bug sur Java 7


En ce moment, on parle beaucoup d'un bug sur Java 7 et la communauté s'enflamme un peu.Je suis tombé sur un commentaire qui résume tout  :

- oui java 7 est buggé sur l’optimisation des boucles
- oui cela pose problème avec lucene et surement quelques autres projets
- non il ne faut pas évité java 7 a tout prix
- oui il faut être prudent et attendre avant une migration en prod et cela vaut pour toutes nouvelles versions d’un produit
- oui il est possible de désactiver les optimisation pour retrouver un java 7 non buggé.
http://www.infoq.com/news/2011/08/java7-hotspot

ref : http://www.silicon.fr/victime-de-bugs-handicapants-java-7-est-rejete-par-la-communaute-apache-57691.html

dimanche 31 juillet 2011

Java 7 Effets de bords avec WatcherService ?


Je test Java 7 en ce moment et je suis tombé sur un comportement inattendu en suivant le tutoriel 

J'ai fait les étapes suivantes :
mkdir ~/tmp
touch ~/tmp/toto

Puis j'ai regardé les évènements produits dans ~/tmp/toto et cela fonctionne bien (Si je crée un fichier, j'ai bien l' évènement CREATED).

Puis j'ai fait cela :

mv ~/tmp ~/tmp.old
touch ~/tmp.old/titi

J'ai regardé si il y avait des évènements et il y en avait ! Hors c'est le répertoire que je venais de mover donc je m'attendais plutôt à une exception envoyée par la méthode reset() !
J'ai pris mon courage à deux mains et j'ai posté un message sur le site d'Oracle ...


Voici l'exemple du blog d'Oracle:
for (;;) {

    //wait for key to be signaled
    WatchKey key;
    try {
        key = watcher.take();
    } catch (InterruptedException x) {
        return;
    }

    for (WatchEvent event: key.pollEvents()) {
        WatchEvent.Kind kind = event.kind();

        //This key is registered only for ENTRY_CREATE events,
        //but an OVERFLOW event can occur regardless if events are
        //lost or discarded.
        if (kind == OVERFLOW) {
            continue;
        }

        //The filename is the context of the event.
        WatchEvent ev = (WatchEvent)event;
        Path filename = ev.context();

        //Verify that the new file is a text file.
        try {
            //Resolve the filename against the directory.
            //If the filename is "test" and the directory is "foo",
            //the resolved name is "test/foo".
            Path child = dir.resolve(filename);
            if (!Files.probeContentType(child).equals("text/plain")) {
                System.err.format("New file '%s' is not a plain text file.%n", filename);
                continue;
            }
        } catch (IOException x) {
            System.err.println(x);
            continue;
        }

        //Email the file to the specified email alias.
        System.out.format("Emailing file %s%n", filename);
        //Details left to reader....
    }

    //Reset the key -- this step is critical if you want to receive
    //further watch events. If the key is no longer valid, the directory
    //is inaccessible so exit the loop.
    boolean valid = key.reset();
    if (!valid) {
        break;
    }
}

dimanche 24 juillet 2011

cvc-complex-type.2.4.a: Invalid content was found starting with element 'display-name'.

Problème :

cvc-complex-type.2.4.a: Invalid content was found starting with element 'display-name'. One of '{"http://java.sun.com/xml/ns/javaee":servlet-class, "http://java.sun.com/xml/ns/javaee":jsp-file}' is 
 expected.

Dans Eclipse, j'ai la balise display-name souligné en rouge:

web.xml :
   <servlet>
<servlet-name>monitor</servlet-name>
<display-name>monitor</display-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/monitor-servlet.xml</param-value>
    </init-param>
<load-on-startup>1</load-on-startup>
   </servlet>

Solution:

Il faut mettre la balise display-name en premier :

   <servlet>
<display-name>monitor</display-name>  
<servlet-name>monitor</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/monitor-servlet.xml</param-value>
    </init-param>
<load-on-startup>1</load-on-startup>
   </servlet>

Remarque : Sur mon projet google : http://code.google.com/p/lin-mon-webapp/, j'ai commité un fichier web;xml sans erreur de validation (J'ai pu le vérifier en faisant validate dans Eclipse).

lundi 18 juillet 2011

java.lang.ClassNotFoundException: javax.faces.FacesException

Problème :

Dans JBoss 6.0.0, lorsque je déploie mon war, j'ai l'exception suivante :

java.lang.ClassNotFoundException: javax.faces.FacesException

Solution :

J'ai ajouté la dépendance Maven suivantes pour résoudre le problème :


<dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.0.0-Beta2</version> </dependency>

vendredi 15 juillet 2011

Créer une database avec un utilisateur


Un simple pense bête de commande Mysql...

mysql>mysql -u root
mysql>create database db;
mysql>GRANT ALL ON db.* TO 'integration'@'localhost' IDENTIFIED BY 'integration';
mysql>GRANT ALL ON db.* TO 'integration'@'%' IDENTIFIED BY 'integration';
mysql>flush privileges;
mysql>quit

Ensuite on peut se connecter en localhost ou d'une IP :
mysql -u integration -p 
mysql -u integration -h 127.0.0.1 -p

jeudi 7 juillet 2011

java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener

Problème :

Dans JBoss 6.0.0, lorsque je déploie mon war, j'ai l'exception suivante :

java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener 

Solution :

J'ai ajouté les dépendances Maven suivantes pour résoudre le problème :


<dependency>
 <groupId>com.sun.faces</groupId>
 <artifactId>jsf-impl</artifactId>
 <version>2.0.0-Beta2</version>
</dependency>
<dependency>
 <groupId>com.sun.faces</groupId>
 <artifactId>jsf-impl</artifactId>
 <version>2.0.0-Beta2</version>
</dependency>

lundi 4 juillet 2011

ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory

Problème :

Lorsque je déploie mon war dans JBoss 6.0.0, j'ai l'erreur suivante :

java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory

Voici un extrait de mon fichier Maven pom.xml :

   <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-annotations</artifactId>
     <version>3.4.0.GA</version>
     <exclusions>
       <!-- Exclude Commons Logging in favor of SLF4j -->
       <exclusion>
         <groupId>org.apache.commons</groupId>
         <artifactId>com.springsource.org.apache.commons.logging</artifactId>
       </exclusion>
   </dependency>


Solution :

Il faut exclure xml-apis car il y a un conflit avec des librairies déjà présente (xeres-impl).
Il faut donc exclure xml-apis de notre war comme ceci :

     <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-annotations</artifactId>
     <version>3.4.0.GA</version>
     <exclusions>
       <!-- Exclude Commons Logging in favor of SLF4j -->
       <exclusion>
         <groupId>org.apache.commons</groupId>
         <artifactId>com.springsource.org.apache.commons.logging</artifactId>
       </exclusion>
   <exclusion>
     <groupId>xml-apis</groupId>
     <artifactId>xml-apis</artifactId>
   </exclusion>        
     </exclusions>
   </dependency>

dimanche 3 juillet 2011

Eclipse : Can not find the tag library descriptor for "http://java.sun.com/jsf/core"

Problème :

Dans Eclipse, j'ai l'erreur suivante : Eclipse : Can not find the tag library descriptor for "http://java.sun.com/jsf/core"

Solution :

J'ai ajouté la dépendance suivante pour qu'elle se trouve dans le classpath d'Eclipse :


<dependency>
 <groupId>com.sun.faces</groupId>
 <artifactId>jsf-api</artifactId>
 <version>2.0.0-Beta2</version>
</dependency>

samedi 2 juillet 2011

Can not find the tag library descriptor for "http://java.sun.com/jsf/html"

 Problème :

J'ai l'erreur suivante dans Eclipse : Can not find the tag library descriptor for "http://java.sun.com/jsf/html"

Solution :

Il faut ajouter les dépendances Maven suivantes pour avoir les jars dans le classpath :

<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-impl</artifactId>
  <version>2.0.0-Beta2</version>
</dependency>

vendredi 1 juillet 2011

SAXException: The content of element type "web-app" must match



Problème


Lorsque je déploie mon war dans JBoss 6.0.0 ( idem JBoss 5.1), j'ai l'erreur suivante :

Caused by: org.xml.sax.SAXException: The content of element type "web-app" must match "(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-mapping*,session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)". @ vfs:///opt/jboss/jboss-6.0.0.Final/server/dr_jbossweb-standalone/deploy/getting-spring.war/WEB-INF/web.xml[53,11]

Je regarde de plus mon web.xml et je ne vois rien d'anormal :

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:META-INF/properties/log4j.properties</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>

  <!--All spring configuration files need to be loaded in context. Although we have single file but
  with the growing configuration stuff we need to break down configuration files too-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/integration-*.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet>
    <!--Spring's front controller or dispatcher which will be responsible to handle every web request
    and dispatch it to a specific web controller-->
    <servlet-name>integration</servlet-name>
    <display-name>integration</display-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/integration-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!--Let every request be handled by Spring's Dispatcher servlet and it'll decide which web controller to call -->
  <!--based on @RequestMapping-->
  <servlet-mapping>
    <servlet-name>integration</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>
</web-app>

D'ou vient l'erreur ?


Solution

La solution est un peu étrange mais simple.
I faut mettre :
  <!--All spring configuration files need to be loaded in context. Although we have single file but
  with the growing configuration stuff we need to break down configuration files too-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/integration-*.xml</param-value>
  </context-param>

avant
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

Cela donne le web.xml suivant :

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:META-INF/properties/log4j.properties</param-value>
  </context-param>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/integration-*.xml</param-value>
  </context-param>  
  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet>
    <!--Spring's front controller or dispatcher which will be responsible to handle every web request
    and dispatch it to a specific web controller-->
    <servlet-name>integration</servlet-name>
    <display-name>integration</display-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/integration-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!--Let every request be handled by Spring's Dispatcher servlet and it'll decide which web controller to call -->
  <!--based on @RequestMapping-->
  <servlet-mapping>
    <servlet-name>integration</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>  
</web-app>

mercredi 29 juin 2011

Can not find the tag library descriptor for "http://richfaces.org/a4j"

Problème :

J'ai un fichier jsp avec dedans :


<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>


Eclipse signale l'erreur suivante : Can not find the tag library descriptor for "http://richfaces.org/a4j"


Solution :

J'ai rajouté les dépendances suivantes pour avoir les jar dans le classpath :

<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
<version>3.3.0.GA</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl-jsf2</artifactId>
<version>3.3.3.Final</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
<version>3.3.3.Final</version>
</dependency>

mardi 28 juin 2011

no declaration can be found for element 'aop:aspectj-autoproxy'

Problème :

Au déploiement, j'ai l'erreur suivante :
Caused by: org.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 28; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'aop:aspectj-autoproxy'.

Solution :

Il y a un problème avec le xsd du schemaLocation.


Dans mon fichier web.xml, j'ai vérifié xsi:schemaLocation et il n'y avait pas spring-aop-3.0.xsd.
J'ai donc modifié le fichier comme ceci :

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

lundi 27 juin 2011

java.lang.ClassNotFoundException: org.aspectj.util.PartialOrder$PartialComparable

Problème :

Lorsque je déploie mon war dans JBoss 6.0.0, j'ai l'erreur suivante :

java.lang.ClassNotFoundException: org.aspectj.util.PartialOrder$PartialComparable


Solution :

Il manque la dépendance Maven  : aspectjweaver  :

  <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.6</version>
</dependency>

vendredi 24 juin 2011

Comment ajouter log4j dabs une application Spring3 Maven avec JBoss6 ?

Pour ajouter log4j avec Maven, on a tendance à faire :

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
</dependency>

Or la compilation va échouer en raison de la license des artefacts utilisé pour certaines fonctionnalités dans log4j.
J'ai trouvé cet explication sur le blog suivant : http://unitstep.net/blog/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions/

If you’re using Maven to manage your project’s build and dependencies, you may have encountered some problems when trying to include the latest version of log4j as a dependency.
 Specifically, log4j 1.2.15 depends on some artifacts that are not available in the central Maven repository due to licensing issues, and thus when you try to build a project that depends on this version of log4j,
 you may not be able to download the artifacts and your build will fail.

Donc pour que cela fonctionne, il faut exclure certaines dépendances :
   <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.15</version>
     <exclusions>
       <exclusion>
         <groupId>javax.mail</groupId>
         <artifactId>mail</artifactId>
       </exclusion>
       <exclusion>
         <groupId>javax.jms</groupId>
         <artifactId>jms</artifactId>
       </exclusion>
       <exclusion>
         <groupId>com.sun.jdmk</groupId>
         <artifactId>jmxtools</artifactId>
       </exclusion>
       <exclusion>
         <groupId>com.sun.jmx</groupId>
         <artifactId>jmxri</artifactId>
       </exclusion>
     </exclusions>
   </dependency>

J'ai committé l'ajout de log4j dans le trunk de mon projet tutoriel sur Spring Maven et JBoss 6 : http://code.google.com/p/lin-mon-webapp/

references :
http://unitstep.net/blog/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions/

jeudi 23 juin 2011

Maven Spring3 JBoss 6 Hibernate exemple


Je suis fier d'annoncer la première version du projet lin-mon-webapp avec Spring 3 Hibernate Maven sur JBoss 6.Le code source est disponible sur Google project :  http://code.google.com/p/lin-mon-webapp/.
Pour réussir je me suis aidé du blog suivant :http://www.nabeelalimemon.com/blog/2010/05/spring-3-integrated-with-hibernate-part-a/. (Merci ;-)))

Pour construire te déployer le war, vous aurez besoin de :

-> Maven 2
-> JBoss 6 ( In jbossweb-standalone/lib/ vous devez mettre les jars suivants :  jstl-1.1.2.jar et standard-1.1.2.jar )
-> Mysql et de créer la base intégration avec la table User :

create database integration;
GRANT ALL ON integration.* TO 'integration'@'localhost' IDENTIFIED BY 'integration';
flush privileges;
create table USER (   
user_id int(11) primary key,   
first_name varchar(30),   
last_name varchar(30),   
email varchar(30) );
insert into USER values (1, 'titi', 'toto', 'mail@gmail.com');

Puis vous pouvez consulter le nombre et la liste des utilisateurs : http://localhost:8080/monitor/users

Voici les fichiers principaux de l'application :


Maven pom.xml :

<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.dr.linmon</groupId>
<artifactId>linmon</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Monitor app</name>
<repositories>
<repository>
  <id>JBoss Repo</id>
  <url>http://repository.jboss.com/maven2</url>
</repository>
</repositories>
<dependencies>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${org.springframework.version}</version>
   </dependency>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${org.springframework.version}</version>
   </dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-orm</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>${org.springframework.version}</version>
</dependency>    
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>  
<dependency>
    <groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.5</version>
     <scope>runtime</scope>
</dependency>



        <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.9</version>
        </dependency>


   <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.15</version>
     <exclusions>
       <exclusion>
         <groupId>javax.mail</groupId>
         <artifactId>mail</artifactId>
       </exclusion>
       <exclusion>
         <groupId>javax.jms</groupId>
         <artifactId>jms</artifactId>
       </exclusion>
       <exclusion>
         <groupId>com.sun.jdmk</groupId>
         <artifactId>jmxtools</artifactId>
       </exclusion>
       <exclusion>
         <groupId>com.sun.jmx</groupId>
         <artifactId>jmxri</artifactId>
       </exclusion>
     </exclusions>
   </dependency>
   <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-validator</artifactId>
     <version>4.0.2.GA</version>
     <exclusions>
  <exclusion>
    <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
   </exclusion>      
     </exclusions>
   </dependency>
   <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-annotations</artifactId>
     <version>3.4.0.GA</version>
     <exclusions>
       <!-- Exclude Commons Logging in favor of SLF4j -->
       <exclusion>
         <groupId>org.apache.commons</groupId>
         <artifactId>com.springsource.org.apache.commons.logging</artifactId>
       </exclusion>
   <exclusion>
     <groupId>xml-apis</groupId>
     <artifactId>xml-apis</artifactId>
   </exclusion>
   <exclusion>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
   </exclusion>            
     </exclusions>
   </dependency>
   <dependency>
      <groupId>javax.persistence</groupId>
      <artifactId>persistence-api</artifactId>
      <version>1.0</version>
    </dependency>
   <dependency>
     <groupId>commons-dbcp</groupId>
     <artifactId>commons-dbcp</artifactId>
     <version>1.2.2</version>
   </dependency>
   <dependency>
     <groupId>org.aspectj</groupId>
     <artifactId>aspectjrt</artifactId>
     <version>${aspectj.version}</version>
   </dependency>
  <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>


<build>
<finalName>monitor</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<verbose>true</verbose>
</configuration>
</plugin>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.4</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
</plugins>
</build>
  
<properties>
    <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    <aspectj.version>1.6.6</aspectj.version>    
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
</project>


First the web.xml in whicn we create the servlet monitor :

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Maven Spring MVC 3 with JBOSS 6 </display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>     
  
  <!-- Front servlet.  -->
  <servlet>
<servlet-name>monitor</servlet-name>
<display-name>monitor</display-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/monitor-servlet.xml</param-value>
    </init-param>
<load-on-startup>1</load-on-startup>
  </servlet>
 
<!-- Every request on / will be treat by monitor servlet. -->
  <servlet-mapping>
<servlet-name>monitor</servlet-name>
<url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

Then there is the monitor servlet which define the controller, view relover ... and also where to search controller methos:

monitor-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName">
<!-- Every contoller is automaticaly detect due to annotation @Controller.
    We define here in wich package the post processor have to search controller annotation -->
  <context:component-scan base-package="fr.dr.monitor.controller"/>  

<context:annotation-config/>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean 
class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>



The controller class contains this method :

@RequestMapping(value = "users", method = RequestMethod.GET)
public ModelAndView getUsers() {
  List<User> users = userDAO.getUsers();
  ModelAndView modelAndView = new ModelAndView("users");
  modelAndView.addObject("users", users);
  return modelAndView;
}  

To do that the controller call UserDAO methods and Hibernate will retreive data in User table.
Here is the spring beans file that create Hibernate Session and datasource :

spring.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">


 <!--  <context:component-scan base-package="com.springhibernate.integration.aspects" />-->

 <!--Enables the use of @AspectJ style of aspects' declarations. AspectJ run-time isn't necessarily involved-->
 <aop:aspectj-autoproxy/>

 <!--Platform Transaction Manager declared as "transactionManager" will be used.-->
 <!--"aspectj" mode enables load-time/compile-time weaving of transactional methods, which enables
  those methods to be intercepted even when called internally.
  (Unlike Spring generated proxies which will only be intercepted when called from outside)--> 
 <tx:annotation-driven transaction-manager="transactionManager"/>

<!--
Activates various annotations to be detected in bean classes: Spring's
@Required and @Autowired, as well as JSR 250's @PostConstruct,
@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
and @PersistenceUnit (if available).
-->
<context:annotation-config/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="dataSource" ref="dataSource"/>
 <property name="hibernateProperties">
   <props>
     <prop key="dialect">org.hibernate.dialect.MySQL5Dialect</prop>
     <prop key="show_sql">true</prop>
   </props>
 </property>
 <property name="mappingResources">
   <list>
     <value>mappings/user.hbm.xml</value>
   </list>
 </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
 <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<context:property-placeholder location="classpath*:/META-INF/properties/*.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
 <property name="driverClassName" value="${database.driverClassName}"/>
 <property name="url" value="${database.url}"/>
 <property name="username" value="${database.username}"/>
 <property name="password" value="${database.password}"/>
</bean>



  <!--repository init area-->
  <bean id="repository.users" class="fr.dr.monitor.repository.UserDAO"
        autowire="constructor"/>
</beans>

The session factory will be inject to UserDAO to query on USER table :

UserDAO.java

@Repository
@Transactional
public class UserDAO implements IUser {

private SessionFactory sessionFactory;

@Autowired
public UserDAO(SessionFactory sessionFact) {
this.sessionFactory = sessionFact;
}

@Transactional
public User getUser(Long id) {
return (User) sessionFactory.getCurrentSession().get(User.class, id);
}

@SuppressWarnings("unchecked")
@Transactional
public List<User> getUsers() {
return sessionFactory.getCurrentSession().createQuery("from User user").list();
}

@Transactional
public void addUser(User user) {
sessionFactory.getCurrentSession().save(user);
}
}

All the code is available on google project with Apache License V2 : http://code.google.com/p/lin-mon-webapp/