Retour sur Devoxx 2016 : WildFly Swarm

Cette année Devoxx France s’est tenu pendant 3 jours du 20 au 22 avril au Palais des Congrès de Paris. Infotel a permis à de nombreux collaborateurs de participer à cette éventement.

Frédéric JOSEPH nous fait un retour sur WildFly Swarm


WildFly Swarm – A quoi ça sert ?

WildFly, anciennement JBoss Application Server, est un serveur d’application Java EE 7 de la société Red Hat.


WildFly Swarm est un projet se basant sur WildFly 9 et offrant une approche innovante pour le packaging d’applications Java EE en incluant le code applicatif et les dépendances du serveur au sein d’un unique jar exécutable (fat-jar ou uberjar).

Serveur d’applications monolithique vs « uberjar »

Lors de l’utilisation d’un serveur d’applications monolithique, il faut préalablement installer le serveur puis déployer l’application dessus.

Ce serveur fournit généralement bien plus de fonctionnalités (EJB, JMS, JSF…​) que celles exploitées par l’application Java EE.

Dans un uberjar « WildFly Swarm », seules les composantes de WildFly AS (on parle de « fraction ») nécessaires à l’application sont embarquées dans le jar.
On obtient ainsi un serveur d’applications personnalisé plus léger et démarrant plus rapidement qu’un serveur Java EE « classique ».

De part son fonctionnement, WildFly Swarm incite les développeurs à découper une application Java EE en plusieurs modules distincts et autonomes, afin de ne pas embarquer toute la stack Java EE dans un unique fichier jar (qui serait très volumineux).


Chacun des modules peut alors être un micro-service à part entière pouvant être remplacé, mis à jour ou déployé sur de nouvelles machines de manière indépendante des autres modules.


Du fait qu’une application soit constituée d’un unique jar exécutable, il devient également très facile d’automatiser son déploiement en l’intégrant par exemple au sein d’un conteneur docker (plugin Maven docker-maven-plugin).

Mise en oeuvre

L’utilisation de WildFly Swarm est vraiment très simple avec Maven.

Pré-requis

Les versions minimales pour exploiter WildFly Swarm sont :

  • JDK 8

  • Maven 3.2.5

Modification du POM

  • Package
    <packaging>jar</packaging>

    Il devient inutile de réaliser le package de l’application sous la forme d’un war.

    Toutefois, cela reste possible et l’on obtiendra une archive war valide qui sera encapsulée dans le uberjar à la place du jar.


  • Plugin Maven

    Ajout du plugin Maven

    <plugin>
        <groupId>org.wildfly.swarm</groupId>
        <artifactId>wildfly-swarm-plugin</artifactId>
        <version>${version.wildfly-swarm}</version>
        <configuration>
          <mainClass>com.example.rest.Main</mainClass>
          <properties>
            <swarm.http.port>8080</swarm.http.port> <!-- Already the default value -->
            <swarm.context.path>/</swarm.context.path> <!-- Already the default value -->
          </properties>
          <jvmArguments>
            <jvmArgument>-Xmx128m</jvmArgument>
          </jvmArguments>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>create</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
  • Dépendances

    Ajout des fractions du serveur d’applications dont l’application à besoin.

    Exemple pour JAX-RS

    <!-- Java EE 7 dependency -->
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- Wildfly Swarm Fractions -->
    <dependency>
      <groupId>org.wildfly.swarm</groupId>
      <artifactId>jaxrs</artifactId>
    </dependency>

Code de l’application

@Path("/hello")
public class HelloWorldEndpoint {
 
  @GET
  @Produces("text/plain")
  public Response doGet() {
    return Response.ok("Hello from WildFly Swarm!").build();
  }
}


@ApplicationPath("/rest")
public class RestApplication extends Application {
}


public class Main {
 
    public static void main(String[] args) throws Exception {
 
        Container container = new Container();
 
        JAXRSArchive deployment = ShrinkWrap.create(JAXRSArchive.class, "my-app.war");
        deployment.addClass(RestApplication.class);
        deployment.addClass(HelloWorldEndpoint.class);
        deployment.addAllDependencies();
        container.start().deploy(deployment);
    }
}


La classe Main sert à configurer le conteneur Java EE et à déployer les ressources programmatiquement (facultatif si on package en war).

Génération/Exécution de l’application

La génération de l’archive s’effectue de manière classique.

mvn package

Le dossier target contient alors le jar de l’application ainsi qu’une archive *-swarm.jar

Si on ouvre cette archive jar, on trouve principalement :

  • un répertoire m2repo contenant l’ensemble des librairies nécessaires à l’application

  • un répertoire _bootstrap contenant le jar de l’application

  • un répertoire META-INF contenant les fichiers de configuration nécessaires au uberjar dont notamment :

    • wildfly-swarm.properties : propriétés définies par l’utilisateur (ou par défaut)

      #Generated by WildFly Swarm
      #Sun May 08 14:52:08 CEST 2016
      swarm.bundled.dependencies=true
      swarm.context.path=/
      swarm.http.port=8080
      swarm.app.artifact=hello-swarm-infotel.jar
    • MANIFEST.MF : fichier Manifest standard indiquant la classe Main de bootstrap (Main-Class), ainsi que la classe Main de l’application (Wildfly-Swarm-Main-Class).

      Manifest-Version: 1.0
      Main-Class: org.wildfly.swarm.bootstrap.Main
      WildFly-Swarm-Main-Class: com.example.rest.Main

      Les autres fichiers de configurations servent à lister les dépendances de l’application et des modules WildFly Swarm.

Le lancement de l’application s’effectue à l’aide de la commande java -jar *-warm.jar ou avec la commande maven

mvn wildfly-swarm:run

L’application est alors opérationelle comme une application déployée sur un serveur Java EE « classique ».

Et voici comment réaliser un micro-service, exposant un Web Service REST, sous la forme d’un uberjar contenant un serveur Java EE personnalisé et dont la taille est seulement de 38.6 Mo.


Pour aller plus loin

Les possibilités de WildFly Swarm vont bien au-delà des limites de cet article (security, monitoring, message JMS…​).


Quelques liens utiles :



seedstack.org : la solution open source de PSA

seedstack_image


Un besoin permanent de productivité et de cadrage

Bien avant l’apparition du langage Java, PSA construisait déjà des frameworks permettant d’accélérer le développement logiciel et de répondre au mieux à ses besoins métiers. Lorsque Java est arrivé avec son lot de frameworks et d’outils, les frameworks PSA ont évolués pour devenir des couches d’intégration autour de frameworks existants et ainsi fournir des outils communs à l’ensemble de ses développeurs. Cependant, ce travail d’intégration d’outils qui n’ont pas été prévus pour fonctionner ensemble et difficiles à configurer a fini par montrer ses limites. De nombreux projets restaient bloqués sur des frameworks obsolètes parce que « montée de version » voulait dire réécriture complète du projet. Le manque de modularité se faisait cruellement sentir. De plus, même si les outils étaient communs (Spring, Struts, etc.), ils leur manquaient de l’opinion et des bonnes pratiques. C’est à dire qu’à chaque fois qu’un développeur changeait de projet il avait tout à réapprendre: organisation, conventions, etc…


Un programme d’entreprise

Début 2013, PSA a donc décidé de rassembler une équipe pour faire face à ce problème. Composée de deux architectes et de deux à huit développeurs selon le plan de charge (moitié PSA, moitié collaborateurs Infotel en mission pour PSA), l’équipe s’est donc attelé à la tâche : réécrire une solution complète nommée SeedStack. Dès l’origine du projet, des orientations structurantes ont été faites.


Des choix novateurs

Premièrement, la stack n’intègrerait pas Spring, comme les précedants frameworks. Elle aurait un noyau plus léger et plus modulaire pour éliminer le couplage. Le micro framework Nuun.io a été choisi pour d’adresser ces éléments grace à son architecture kernel/plugin. Il confère une grande agilité à SeedStack qui a pu grandir et se réorganiser depuis deux ans sans rencontrer aucun obstacle. Chaque plugin expose ses API (Application Programming Interface) qui servent de contrats avec les développeurs et facilitent ainsi les montées de version. Certains exposent également des SPI (Service Provider Interface) permettant aux développeurs d’étendre les fonctionnalités du framework et donc de répondre à tous leurs besoins.


Mettre le métier au cœur du développement et le cadrer

Deuxièmement, il a été décidé de promouvoir des styles d’architectures de type REST (Representational State Transfer) et DDD (Domain Driven Design). Le REST via ses API hypermedia permet aux applications d’exposer des ressources Web simples à utiliser, qui garantissent une compatibilité à long terme tout en permettant une grande évolutivité. Son support a été développé en se basant sur les spécifications JAX-RS (via Jersey) et HAL. Le DDD quant à lui permet de se recentrer sur le domaine métier. Il remet la conception au coeur du travail de développeur, alors qu’elle est trop souvent délaissée au profit d’architecture de type CRUD : correspondance 1-1 entre de la base de données et l’IHM. Aucune solution satisfaisante n’étant disponible pour son implémentation, il a été décidé de développer un nouveau framework adressant la partie tactique du DDD.

Enfin, pour la partie Web, un framework a été développé pour combiner le meilleur d’AngularJs, RequireJs, et Bootstrap. L’utilisation du REST côté serveur et d’une SPA (Single Page Application) côté UI permet ainsi, le découplage du front et du back qui peuvent maintenant avoir des cycles de vie séparés. Par ailleurs, ce framework Web n’est pas en reste côté modularité car il permet via un système de fragments de composer son application à partir de modules indépendants.


Une suite Open Source

Suite à ces choix SeedStack a connu un départ rapide et les gains en productivité ne se sont pas laissés attendre. La première version a été finalisée après seulement 6 mois de développement. Dès lors, elle a été intégrée par des projets pilotes, qui ont permis à la solution de se développer et de s’affiner. Avec un rythme de 3 versions par an, SeedStack a connu des évolutions fréquentes. Début 2015, une quarantaine de projets (dont la moitié en production) utilisaient déjà cette stack. Conscient de l’intérêt de sa solution, PSA a alors décidé de publier SeedStack sous une license libre : la MPL 2.0 (Mozilla Public License 2.0). Après un audit juridique et technique ainsi qu’un peu de refactoring, la stack a été publié sur GitHub en version béta en mai 2015. Puis, après quelques mois de travail une première version open source a été publiée en Juillet. Loin d’achever cette « success story », la mise en open source lance de nouveaux défis : tout d’abord continuer d’améliorer la stack, mais aussi communiquer et trouver de nouveaux partenaires.

Des premières contributions extérieures ont été enregistrées et je vous encourage tous à venir participer. Il n’y a pas de petites contributions ! Que ce soit de la documentation, des rapports de bug ou du code, toutes les contributions sont les bienvenues.