HOAB

History of a bug

Jacoco ne génère pas de rapport via Sonar

Rédigé par gorki Aucun commentaire

Le problème :

Configuration du job Jenkins pour Sonar avec les arguments Jacoco :

clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Dmaven.test.failure.ignore=true

Et pourtant pas de couverture de code à la fin de l'exécution du build sonar.

Solution :

Simple quand on connait la réponse, conflit entre  :

  • les arguments dans le pom.xml du plugin Surefire
  • les arguements en ligne de commande du plugin Jacoco.

Du coup, les <argLine> du plugin Surefire dans le pom.xml doivent référencer la variable ${argLine}

 <argLine>-server -ea -XX:MaxPermSize=256m -Xmx4g -XX:-UseSplitVerifier ${argLine}</argLine> 

Extrait de stackoverflow

 

Spring, Autowire, Proxy Class

Rédigé par gorki Aucun commentaire

Le problème :

A l'origine, suite à une réorganisation des classes et un nettoyage des configurations Spring, une des classes (appelons-là ClasseA) n'est plus "Autowired" sur ClasseB.

Alors que :

- les dépendances entre configurations Spring sont OK

- le component scan est OK

- les traces de Spring montrent bien une instanciation de la classe ClasseA et une tentative d'"autowiring" sur la classe ClasseB.

Puis, plus rien, pas de trace d'erreur si ce n'est que l'autowiring indique qu'il n'a pas trouvé de candidat.

 

Solution :

Ce n'est pas très simple.

Première étape :

- le tag qui a fait marcher le test :

<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />

Je ne voyais pas le lien entre les transactions spring et ma classe qui n'avait aucun rapport avec les transactions.

En réalité c'est le proxy-target-class="true" qui a fait marcher le test. Grâce à ce lien, il est indiqué que cet attribut s'applique partout !

 

Deuxième étape deux nouveaux tests :

- suppression du proxy-target-class:  le test est KO (revenu à l'état premier)

<tx:annotation-driven transaction-manager="transactionManager" /> 

- ajout d'un tag général dédié aux proxies : le test est KO, il manque cette classe org.aspectj.util.PartialOrder$PartialComparable.

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<aop:config proxy-target-class="true" />

 

Troisième étape, en ajoutant le jar aspectjweaver (moins lourd que le aspecttools), ça a marché.

Donc c'était bien l'instanciation de ma classe via un JDK Proxy plutôt que via un CGLIB qui a changé la donne.

 

Pour aller plus avant :

- ma classe hérite de org.apache.commons.configuration.CompositeConfiguration

- j'ai essayé d'en extraire une interface pour utiliser les JDK Proxy plutôt que les CGI : échec sur les premiers tests. J'ai laissé filé.

- un mystère que je n'ai pas creusé non plus : pourquoi le fait d'utiliser le proxy-target-class sur le tag aop:config demande plus de fonctionnalités (PartialOrder manquant) que sur tx:annotation-driven ?

- les JDK proxy sont conseillés car ils implique une programmation par interface (pour ceux qui aiment...)

 

Moralité ( il est mort alité...) :

- d'où l'importance de ne pas laisser faire la configuration Spring à n'importe qui, de bien comprendre les tags et leur portées.

- contrôler la portée de vos component-scan, ça aide d'avoir des tests rapides...

 

Mise à jour :

Le problème a aussi une autre conséquence qui bloque le comportement Autowired:

- Si une classe CLASSE_REELLE (@Component ) implémente une interface INTERFACE_GENIALE

- Une classe B (de test par exemple) essaye d'injecter A directement

- aop:config n'est pas configuré pour empêcher l'utilisation des proxy Java ! Spring décide par défaut d'utiliser les proxy dès qu'une interface est présente. (cf ce lien :  JDK- and CGLIB-based proxies)

Conséquence : Spring ne qu'injecter des variables de types INTERFACE_GENIALE et pas de type CLASSE_REELLE. Seules les interfaces sont injectables.

 

Spring Boot et CXF

Rédigé par gorki Aucun commentaire

Le problème :

SpringBoot c'est assez pratique, le REST est géré de base avec Spring Boot MVC, mais parfois on a aussi besoin d'un serveur SOAP et là souvent CXF est utilisé plutôt que Spring MVC...)

Petit pense bête car les solutions trouvées sur le net me semble :

- compliquée : en utilisant Spring integration

- incomplète : déclaration simple

Solution :

En trois étapes :

  1. - Utiliser un fichier spring externe à Spring Boot
  2. - Déclarer la servlet CXF
  3. - Configurer Spring et CXF

Point 1 et 2 : dans l'application Spring Boot

Attention :
- dans notre exemple, CXF va gérer les URLs commençant par /soap/
- ne pas oublier de démarrer la servlet CXF

package com.test.springboot.cxf

import javax.annotation.PreDestroy;

import org.apache.cxf.transport.servlet.CXFServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/**
 *
 */
@Configuration
@ImportResource("classpath:spring-cxf.xml")
@ComponentScan
@EnableAutoConfiguration()
public class SpringBootCxf {
    private static final Logger LOGGER = LoggerFactory.getLogger(SpringBootCxf.class);

    public static void main(final String[] args) throws Exception {
        SpringApplication.run(SpringBootCxf.class, args);
    }

    @Bean
    public ServletRegistrationBean cxfServlet() {
        ServletRegistrationBean servletDef = new ServletRegistrationBean(new CXFServlet(), "/soap/*");
        servletDef.setLoadOnStartup(1);
        return servletDef;
    }

    @PreDestroy
    public void exit() {
        LOGGER.info("Exiting");
    }
}

Point 3 : Le fichier de configuration Spring - CXF

Attention :
- le point important ici est le lien entre le fichier XML et le composant qui implémente le service :

implementor="#eventServiceSoap"

Fichier XML complet :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:soap="http://cxf.apache.org/bindings/soap"
	xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- these are included in the dependency jar -->
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<!-- event -->
	<jaxws:endpoint id="eventServiceEndpoint" implementor="#eventServiceSoap"
		address="/event">
		<jaxws:properties>
			<entry key="schema-validation-enabled" value="false" />
		</jaxws:properties>
		<jaxws:binding>
			<soap:soapBinding version="1.2" mtomEnabled="true" />
		</jaxws:binding>
	</jaxws:endpoint>	
</beans>

Ensuite on peut utiliser un composant "Autowired" by Spring :
- EventManagerBean est le résultat de la génération WSDL2Java

@Component("eventServiceSoap")
public class EventServiceImpl implements EventManagerBean {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(EventServiceImpl.class);

    @Autowired
    EventRepository eventRepository;

    ...

 

 

 

 

Git, les branches et pourquoi mes fichiers ne disparaissent pas

Rédigé par gorki Aucun commentaire

Le problème :

C'est tout bête, c'est expliqué plein de fois partout, mais comme je l'ai compris un peu sur le tard...

Pourquoi quand je change de branche GIT, mais fichiers ne sont pas uniquement ceux de la branche sur lequel je viens de switcher ?

 

Solution :

Tout simplement parce que les fichiers étaient soit dans la working directory, soit dans le stage.(index)

En fait le checkout ne met à jour que les fichiers déjà commités dans les branches et ne touche pas aux fichiers stage (index) ou dans le working directory.

Autrement dit tant que vos fichiers ne sont pas commités, il resteront présent (sauf si vous les supprimer, clean la branche, etc...)

Et autre chose importante : vous pouvez modifier tout ce que vous voulez, changer de branche et commiter dans cette branche sans impacter les autres (conséquences du point précédent). Ce qui permet de commencer un travail, de se dire "mince ! je devais faire une branche, checkout d'une nouvelle branche et commit"

Liens utiles :

- ce que j'aurais aimé savoir avant de commencer GIT. Cela sous entend de prendre du temps avant de commencer à jouer avec GIT.

- les différents espace GIT et comment faire passer les fichiers de l'un à l'autre

- les différents espace GIT en plus détaillé

Enterprise Architect et référentiel partagé MYSQL

Rédigé par gorki Aucun commentaire

Le problème :

Pas vraiment de problème si ce n'est le problème des drivers en 32 ou 64 bits. C'est plus un pense-bête.

EA <-> base Mysql via driver ODBC

La documentation d'installation du driver ODBC : ici

Solution :

  1. Installer EA
  2. Installer un kit Microsoft Visual C++ 2010. Attention à prendre la même version (32 ou 64 bits) que le driver ODBC
  3. Installer un driver Mysql
    • Chez moi j'ai eu un problème :
      • si pas de driver x64, pas reconnu dans ODBC,
      • si pas de driver x32 EA ne se connecte pas (il est en 32 bits).
    • Bref il faut les deux... quelque soit le kit VC++....
  4. Créer un utilisateur sur votre base MYSQL, une base, donner les droits à l'utilisateur pour accéder à la base
  5. Créer les tables via les scripts EA
  6. Créer une source de données ODBC
    1. Panneau de configuration > Source de données (ODBC)
    2. Source de données utilisateurs > Ajouter
    3. Adresse du serveur + login/mdp + base
  7. Ouvrir EA
  8. Ouvrir le projet à commiter
    1. Vérification de l'intégrité : Tools | Data Management | Project Integrity Check
    2. Transfert :
      • Tools | Data Management | Project Transfert
      • Choisir le type : EAP vers DMBS (fichier vers BDD)
      • Choisir le fichier source
      • Choisir la connexion ODBC et remplir les informations (utiliser la connection ODBC créée précdemment)
      • Cocher :
        • "Return matched rows instead of affected rows"
        • "Allow big result sets"
  9. Ouvrir le projet avec EA
    1. File | Open | Connect to server | Connection Wizard
    2. Choisir la connexion ODBC et remplir les informations
Fil RSS des articles