Archive for the ‘maven’ Category

Handling multiple verticle deployment
April 4, 2014

Every Vert.x module needs a single point of start.
Once your application has many verticles interacting you’ll need one verticle to start them all, one verticle to find them, one verticle to bring them all and in the darkness bind them (I’m sorry).
For this particular task I prefer to use javascript. I tend to think of this verticle as the start script of my application, so I like it to be easy to write and I found the javascript syntax to be a good fit on this.

My deployment verticle

I usually name it app-deployer.js and I place it in src/main/javascript (I’ll explain below how to add it to Maven).

var container = require("vertx/container")
var console = require("vertx/console")
var config = container.config;

var skipDeploy;
if (config.skipDeploy) {
  skipDeploy = config.skipDeploy;
} else {
  skipDeploy = [];
}

const verticles = [
  {
    name : "con.locademiaz.vertx.FirstVerticle",
    instances : 1,
    config : {
      foo_param : config.bar_param
    }
  }
];

deployVerticles(verticles, 0);

function deployVerticles(verticles, verticleIndexToDeploy) {
  if (verticleIndexToDeploy < verticles.length) {
    const verticle = verticles[verticleIndexToDeploy];
    const verticleName = verticle.name;
    if (skipDeploy.indexOf(verticleName) == -1 ) {
      container.deployVerticle(
        verticleName,
        verticle.instances,
        verticle.config,
        function(err, deployID) {
          if (!err) {
            console.log("[Ok] " + verticleName);
            deployVerticles(verticles, verticleIndexToDeploy + 1);
          } else {
            console.log("[Fail] " + verticleName + " -> " + err.getMessage());
          }
        }
      )
    } else {
      console.log("[Skip] " + verticleName);
      deployVerticles(verticles, verticleIndexToDeploy + 1);
    }
  }
}

In this file you can do all kinds of tricks.
One of my preferred ones is to add a list of blacklisted verticles. This is useful for testing because you can deploy this file, getting your all system deployed, and mock some behavior inside your test.
Also, as I like to keep my external configuration lean, it is here where I manipulate what is passed by the command line and adapt it to each verticle needs.

Extending your Maven configuration

Following what is explained in my previous post this is how you add your verticle deployer to your Maven configuration

pom.xml

Add the resource folder

<project>
  ...
  <build>
    ...
    <resources>
      ...
      <resource><directory>src/main/javascript</directory></resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>

And now, because I’m a control freak, I don’t like unnecessary files ends up in the jar for my project, so I exclude them from the package as follows:

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <excludes>
            <exclude>app-deployer.js</exclude>
          </excludes>
        </configuration>
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

And that’s it, now you have a nice entry point for your module.
Enjoy.
.

Vert.x Java project – Quick start
April 3, 2014

After having 41 successful-n-productive™ Vert.x systems running, I have distilled a few practices which makes worth to share.

Building environment

I’ve decided to go with Maven for managing dependencies and build cycle. Vert.x has support for Gradle but I dropped this option because I just wanted a simple descriptive language for my project, instead of a full imperative language for this purpose. Nothing against Gradle though.

Vert.x modules

Vert.x recommends to organize your application as modules. Beside all the technical benefits of this practice (classloader isolation, dependency management, etc), I would also like to add that this is a great way to define different areas of development across your team. This, along with a clear document of the services provided and exposed by the modules within its interfaces, will help you to isolate different application concerns as the building blocks for the whole system.

Initial setup

Vert.x has a Maven Archetype for getting started, but IMHO it doesn’t do well with Maven files, and it also generates a single project containing examples for every supported language. BTW, I’ve sent a pull request for this, that has never discussed.
This post will assume you have some knowledge of Maven, its structure and usage.

pom.xml

You can read an in depth explanation of the structure of this file here (this is not yet ready)

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.locademiaz.vertx</groupId>
  <artifactId>quick-start</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-platform</artifactId>
      <version>2.1M2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>testtools</artifactId>
      <version>2.0.2-final</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/js</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
        <filtering>true</filtering>
      </testResource>
    </testResources>

    <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>2.5.1</version>
         <configuration>
           <source>1.7</source>
           <target>1.7</target>
         </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <outputDirectory>${project.build.directory}/mods</outputDirectory>
          <finalName>${module.name}</finalName>
          <appendAssemblyId>false</appendAssemblyId>
          <descriptors>
            <descriptor>src/main/assembly/mod.xml</descriptor>
          </descriptors>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>io.vertx</groupId>
        <artifactId>vertx-maven-plugin</artifactId>
        <version>2.0.1-final</version>
      </plugin>
    </plugins>
  </build>
  <properties>
    <module.name>${project.groupId}~${project.artifactId}~${project.version}</module.name>
  </properties>
</project>
mod.xml

Vert.x defines a structure for its modules, so, below is a Maven Assembly definition for building it. In concordance with the pom.xml defined above, this must be placed in the src/main/assembly directory.

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

  <id>mod</id>

  <formats>
    <format>zip</format>
    <format>dir</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <useProjectArtifact>false</useProjectArtifact>
      <outputDirectory>lib/</outputDirectory>
      <scope>runtime</scope>
      <fileMode>664</fileMode>
    </dependencySet>
  </dependencySets>

  <includeBaseDirectory>false</includeBaseDirectory>

  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>**</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>
Your first verticle

Now we have everything setup to start coding. Create a FirstVerticle.java file inside the src/main/java/com/locademiaz/vertx directory with the following content:

package com.locademiaz.vertx;

import org.vertx.java.platform.Verticle;

public class FirstVerticle extends Verticle {

    @Override
    public void start() {
        container.logger().info("Your first verticle has been started!");
    }
}
mod.json

The final part of a Vert.x module is its descriptor. You can find a comprehensive list of its fields here. Place this file in the src/main/resources directory

{
    "main":"com.locademiaz.vertx.FirstVerticle",
    "deploys":"${module.name}",
}

Running your module

Development phase

As you can see in the pom.xml file above the vertx-maven-plugin is configured in lines 72-76. Having this configured, allows you to run, directly from your source code, Vert.x with your module just in place. For doing so just run:

$ mvn clean package vertx:runMod

et voilà, you should see the message logged into the system console

Productive phase

As presented here, the .zip generated in the target/mods by the command

$ mvn clean package

is ready to be deployed. You can drop it into your Nexus repository, or into your local maven structure, or you can also use the handy runzip option:

$ vertx runzip target/mods/com.locademiaz.vertx~quick-start~0.1-SNAPSHOT.zip

In the upcoming entries you can expect more insights about handling deployment, configuration, vert.x packaging, testing, continuous integration and any other shenanigan I encounter in this pleasant trip. Stay tuned.

Jetty + DataSource + JTA
April 18, 2010

Working on my next post about Drools Flow Work Items I wanted to have a one click example. This example involves a web application so I started with Jetty which fits perfect for a mvn jetty:run example. In the standalone example we run our own JNDI directory provided by Bitronix. Jetty has JNDI directory embedded so we have to register the datasource and the transaction manager. Doing this task for a totally jetty noob could be a little difficult and time consuming. So, hoping nobody has to spend too much time on this, I’ll try to summarize the steps I did to make this.
(more…)

Sobre la Programación Orientada a IDE©
September 27, 2009

Hace algún tiempo que vengo luchando contra este concepto[*]. La idea viene de la falacia que todo hay que hacerlo desde dentro de la IDE. Así, la IDE es la que termina guiando nuestro desarrollo y volviéndolo uno con la decisiones unilaterales que han tomado sus desarrolladores.
No estoy para nada en contra de las IDE, solo de las IDE que te obligan a hacer las cosas de la manera que se les antoja. Ésta es una herramienta y no quiero que me obligue a nada, yo quiero usarla como se me antoje y mi profesionalismo me indique para expresar mi arte.

Yendo al contexto Java, que es donde me siento cómodo seguro por el momento, me he encontrado con incontables casos donde a la pregunta de “cómo es su ciclo de deploy” la respuesta comienza con “exportamos el proyecto desde eclipse”…
Por qué esto está mal (sin orden particular)?
• Se depende de un humano para armar ‘entregables’ (no hay integración continua)
• Atenta contra la posibilidad de incluir a un nuevo integrante al equipo que haga uso de otra herramienta
• Tenemos que manejar las dependencias desde el eclipse
Otros efectos colaterales:
• Tendencia a ensuciar los controladores de versiones con cosas propias de las IDE
• Tendencia a nunca entender lo que una IDE hace tan mágicamente (aunque esto es algo inherente a la estupidez en cualquier contexto)
Soluciones a esto:
• Uso de Maven

Por qué Maven?
Maven no es nada de otro planeta ni hace magias oscuras. Hace muy pocas cosas y las hace bien. Mediante el uso de Maven se obtienen algunos puntos muy positivos: controlar dependencias, manejar ciclos de deploy (incluyendo el empaquetado) y unificar (de manera IDE agnóstica) convenciones a la hora de trabajar. Ésto último tiene un punto a destacar alucinante, que venga alguien totalmente ajeno a nuestro desarrollo y no se sienta [tan] perdido frente a cientos de archivos de código; va a saber dónde estan los fuentes, dónde buscar tests, dónde mirar a grandes rasgos qué bibliotecas se usan y va a poder generar un entregable corriendo un solo comando.

Qué es lo peor que podés hacer?
Intentar ajustar maven a tu proyecto y no al revés. Maven es una herramienta para organizar, que si bien deja que modifiques sus convenciones al hacerlo estarías perdiendo muchas de las cosas que destaqué en la pregunta anterior. Cuando te convenzas que estas son las cosas que querés que tu proyecto cumpla, pagá el precio por haber comenzado por la senda del mal y purga tu alma moviendo archivos y repensando los paquetes que tiene tu sistema.

Qué es algo feo feo de ver?
A alguien usando JBoss Developer Studio para mostrar las maravillas de Seam (básicamente hot deploy) cuando realmente conciliar estas maravillas con las ‘buenas prácticas’ antes mencionadas es imposible (y lo peor es que la mayoría de la gente valora más un entorno de desarrollo a-La PHP en lugar de un proyecto ordenado).

Quiénes son los más horrorizados con no comer/ver la tele/dormir con la IDE?
Los desarrolladores .Net . Ellos han comprado una serie de preceptos guiados por Visual Studio y sus wizards, que se les hace arcaico y elitista tratar de usar herramientas de línea de comando, el resto simplemente “la complican de gusto”.

Qué es lo que tendría que hacer un desarrollador nuevo cuando entra a un equipo?
• git clone [o el scm que quieran]
• mvn eclipse:eclipse [o la ide que quieran]
• [abrir la ide y buscar las cosas como tu intuición te indica]
• mvn package
• [deploy]
• [probar la aplicación]

Qué alternativas similares hay?
Para Java ninguna[**] y no me parece mal. Creo que se puede confiar bastante en los desarrolladores de maven como para que guien este camino.
Hablar de ciclos de desarrollo en otros lenguajes no puedo, solo comentar que en C se adolece del mismo problema que generó Ant en su momento, Autoconf/Autotools son infinitamente poderosos, infinitamente complejos y no existe una manera estándar de hacer las cosas, realmente una pena; apenas crece un poquito un proyecto C meterse es una tarea heroica.

[*]: término que nunca antes había escuchado :)
[**]: ant+ivy me parece una aberración mutante