lundi 14 janvier 2013
Java 7 list of new features
http://docs.oracle.com/javase/7/docs/webnotes/adoptionGuide/index.html
This is an adoption guide for java 7 with the list of all new features (from official Oracle site).
samedi 27 octobre 2012
Liferay : how to fix NoSuchBeanDefinitionException while portlet deploying
The partial stacktrace is belows:
16:36:12,700 ERROR [PortalClassLoaderServletContextListener:92] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'my.service.SynergieCategoryLocalService.impl': Injection of BeanReference fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.service.persistence.SynergieCategoryPersistence.impl' is defined org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fr.smile.synergie.service.SynergieCategoryLocalService.impl': Injection of BeanReference fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.service.persistence.SynergieCategoryPersistence.impl' is defined at com.liferay.portal.spring.annotation.BeanReferenceAnnotationBeanPostProcessor.postProcessAfterInstantiation(BeanReferenceAnnotationBeanPostProcessor.java:67) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45) at com.liferay.portal.spring.context.PortletContextLoaderListener.contextInitialized(PortletContextLoaderListener.java:77) at com.liferay.portal.kernel.servlet.PortalClassLoaderServletContextListener.portalInit(PortalClassLoaderServletContextListener.java:89) at com.liferay.portal.kernel.util.PortalInitableUtil.init(PortalInitableUtil.java:47) at com.liferay.portal.kernel.servlet.PortalClassLoaderServletContextListener.contextInitialized(PortalClassLoaderServletContextListener.java:73) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926) at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1217) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:293) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1337) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1601) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590) at java.lang.Thread.run(Thread.java:680) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.service.persistence.SynergieCategoryPersistence.impl' is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387) at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:971) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:246) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:880) at com.liferay.portal.bean.BeanLocatorImpl.locate(BeanLocatorImpl.java:59) at com.liferay.portal.kernel.bean.PortalBeanLocatorUtil.locate(PortalBeanLocatorUtil.java:58) at com.liferay.portal.spring.annotation.BeanReferenceElement.getResourceToInject(BeanReferenceElement.java:70) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180) at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105) at com.liferay.portal.spring.annotation.BeanReferenceAnnotationBeanPostProcessor.postProcessAfterInstantiation(BeanReferenceAnnotationBeanPostProcessor.java:64) ... 36 more
The portlet classes have been generated by build-service and the same code worked fine during last 2 years. So I was pretty sure that my Spring config is OK and the problem resides in the other part of the system.
After few days spent in debug mode, I have found that while deploying the portlet, the folder WEB-INF/lib was missing the jar file util-java.jar.
Obviously, util-java.jar is needed by Liferay to make some stuff. And apparently, in my case, this jar have not been copied automatically by Liferay hot deployer.
I have copied the missing util-java.jar to WEB-INF/lib and portlet has been deployed without any error.
jeudi 9 février 2012
Maven BuildNumber plugin - short revision id for Git
mercredi 8 février 2012
My first Open Source commitment - Git short revision




- http://jira.codehaus.org/browse/MBUILDNUM-86
- http://jira.codehaus.org/browse/SCM-664
mardi 3 mai 2011
Log4j : Customize LoggingEvent for SMTPAppender
Recently I was confronted to the need of customizing the log4j message generation. When an exception occurs, the application should sent the email to the development team in the following format:
The error message should be enclosed by the corporation information represented by the header and footer. The problem is the application URL (marked by the red ellipse). This URL can be different depending on the environment where the application is running and throwing the exception. In the complex, industrial projects where exist many environments, this can be very helpful to determine which environment has a problem.
First of all, how set the footer and header? It’s quite simple, you have to use org.apache.log4j.EnhancedPatternLayout, in the parameter ConversionPattern, you put the header, footer and the message error with some additional information (date, class name which generated the exception, etc). The standard log4j distribution(log4j.jar file) does not contain the class EnhancedPatternLayout, you have to download the additional extras companion (here)
Pay particular attention to do not use org.apache.log4j.PatternLayout which contains some issues with synchronization (see the first paragraphe of the associated JavaDoc). PatternLayout class is still widely used and all exemples on Internet use it, but for make your code robust you don’t have to use it.

And what about the environment dependent URL ? How can I put the http://myapp.production.com or http://myapp.integration-test.com in the log message? I found 2 solutions:
- Use ant or maven to replace a specific symbol in your log4j.xml (log4j.properties) when you are building the app. You can use filter resource maven plugin fot that. But is not the most elegant solution, because you will have a strong dependency with the build tool. For production system, it is not a choice.
- Use org.apache.log4j.EnhancedPatternLayout and %properties{key} mechanism
The code is self documented. I put the URL to prod environment behind the key named "app".I hardcoded the value in order to make the explanation simpler. But in your production code you may get the correposnding value from properties file, from environment variable or from the database.
Next, the key “app” in the event property becomes available for Log4J runtime. You may see how I use it in my log4j.xml file (the 2nd screenshot).
The setProperty method is an extension point and the excellent example of a good designed API.
Updated : actually, there is a simpler method to inject the environment name into the log4j logging message - simply, change the ConversionPattern for each log4.propeperties file.
dimanche 17 avril 2011
JavaOne 2011 in Moscow. Review.
La semaine dernière j’étais en Russie, à Moscou, à la conférence JavaOne organisé par Oracle.
J’ai eu deux jours du plaisir technique. Entouré par les gens passionnés par la technique, j’ai pris une bonne dose de motivation.
La conférence se déroulait au centre de Moscou, au bâtiment épique de l’académie de science de la fédération russe (Российская Академия Наук - РАН) connu aussi sous le nom « Les Cerveaux » :)
Quelques points/événements clés que j’ai retenus à l’issue de la conférence sont présentés ci-dessous suivis de photos de ma collection.
Les nouveautés dans Java 7 présenté par une personne charismatique - Danny COWARD: join/fork mécanisme pour les traitements parallèles (map-reduce) ; le sucre syntaxique avec l’opérateur « Diamond » (<>) qui va faciliter la lecture du code qui utilise les génériques; le support de String dans l’opérateur switch ; les clauses catch avec la possibilité de préciser multiples exceptions.
Les standard Java EE 6 : avec l’API Servlet 3.0 (les appels asynchrones, configuration avec les annotations, le fichier web.xml est optionnel, l’utilisation du fichier web-fragment.xml pour les composants auto-configurable dans le contaneur, etc.), le support native de getsion de dépendence (DI) avec l’arrivé de la notation @Inject.dimanche 20 mars 2011
Integration tests with JUnit and Spring

- Ecrire une classe de tests qui hérite de AbstractTransactionalJUnit4SpringContextTests
- Définir une méthode setUp avec l'annotation @BeforeTest. Cette méthode va utiliser executeSqlScript pour préparer la base de données en y injectant les données qui sont nécessaires pour l'exécution de votre méthode de test. Attention, à ne pas utiliser les ";" à la fin des lignes avec SQL. Les lignes qui se terminent par le ";" seront ignorés par Spring.
- La méthode de test qui va faire des "asserts" sur le nombre des lignes insérées dans les différentes tables impactés par les opérations DAOs. Pour faire ces asserts la méthode countRowsInTable est la plus appropriées.
- Pour que la base de données reste dans son état initial, il faut supprimer maintenant toutes les données qui ont y été ajoutées par deux étapes précédentes. Pour cela, il suffit de créer une méthode tearDown annotée par @AfterTest, dans cette méthode vous pouvez appeler la méthode généreusement offerte par Spring - deleteFromTables.
samedi 13 septembre 2008
Audit des logiciels
Pour ceux qui cela intéresse il y a la norme ISO 9126 consacrée à l’évaluation de la qualité de logiciel. Pour plus de détails : http://en.wikipedia.org/wiki/ISO_9126
Une représentation très compréhensive en français est ici.
Parmi les logiciels qui permettent de sortir certaines métriques sur le code, je peux vous recommander :
- Source Monitor. Support de plusieurs langages: Java, C++, C#, C, Delphi, Visual Basic et même HTML. Un outil puissant, facile à utiliser et à installer. OpenSource. http://www.campwoodsw.com/sourcemonitor.html.
Merci à Aurélien qui m'a montré cet outil. - Metrics pour Eclipse. Que pour le monde Java. Un plagin très sympathique et puissant qui s’intègre à Eclipse et qui calcule les métriques à la volée. http://metrics.sourceforge.net/
Cet audit semble être très intéressant. On devra évaluer une dizaine de l’application pendant quelques heures. J’espère ce sera très enrichissant !
Bon, c’était mon dernier post pour ce week-end ;)