Affichage des articles dont le libellé est astuces. Afficher tous les articles
Affichage des articles dont le libellé est astuces. Afficher tous les articles

samedi 27 octobre 2012

Liferay : how to fix NoSuchBeanDefinitionException while portlet deploying

I would like to share the fix for mysterious and annoying issue that I've encountered during the development and deploying of a portlet for Liferay 5.2.3.

The error that Liferay server (Tomact) listed in the logs was related to misconfigured Spring beans and the exception was org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.service.persistence.SynergieCategoryPersistence.impl' is defined 
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.

samedi 29 janvier 2011

Démarrage d'un nouveau projet. Retour d'expérience

Récemment j’ai participé au démarrage d’un projet en Java. Nous avions la chance de prendre les décisions sur la création de l’usine de logiciel pour assurer la qualité du produit pour le client.

Je ne vais pas décrire toutes les étapes et tous les concepts que nous avons mis en place. Mais, je vais me limiter de présenter les outils que je n’ai jamais utilisés avant.

Wiki

Tout d’abord c’est – Redmine – un wiki d’entreprise. C’est un outil dont j’ai entendu parler depuis longtemps et j’ai l’utilisé un tout petit peu sur un projet sur lequel j’étais tout seul. Dès le démarrage du projet nous avons commencé à utiliser Redmine et nous avons réussi à motiver les développeurs de l’utiliser au quotidien. D’après ce que j’ai vu, les gens qui ont fait leur première page sur le Wiki y reviennent et l’utilisent plus régulièrement que ceux qui n’ont jamais écrit là-dedans. Je pense que cela s’explique par le fait d’être un auteur. Un auteur cherche en permanence d’améliorer son œuvre : ajouter une description d’un truc technique complexe, jouer avec la mis en page (surligner les informations importantes). Nous avons commencé par le plus simple. La page principale de notre wiki centralise et met à porter de main les informations sur l’infrastructure du projet :

  1. Le chemin vers le repository SVN
  2. URL, login et mdp pour les serveurs Hudson et Sonar.
  3. IP, login et mdp pour les bases MySql de test
  4. Le raccourci vers le répertoire du projet sur un serveur de fichier
  5. URL , login et mdp vers le serveur Nexus
  6. IP d’une passerelle SMTP utilisée
  7. Les HowTo’s sur la configuration d’Eclipse, Maven, Tomcat, etc.

Ces informations sont nécessaires tout au long du projet et sont utilisées par tous les membres de l’équipe. Désormais, je n’entends plus dans l’openspace les questions du genre : « C’est quoi le IP et le mot de passe du serveur MySQL ?» ou « Comment t’as fait pointer ton Maven en local vers le serveur Nexus ?». Toutes les réponses sont dans le Wiki. J’ai l’impression que les développeurs deviennent plus autonomes et par conséquent plus productif, ils savent où il faut chercher l’info.

L'intégration du Mylyn dans Redmine permet créer un boucle complet de la gestion technique du projet: Eclipse -SVN - BugTracker - Suivie du projet. Cette fonctionnalité n'est pas encore adaptée par notre projet, car cela nécessite la forte discipline et la rigueur des développeurs.

Un petit plugin textile de Redmine pour colorer le code source dans les pages wiki :


Vous remplacez le nom de la classe (xml, java, C#, python, etc) et les mots clés presents dans le texte seront coloré comme dans un IDE. Très pratique et très joli.

Tomcat 6.0 manager sous Ubuntu ne marche pas

Dans l'objectif d'automatiser le déploiement du war sur le serveur Tomcat 6.0, nous avons utilisé le plugin tomcat du maven. Voilà comment j'ai réussi:

  1. Installer l'application manager : sudo aptitude install tomcat6-admin
  2. Modifier le fichier $VOTRE_TOMCAT_INSTALL/conf/tomcat-users.xml comme suit, faites attention qu'il faut bien le rôle "manager"
  3. Redémarrer le serveur: sudo /etc/init.d/tomcat6 restart
  4. Mon erreur c'étais que je n'ai pas précisé le rôle admin. Et j'avais tout le temps l'erreur HTTP 403.

lundi 1 mars 2010

Interviews techniques. Best practices pour les candidats

Suite à mon expérience avec le monde des SSII parisiennes, j’ai accumulé un certain nombre des idées et de remarques sur les entretiens techniques.

J’ai eu de la chance d’être présent sur les deux côtés des barricades : en tant que candidat cherchant des nouvelles missions et en tant que « conducteur » représentant l’entreprise qui voulait embaucher des spécialistes techniques.

Dans cet article je vais présenter mon expérience en tant que candidat.

Alors, vous êtes un candidat, l'ingénieur en informatique cherchant une nouvelle mission/poste.

Je vais laisser à côté le premier test technique que vous avez éventuellement passé avec le RH. Dans la plupart des cas, ce test est un QCM classique (la syntaxe du langage, possibilité du plateforme, les questions sur les bases de OOP). Ce test est nécessaire pour faire la première « brute » estimation de vos compétences. Ce test permettra d’éviter à l’entreprise de solliciter l’un de ces référents techniques ou architecte pour évaluer le niveau des connaissances de base du candidat.

Tout d’abord, pour réussir l’entretien technique il faut adapter une idée qu’une interview c’est un jeu. Pour vous ce jeu doit avoir 2 objectifs : répondre correctement aux questions et profiter de l’occasion pour parler avec une personne forte techniquement. En effet, les conducteurs des entretiens ce sont des personnes avec un bon niveau technique qui peuvent vous apporter beaucoup d’information nouvelle et intéressante. Notez toutes les questions sur lesquelles vous n’avez pas de réponse, n’hésiter pas à posez des questions à l’interwieur si le contexte est favorable (pas de contraintes de temps, par exemple). Cela montre que vous êtes toujours prêt à apprendre et curieux par rapport aux nouvelles technologies.

Si on vous pose la question et vous ne savez pas exactement la bonne réponse. Pas de panique. Essayez de réfléchir à la voix haute. Faites quelques hypothèses. Peut-être en cours de cette réflexion vous allez trouver la réponse ou la personne en face de vous pourrait vous indiquer la bonne direction. Mais, n’hésitez pas à dire fermement : « Je ne sais pas », si vous ne savez pas du tout où chercher la bonne réponse.
Très souvent on vous posera des questions pièges. Par exemple, « Quelle type de relations entre les objets préférez-vous : héritage ou agrégation/composition ? » Il n’y a pas une seule réponse correcte. Tout dépend du contexte particulier. Vous devez expliquer cela pour chaque type de relation en donnant un exemple.

Lors de vos réponses essayez de montrer votre culture technique, en s’appuyant sur les ouvrages, livres ou blogs des différents experts dans votre domaine.

N’hésitez pas à schématiser vos réponses ou vos réflexions. Les diagrammes UML simples ou juste des carrés avec des cercles suffiront. Les architectes adorent les schémas. :)

Après chaque entretien, faites des rétrospectives. Analysez vous-même vos réponses et le résultat de l’entretien. Notez bien les points que vous ne maîtrisez pas et réfléchissez comment vous pouvez les améliorer. Chaque entretien c'est un miroir qui reflète vos faiblesses. Oui, uniquement, les faiblesses. En informatique, il n y a pas une personne qui sait tout !

PS : L’article a été posté avec le support du café www.lacantochepaname.com, rue Réaumur.