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>