Enfin un support natif de Maven dans Eclipse!
The Eclipse Integration for Apache Maven
Mais a priori il va falloir s'armer de patience : première release en septembre 2008.
Enfin un support natif de Maven dans Eclipse!
The Eclipse Integration for Apache Maven
Mais a priori il va falloir s'armer de patience : première release en septembre 2008.
Publié par Cédric Thiébault à 11 h 30 0 commentaires
Depuis la version 3.1 de Hibernate Annotations (il me semble), on peut enfin avoir une collection de types primitifs (String
par exemple) grâce à @CollectionOfElements
.
Avant ça, on était un peu bloqué avec des affaires comme un champ texte qui contient la liste séparée par des virgules (ou un autre caractère), ou alors une entité gérée par Hibernate qui ne contient qu'une ID et la primitive à stocker :-(
Attention cependant, l'annotation @org.hibernate.annotations.CollectionOfElements
est spécifique à Hibernate. Elle ne fait pas partie des spécifications JPA...
@Entity public class User { @CollectionOfElements private Set<String> nicknames; }
Publié par Cédric Thiébault à 10 h 51 0 commentaires
Libellés : hibernate
Excellent article sur la différence entre l'inversion de contrôle et l'injection de dépendances. La confusion est souvent faites entre les deux: on pense, à tort, que c'est la même chose...
S'mythology - A Little Clarity - Inversion of Control and Dependency Injection
Publié par Cédric Thiébault à 10 h 50 0 commentaires
Libellés : architecture
NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager
En mettant à jour Hibernate Annotations à la dernière version (3.3.0.ga) via Maven2 (qui semble enfin avoir les dernières versions de Hibernate), j'avais cette exception :
NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager
C'est que le POM de Hibernate Annotations est incomplet.... Il manque la dépendance à hibernate-commons-annotations.
Donc en attendant que le POM de Hibernate Annotations soit corrigé ( http://jira.codehaus.org/browse/MAVENUPLOAD-1532), ajoutez dans le POM de votre projet la dépendance à hibernate-commons-annotations 3.3.0.ga.
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>3.3.0.ga</version> </dependency>
Publié par Cédric Thiébault à 10 h 16 0 commentaires
Convention plutôt que configuration en bon français : il est inutile de préciser des détails lorsqu'ils respectent des conventions établies ( Wikipedia). On en entend de plus en plus parler avec la popularité grandissante de Ruby On Rails.
Le but de ce post est de réduire un peu la taille des fichiers de configuration de Spring qui peuvent vite devenir trés gros...
Pour commencer on peut utiliser le autowiring lors de la définition de nos beans. Spring va effectuer les résolutions automatiquement soit par type, soit par nom.
Dans l'exemple suivant, je définis le autowire par defaut pour tout le contexte :
-- default-servlet.xml --
<beans xmlns="http://www.springframework.org/schema/beans" default-autowire="byName"> <bean id="userController" class="x.y.z.userController" autowire="default" /> </beans>
L'utilisation du autowire n'est pas recommandée par les développeurs de Spring pour les projets de grande taille mais je pense vraiment qu'au niveau du MVC ca ne pose pas de problèmes.
La plupart du temps les URLs ressemblent aux noms des controlleurs... En utilisant le ControllerClassNameHandlerMapping
Spring va chercher dans la liste des controlleurs enregistrés ceux dont le nom (moins le suffixe Controller) match l'url. Par exemple :
- WelcomeController <--> '/welcome*' - DisplayShoppingCartController <--> '/displayshoppingcart*'
Dans le cas de MultiActionController
, le mapping se fera comme suit :
- UserController <--> '/user/*' - UserController.edit(...) <--> '/user/edit.htm'
Pour les parties plus statique des sites, il est idiot de créer un controlleur par page... La classe UrlFilenameViewController
transforme une URL en chemin sur le disque pointant vers la vue correspondante :
/users/list.htm --> /users/list
Si on met tout ca ensemble dans la configuration du servlet de Spring, on obtient :
-- default-servlet.xml --
<beans xmlns="http://www.springframework.org/schema/beans" default-autowire="byName"> <bean id="userController" class="x.y.z.userController" autowire="default" /> <!-- jsp view resolver that points to /jsp folder --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean id="fileNameViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" /> <!-- maps request URLs to Controller names --> <bean id="urlMappingWithControllers" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" /> <bean id="urlMappingNoControllers" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="*">fileNameViewController</prop> </props> </property> </bean> </beans>
Publié par Cédric Thiébault à 13 h 05 0 commentaires
Libellés : spring
Quelques petits liens pour coder Java sur un air de Java ;-)
Java - Sexe, accordéon et alcool
Boris Vian - La Java Martienne
Boris Vian - La Java des bombes atomiques
La Java bleue
Publié par Cédric Thiébault à 11 h 12 1 commentaires
MyEclipse ne supporte pas officiellement Maven2 mais en utilisant le plugin m2eclipse on peut s'en sortir assez facilement....
Selon le standard définit par Maven les classes devraient être compilées dans le répertoire target, mais si l'on veut utiliser MyEclipse pour déployer l'application (Hot deployment) il faut que nous compilions les classes vers src/main/webapp/WEB-INF/classes.
L'idéal serait que MyEclipse supporte le déploiement des classes compilées dans différents répertoires vers le serveur comme ça nous pourrions suivre le standard Maven et compiler vers target mais ce n'est pas encore le cas...
Attention : lorsque l'on déploit avec MyEclipse, on perd la fonctionnalité des filtres de Maven :-(
Dans les propriétés du projet web, définir le webrootdir à src/main/webapp et configurer le fichier .classpath comme suit :
<classpath> <classpathentry kind="src" path="src/main/java" output="src/main/webapp/WEB-INF/classes" /> <classpathentry kind="src" path="src/main/resources" output="src/main/webapp/WEB-INF/classes" /> <classpathentry kind="src" path="src/test/java" output="target/test-classes" /> <classpathentry kind="src" path="src/test/resources" output="target/test-classes" /> <classpathentry kind="output" path="src/main/webapp/WEB-INF/classes" /> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" /> <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" /> </classpath>
Le plus gros problème dans tout ça, c'est que MyEclipse déploit tous les jars définis dans le POM... même ceux qui ne servent qu'à la compilation (scope=provided). Par exemple les fichiers servlet-api.jar et jsp-api.jar seront copiés dans WEB-INF/lib et cela peut créer des problèmes au démarrage du serveur web.
En attendant le support officiel de Maven2 par MyEclipse, il nous reste à effacer ces fichiers manuellement ou à ne pas les inclure dans le POM :(
La communauté des utilisateurs de MyEclipse pousse de plus en plus fort pour le support officiel de Maven2 et certains proposent déjà des solutions qui ne semblent pas demander une tonne de code pour exploiter le plugin m2eclipse (légèrement adapté) et déployer seulement les jar définis pour le runtime.... Patience donc!
Publié par Cédric Thiébault à 12 h 43 0 commentaires
Dans le style des publicités Mac vs PC, voici Java vs Ruby vu par des adeptes de Ruby on rails... Evidemment :)
Publié par Cédric Thiébault à 09 h 43 1 commentaires
Libellés : java
Voici quelques petits trucs pratique pour alléger les POM de Maven2 dans les projets multi-modules...
Classiquement chaque POM défini ses dépendances comme suit :
-- pom.xml --
<project> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>2.0.5</version> <exclusions> <exclusion> <groupId>struts</groupId> <artifactId>struts</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
Si plusieurs modules utilisent Spring MVC, on ne veut pas dupliquer ce code dans chaque POM... On définit la configuration de la dépendance dans le POM parent et on inclus seulement la dépendance dans les modules sans spécifier la version ni les exclusions.
-- pom.xml parent --
<project> <groupId>demo</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>child</module> </modules> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>2.0.5</version> <exclusions> <exclusion> <groupId>struts</groupId> <artifactId>struts</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement> </project>
-- pom.xml child --
<project> <artifactId>child</artifactId> <parent> <groupId>demo</groupId> <artifactId>child</artifactId> <version>1.0-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> </dependencies> </project>
Dernier petit truc pour simplifer la gestion des version des dépendances : au lieu de hardcoder la version de la dépendance dans sa définition, on peut utiliser des 'properties'. Par exemple pour Spring où l'on dépend de plusieurs jars, on peut facilement upgrader en modifiant seulement la propriété 'spring.version'.
-- pom.xml --
<project> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-dao</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-hibernate3</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </dependencyManagement> <properties> <spring.version>2.0.4</spring.version> </properties> </project>
Au passage, le site mvnrepository.com est un bon outils pour trouver les jars publiés dans Maven2 et surtout pour trouver lesquels ont été déplacé...
Publié par Cédric Thiébault à 15 h 24 0 commentaires
Libellés : maven
Après plusieurs heures passées à trouver mon erreur d'encodage UTF-8, voici un petite liste des points à vérifier sur une application web.
Mon environnement :
Vérifier que les tables et les champs textes utilisent le charset UTF-8 :
CREATE TABLE [...] DEFAULT CHARSET=utf8;
-- hibernate.cfg.xml --
<hibernate-configuration> <session-factory> <property name="hibernate.connection.useUnicode">true</property> <property name="hibernate.connection.characterEncoding">utf-8</property> </session-factory> </hibernate-configuration>
Utiliser le servlet filter CharacterEncodingFilter
dans le web.xml afin de forcer l'encodage. Attention de bien positionner ce filtre en première position dans la liste des différents filtres!
-- web.xml --
<web-app> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> </web-app>
Lors du load des templates Velocity, spécifier l'encodage UTF-8.
String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, fileName, "UTF-8", tokens);
Encoder aussi les mails. Dans mon cas avec MimeMessageHelper
.
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
Définir l'encodage des JSP.
<%@ page contentType="text/html; charset=UTF-8"%> <%@ page pageEncoding="UTF-8"%>
Si après tout ça vous avez encore des problèmes, vous pouvez toujours essayer de configurer Tomcat mais je pense que ça ne changera pas grand chose...
-- server.xml --
<Server> <Service> <Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" [...] /> </Service> </Server>
Tous ces points ne sont surement pas nécessaire... il faut que je vérifie. Je pense que l'encodage au niveau de la base de données, du web.xml et des mails (Velocity et MimeMessage) est suffisant mais cette liste peut ammener des indices à d'autres qui rencontrent ce genre de problèmes...
Dans mon cas, le problème venait du servlet filter d'encodage de Spring : il n'était pas en première position :-(
Publié par Cédric Thiébault à 10 h 02 12 commentaires
Libellés : java