Archive

Archive pour juillet 2008

Créer un packaging maven2

Maven 2 propose d’origine les types de packaging des différents composants java / j2ee : jar, war, ejb et ear.

Cependant, il faut parfois utiliser des types de packaging moins conventionnels qui nécessitent la création d’un packaging maven dédié.

Pour exemple, je vais créer un packaging nommé “custom”, qui va créer des archives avec l’extension .cust et qui contient les classes et ressources du projet dans un répertoire “classes” et les dépendances du projet dans un répertoire lib.

  • Première étape : créer le plugin maven2 à l’aide de l’archetype plugin :
    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-plugin -DgroupId=org.tartachuc.m2 -DartifactId=my-custom-packaging
  • Ajouter dans le descripteur de projet pom.xml le projet maven-archiver :
    
    <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-archiver</artifactId>
    <version>2.2</version>
    </dependency>
    
  • Modifier le MOJO généré par l’archetype pour qu’il prenne en charge le packaging.
    • Renommer la classe MyMojo en CustomPackageMojo
    • Changer le commentaire en entête de la classe pour préciser le goal : custom et la phase : package
      
      /**
      * Goal which creates a custom package
      * @goal custom
      * @phase package
      */
      
    • Ajouter au Mojo les attributs et leur documentation qui vont permettre de récupérer des informations sur le projet qui utilise le plugin :
      /**
      * The maven project.
      * @parameter expression="${project}"
      * @required
      * @readonly
      */
      private MavenProject project;
      
      /**
      * The directory containing generated classes.
      * @parameter expression="${project.build.outputDirectory}"
      * @required
      * @readonly
      */
      private File classesDirectory;
      
      /**
      * Build directory.
      * @parameter expression="${project.build.directory}"
      * @required
      */
      private File buildDirectory;
    • Ajouter au Mojo les attributs qui vont permettre de créer l’archive :
      /**
       * The Jar archiver needed for archiving.
       * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
       * @required
       */
      private JarArchiver jarArchiver;
      
      /**
       * The maven archive configuration to use
       * @parameter
       */
      protected MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
    • Ce packaging maison nécessite d’archiver les dépendances du projet, dans un premier temps les dépendances vont être copiées dans un répertoire de travail. Pour pouvoir configurer ce répertoire de travail, ajouter un attribut au Mojo
      /**
       * Lib directory
       *
       * @parameter expression="${project.build.directory}/custom/libs"
       * @required
       */
      private File libDirectory;
    • Il faut maintenant implémenter la méthode “execute” qui est le point d’entrée du Mojo.
      /** {@inheritDoc} */
      public void execute() throws MojoExecutionException {
          // Compute archive name
          String archiveName = project.getBuild().getFinalName() + ".cust";
          File custFile = new File(buildDirectory, archiveName);
          // Configure archiver
          MavenArchiver archiver = new MavenArchiver();
          archiver.setArchiver(jarArchiver);
          archiver.setOutputFile(custFile);
      
          // copy runtime libs
          copyLibs();
          try {
              // archive classes
              archiver.getArchiver().addDirectory(classesDirectory, "classes/");
              // archive libs
              archiver.getArchiver().addDirectory(libDirectory, "lib/");
              // create archive
              archiver.createArchive(project, archive);
              // set archive as artifact
              project.getArtifact().setFile(custFile);
          } catch (ArchiverException e) {
              throw new MojoExecutionException("Exception while packaging", e);
          } catch (ManifestException e) {
              throw new MojoExecutionException("Exception while packaging", e);
          } catch (IOException e) {
              throw new MojoExecutionException("Exception while packaging", e);
          } catch (DependencyResolutionRequiredException e) {
              throw new MojoExecutionException("Exception while packaging", e);
          }
      }
      
      /**
       * Copy runtime libs
       * @throws MojoExecutionException
       */
      protected void copyLibs() throws MojoExecutionException {
          try {
              Set artifacts = project.getArtifacts();
              for (Iterator iter = artifacts.iterator(); iter.hasNext();) {
                  Artifact artifact = (Artifact) iter.next();
                  ScopeArtifactFilter filter = new ScopeArtifactFilter(
                          Artifact.SCOPE_RUNTIME);
                  if (!artifact.isOptional() && filter.include(artifact)
                          && "jar".equals(artifact.getType())) {
                      FileUtils.copyFileToDirectory(artifact.getFile(),
                              libDirectory);
                  }
              }
          } catch (IOException e) {
              throw new MojoExecutionException("Error copying libs", e);
          }
      }    
  • Il faut maintenant indiquer à maven quel MOJO exécuter lors du cycle de vie de notre nouveau packaging. Pour cela, le plugin doit inclure un descripteur plexus nommé components.xml à placer dans répertoire src/main/resources/META-INF/plexus.
    <?xml version="1.0" encoding="UTF-8"?>
    <component-set>
      <components>
        <component>
          <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
          <role-hint>cust</role-hint>
          <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
          <configuration>
            <type>cust</type>
            <extension>cust</extension>
            <language>java</language>
          </configuration>
        </component>
        <component>
          <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
          <role-hint>cust</role-hint>
          <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
          <configuration>
            <phases>
              <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
              <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
              <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
              <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
              <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
              <package>org.tartachuc.m2:my-custom-packaging:custom</package>
              <install>org.apache.maven.plugins:maven-install-plugin:install</install>
              <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
            </phases>
          </configuration>
        </component>
      </components>
    </component-set>

    Nous avons inséré notre MOJO (org.tartachuc.m2:my-custom-packaging:custom) lors de la phase de packaging. les autres MOJO sont repris des plugins standards de maven.

  • Pour installer le plugin dans votre référentiel local, exécuter la commande
    mvn install
  • Pour utiliser le packaging nouvellement créé, il faut créer un nouveau projet et déclarer le packaging cust et le plugin créé ci-dessus comme extension du build.
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.tartachuc.m2</groupId>
      <artifactId>my-custom-project</artifactId>
      <packaging>cust</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>my-custom-project uses a custom packaging</name>
      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-orm</artifactId>
          <version>2.5.3</version>
        </dependency>
      </dependencies>
      <build>
        <extensions>
          <extension>
            <groupId>org.tartachuc.m2</groupId>
            <artifactId>my-custom-packaging</artifactId>
            <version>1.0-SNAPSHOT</version>
          </extension>
        </extensions>
      </build>
    </project>
  • Here it is :-)
Tags:

Scrum : le virus est en moi

5 juillet 2008 1 commentaire

Pour continuer mon apprentissage de scrum, j’ai commandé ce soir deux livres :

Et pour être prêt le jour J, j’ai aussi commandé deux jeux de carte de planning poker.

Sortie de Subversion 1.5 et Trac 1.1

3 juillet 2008 1 commentaire

Subversion, le populaire gestionnaire de sources et Trac, le wiki / gestionnaire de taches ont chacun publié une nouvelle version majeure.

Pour Subversion, c’est la version 1.5.0 qui vient d’être annoncée, après de nombreuses versions candidates (release candidate). La principale nouveauté est le “merge tracking”, les reports entre différentes branches en sont grandement simplifiés. Il faut avouer que le système précédent imposait une discipline forte dans les commentaires des merge et une gymnastique intellectuelle un peu compliquée.

Je vous encourage à consulter les notes de version pour plus de détails.

La version adaptée de TortoiseSVN, le client visuel pour Windows est également publiée.

L’équipe Trac a elle annoncée la version 0.11, la grosse nouveauté est la possibilité de personnaliser le workflow des taches pour l’adapter à votre organisation. A noter que le plugin d’administration WebMin est maintenant inclus.

Une version francisée est disponible chez trac-hacks

J’attends impatiemment les versions suivantes qui vont amener l’internationalisation et la gestion de plusieurs projets dans un seul référentiel.

Trac est très lié à Subversion, il permet notamment de lier les modifications du code aux taches référencées dans trac.

Formation Scrum par Jeff Sutherland

Je viens de suivre la formation Scrum donnée par Jeff Sutherland et Xebia.

Nous étions 30 et je pense que tout le monde connaissait déjà les grands principes des méthodes agiles et de Scum, Jeff a donc pu passer beaucoup de temps à nous partager son énorme expérience, à nous décrire le fonctionnement de sa société ainsi qu’a répondre aux nombreuses questions.

Jeff a énormément de charisme et présente beaucoup de données sur la productivité des équipes, il doit être capable de convaincre n’importe quel DSI :-)

Si vous êtes intéressés par Scrum ou que vous désirez améliorer votre pratique, je vous conseille vivement cette formation/certification ScumMaster.

De mon coté ça n’a fait que décupler mon désir de travailler sur des projets agiles, objectif numéro un de ce deuxième semestre !

Edit : Frédéric Doillon a posté un article sur sur ces deux jours.

Campus d'été Norsys et Atelier RIA

Il est temps de poster de nouveaux articles, j’ai un peu délaissé ce blog ces dernières semaines pour tout un tas de bonnes excuses, notamment 4 semaines de congés en famille au bout du monde.

En ce moment se déroule le campus d’été de Norsys, SSII qui m’emploie depuis 8 ans. A cette occasion j’ai animé une formation de trois jours, j’ai décidé de consacrer deux jours à un atelier de découverte de frameworks RIA et un jour au profling d’applications Web à l’aide OpenSTA et JProfiler.

Les technologies choisies par les 4 groupes ont étés : Wicket, GWT, Flex et JSF/MyFaces avec Seam.

Chaque groupe avait une backlog de fonctionnalités à implémenter

Mon ressenti à l’issu des démonstrations de chaque équipe est que GWT et Flex ont permis aux équipes de réaliser le plus de fonctionnalités tout en montrant un grand potentiel.

Les deux plateformes ont des points communs :

  • Capacité à gérer l’état coté client et donc utiliser des services sans état coté serveur, c’est un énorme gain pour la scalabilité des applications.
  • Utilisation d’un langage de développement intermédiaire qui est projeté vers une plate-forme cible ( Java -> DHTML/Ajax pour GWT, MXML/ActionScript -> Flash pour Flex)
  • Capacité à développer en mode visuel (Flex Builder ou GWTDesigner)

Elles s’appuient tout de même sur des fondations fort différentes :

  • Le modèle utilisé par GWT est beaucoup plus ouvert que celui d’adobe : la plate-forme flash reste ultra dépendante d’adobe et certaines plate-formes ne sont pas (encore) couvertes (IPhone par exemple).
  • Flex propose toutes les animations vectorielles de Flash et dans certains contextes ça peut faire la différence alors que GWT ne modifie pas “l’expérience utilisateur” par rapport aux applications Web classiques

A suivre, la formation Scrum par Jeff Sutherland.

Suivre

Get every new post delivered to your Inbox.