Spring maintenant payant

Oui la nouvelle du week-end ou plutot de fin de semaine sur le changement de licence de Spring me reste en travers de la gorge, même si j’en comprends les raisons.

Mais d’un coup je me sens coupable d’avoir poussé depuis 2004 à l’utilisation de Spring sur plusieurs projets et d’en avoir été le défenseur auprès de certains collègues réticents sur les principes d’injection de dépendances, de conteneur léger et même d’AOP. Sur mes 2 derniers projets, j’ai même introduit Spring Security (anciennement ACEGI) et utilisé Spring MVC pour une petite application interne chez mon employeur précédent. Et oui, le changement de licence s’applique aussi à tous ces projets.Cela me fait maintenant me re-questionner sur l’utilisation de ce framework.

D’abord pourquoi Spring ? Logiquement après avoir lu les livres de Rod Johnson “J2EE design and development” et “J2EE Development without EJB” son utilisation semblait être une vrai alternatives aux Ejb 2.x pour les raisons suivantes :

  • des objets et services métiers n’implémentant aucune interface technique (juste des POJO).
  • l’injection de dépendances favorisant le couplage faible entre les objets.
  • les tests unitaires sans déployer dans le conteneur EJB accélérant ainsi les phases de test.
  • la rapidité de démarrage du conteneur Spring pemettant de l’utiliser en dehors d’un serveur application.
    Mais Spring est aussi utilisé maintenant pour toutes ses fonctionnalités qui facilitent le développement d’application JavaEE :
  • son intercepteurs transactionnels et son annotation @Transactional
  • l’accès aux services des serveurs d’application par simple déclaration (j2ee:jndi-lookup)
  • la création de proxy sur des Ejb (2.1, 3.0), Web-Services (JAX-RPC et JAXWS) .
    En fait, j’ai en fait toujours été très satisfait de Spring Core et impressionné par sa stabilité et son excellente documentation tout cela en opensource et gratuit. Les applications développées avec étaient même plus portables que les traditionnelles applications J2EE. Mais la lune de miel a une fin et je pense maintenant que je vais devoir m’intéresser aux alternatives, car je vois mal certains clients payer pour une librairie (cela changera peut-être pour avec Spring dm Server).

    Les alternatives

Pour moi la + évidente :

  • JavaEE 5 et les EJB 3
    Et oui avec des conteneurs d’EJB en mode embedded pouvant être utilisés pour les tests et démarrant en quelques lignes de codes ( voir par exemple OpenEJB de la fondation Apache ou encore JBoss embedded ). De + cette solution a l’immense mérite d’être standard.Maintenant techniquement, le mécanisme d’interception d’EJB 3 n’est pas aussi riche que celui proposé par Spring et son support d’AspectJ. Le mécanisme ne permet d’injecter uniquement des Ejbs ou des ressources JNDI. Mais au moins les tests sans déploiement sont possibles, le code simplifié et épuré. De +, Ejb 3.1 apportent aussi son lot de nouveautés comme l’annotation @Singleton ou la non-obligation de créer une interface métier.

  • Guice

Peut-être un peu jeune et n’est qu’un “IOC container” mais pourquoi pas pour une utilisation pour des applications standalone.

Some common JSF pitfalls

Well at least here’ s a non exhaustive list of common jsf pitfalls, i felt into (some are variants of others) :

  • Using a converter in a SelectOneMenu or SelectManyList components, be careful of type being applied. See http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=82&t=003594. Using an array instead of typed collection for the component input values ( still not sure why, have investigated too much on it, so i won’t extend on it)!
  • Declare a resource bundle in the page ( most of the time bundles are declared in a template page) with the loadbundle element instead of declaring it the faces-config.xml file . If done so, requiredMessage or converterMessage attibutes that can be applied to many UIInput components won’t work (i.e the message won’t be found).
  • With a commandLink inside dataTables with a bean of request scope actions are not executed. At least it happened to me with JSF RI 1.2_07 and is due to the fact that the id of the dataTable component is changed between the component tree creation (restore view phase) and the render response phase ( Update 09/21/2008 : See more explanations on this in the comment section by Dan Allen himself, author of “Seam in Action” ). When submitted on a post back request, the actions event are not queues (passed as hidden fields). It’s well detailled here http://typo.ars-subtilior.com/articles/2007/02/07/jsf-datatable-and-commandlink. As a workaround, i used the tomahawk savestate component for the elements of the datatable. This component stores the state of objects passed as value expression in the component tree (having a scope that spans between the inital request restore view and post back render response phase) . Seam has a page scope for that.
  • Validation errors when using a converter in selectOne* components and not overriding the equals() method for the type of object in the list. More explanation here : http://www.crazysquirrel.com/computing/java/jsf/converter-validation-error.jspx
  • Saving state on client side with hidden fields and having conversion or validation issues with a backing bean of request scope: state is lost. For instance, you have an inputHidden component in your form and for a reason or another a form’s field has conversion or validation issues. The backing bean of request scope is not updated for the postback request. The bean used to display the response is new and the inputHidden‘s field value is reset. Once again this shows a lack of page context for state that needs to be kept between the initial request and the postback request.
  • Programmatic submission of a web form in javascript through form’s submit method won’t work because the actionlistener is registred on a commandButton and when the form is submitted, the submit button parameter is not passed in the request. The button’s action event is not put in the event queue. A workaround is to programmatically click on the form’s command button.

Switched to french canadian keyboard

Very interesting news,after a trip to Canada i switched my keyboard layout from french azerty based layout to french canadian. Since it’s a qwerty based layout it might be useful, if one day i have to work abroad. Also it’s more efficient for programming and english writings.

Spring entityManagerFactory in jta and non-jta modes

This blog post is about using JPA with Spring in 2 contexts :

  • production with a JTA transaction manager
  • testing with transactions handled by jpa transaction manager.
    It has been inspired by Erich Soomsam blog postYou can achieve such configuration with a PersistenceUnitPostProcessor having a single persistence.xml file and 2 Spring context files (1 for each environment).Since you are likely to have at least 2 different Spring dataSource definitions : 1 for production that performs a JNDI lookup to find a bound datasource and 1 for development that uses a local and Spring declared datasource backed by a JDBC connection pool (C3p0 or DBCP), place the entityManager declaration in the same file as the datasource declaration. Let’s say that the default persistence.xml use the non-jta datasource:
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit transaction-type="RESOURCE_LOCAL"
    name="seamphony">
    <properties> <!-- Scan for annotated classes and Hibernate mapping XML files -->
    <property value="class, hbm" name="hibernate.archive.autodetection" />
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
    </properties>
    </persistence-unit>
    </persistence>

    Here’s how you can use Spring to post process the persistence unit and configure it for production (here with MySQL datasource and JBoss Transaction Manager):
    <bean
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    id="entityManagerFactory">
    <property ref="dataSource" name="dataSource"></property>
    <property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property value="MYSQL" name="database" />
    <property value="true" name="showSql" />
    <property value="org.hibernate.dialect.MySQLDialect" name="databasePlatform" />
    </bean>
    </property>
    <property name="jpaPropertyMap" />
    </bean>
    <map>
    <entry value="org.hibernate.transaction.JBossTransactionManagerLookup"
    key="hibernate.transaction.manager_lookup_class">
    <entry value="true" key="hibernate.transaction.flush_before_completion" />
    <entry value="true" key="hibernate.transaction.auto_close_session" />
    <entry value="jta" key="hibernate.current_session_context_class" />
    <entry value="auto" key="hibernate.connection.release_mode" />
    </entry>
    </map>
    <property name="persistenceUnitPostProcessors">
    <list>
    <bean class="JtaPersistenceUnitPostProcessor">
    <property value="true" name="jtaMode"></property>
    <property ref="dataSource" name="jtaDataSource"></property>
    </bean>
    </list>
    </property><!-- Datasource Lookup -->
    <bean class="org.springframework.jndi.JndiObjectFactoryBean" id="dataSource">
    <property name="resourceRef">
    <value>false</value>
    </property>
    <property name="jndiName">
    <value>java:/MyDS</value>
    </property>
    </bean><!-- Transaction Manager -->
    <bean class="org.springframework.transaction.jta.JtaTransactionManager"
    id="transactionManager">
    <property value="java:/TransactionManager" name="transactionManagerName" />
    <property value="false" name="autodetectUserTransaction" />
    </bean>

Here’s the class that reads the jta mode property and configure the transaction type accordingly:

import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
public class JtaPersistenceUnitPostProcessor implements
PersistenceUnitPostProcessor {
private boolean jtaMode = false;
private DataSource jtaDataSource;
private PersistenceUnitTransactionType transacType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
public void postProcessPersistenceUnitInfo(
MutablePersistenceUnitInfo mutablePersistenceUnitInfo) {
if (jtaMode) {
transacType = PersistenceUnitTransactionType.JTA;
mutablePersistenceUnitInfo
.setJtaDataSource(this.getJtaDataSource());
}
mutablePersistenceUnitInfo.setTransactionType(transacType);
}
public boolean isJtaMode() {
return jtaMode;
}
public void setJtaMode(boolean jtaMode) {
this.jtaMode = jtaMode;
}
public DataSource getJtaDataSource() {
return jtaDataSource;
}
public void setJtaDataSource(DataSource jtaDataSource) {
this.jtaDataSource = jtaDataSource;
}
}

Spring really helps tuning your persistence unit for different environments. It could be achieved by a custom build task that could alter the persistence.xml file but since this example assumes that Spring is already used, it can be avoided.

Stat your commits

I recently discover the StatSCM maven plugin and it made our team day . It gives useful information about your Subversion activity (it supports other SCM systems) giving precise developers activity information or file statistics. It also generates some nice charts. I found it very useful to monitor what the team members commit: for instance we discovered that a trainee was the developer of the month (ranked by LOC commited) because he commited some very large csv test files.First to enable it, configure the dependency and declare the report in the reports section of your maven parent pom file:

<pom>
<build>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<dependencies>
<dependency>
<groupid>net.sf</groupid>
<artifactid>stat-svn</artifactid>
<version>0.4.0-StatSCM</version>
</dependency>
<dependency>
<groupid>org.apache.maven.reporting</groupid>
<artifactid>maven-reporting-impl</artifactid>
<version>2.0.4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<configuration>
<excludes>
<exclude>**/*.csv</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</reporting>
</pom>

And here some charts produced, like the number of LOC commited by each developer:Number of lines of codeThe day commit activity:Commits activityOr the ration between files addition/modification:

IT consolidation

Todays news:Oracle buys BEA.**Mysql AB acquired by Sun.**Well what’s next? Redhat acquired by Sun (or even Microsoft), Adobe acquired by Oracle, etc ?Industralization of the IT sector seems to get some steam, surely a sign of maturity. I am not sure if it will have an impact on innovation or this trend is the result of a loss of innovation. Big actors want to provide a complete enterprise stack from hardware to software package solutions. Will we only have to deal with SAP, Oracle, IBM, Sun and Microsoft tomorrow ?Google strategy seems to differentiate and focus on online services.

A picture is worth a thousand words (my 2008 no interest techs list)

This comic sums up my opinion on Scala pretty well (very funny):http://stuffthathappens.com/blog/2008/01/02/scala-will-do/I jumped on Ruby and Rails bandwagon spending some man-days (;-)) on it but at least Rails has been a reference in term of web productivity and introduced or leveraged nice concepts (naming conventions over configuration, DSL, REST, TDD etc.) . Recently, many Java web frameworks compared themselves to Rails and how they were much better (Seam,Grails & Co). Rails influenced the IT community (Java, .Net and Python included).=> All in all, i have excuses to have followed the crowd… But not this time, Scala (pretty unreadable), JavaFx (not until i see the consumer jre in action and applets as fast-loaded as flash apps without dumb dialog boxes) are definitely on my 2008 technos of no-interest !I’ll hopefully focus this year on the new Cobol ;-) core (or even .Net/C#) .