Starting with Vert.x 3 – Creating a new project
April 11, 2015

These are my first impressions on what have changed in Vert.x 3 from a regular java developer perspective.

Vert.x 3 has ripped off the old modules concepts in favor of a more straightforward approach. Now you don’t need to create a .zip file with an structure to deploy your application, instead, you run your application inside vert.x however you want. These is a great power and at first I found myself a little lost.

You can still download a vert.x distribution but, with the current state of the platform, I see it like an easy way to start making experiments (even in the many languages vert.x support) and it’s not necessary anymore for productive environments.

In Vert.x 3 you create your own main function, invoke a Vert.x factory, and voilà, you have the whole platform there to serve you. Indeed, you can see the io.vertx.core.Starter class, which is invoked by the executable bin/vertx in the distribution, to see there is nothing but CLI args parsing and building configurations for the factory I mentioned before.

From the v2 era I liked to have a main point written in javascript to deploying all my java verticles. I though it as my init script so it made sense to have it in an scripting language, I didn’t want to lose that. So now it’s my responsibility to create this structure. A few lines of code is worth a thousand words:
(Deprecated: see Update section below)

    public class Launcher {
        public static void main(String[] args) {
            Logger vertxLogger = LoggerFactory.getLogger(Launcher.class.getName());
            Vertx vertx = Vertx.vertx();
            vertx.deployVerticle("main.js", event -> {
                if (event.succeeded()) {
          "Your Vert.x application is started!");
                } else {
                    vertxLogger.error("Unable to start your application", event.cause());

            Runtime.getRuntime().addShutdownHook(new Thread() {
                public void run() {
                    final CountDownLatch latch = new CountDownLatch(1);
                    vertx.close(ar -> {
                        if (ar.succeeded()) {
                  "Your Vert.x application is stopped!");
                        } else {
                            vertxLogger.error("Failure in stopping Vert.x", ar.cause());
                    try {
                        if (!latch.await(2, TimeUnit.MINUTES)) {
                            vertxLogger.error("Timed out waiting to undeploy all");
                    } catch (InterruptedException e) {
                        throw new IllegalStateException(e);

In line 5 I deploy my main verticle.
Lines 13-32 are stolen from io.vertx.core.Starter to properly shutdown the application.

For this to run you just need a few dependencies: io.vertx:vertx-core:jar:3.0.0-milestone4:compile and io.vertx:vertx-lang-js:jar:3.0.0-milestone4:runtime

Packing your application

Now it’s just a matter of packing the application to make it runnable. There is a movement loving the concept of fatJar, I personally dislike it for various reasons, one of them is that I see it completely unnecessary, we are advanced Java developers, man up, setup you classpath and invoke the Main Class as the good lord says (well, that was too much).

In Maven this is extra easy, you just need to properly setup the maven-jar-plugin to write the MANIFEST and the maven-assembly-plugin to load an assembly descriptor. Then you can have a simple script for running it without even having to remember the name of your main jar. I use something like this:

    #!/usr/bin/env bash
    DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
    java -jar $DIR/libs/${}.${project.packaging} $@

Here is a minimal pom.xml briefing all the above ideas:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns=""



And also the dist.xml:

    <assembly xmlns=""

With this initial configuration, you run mvn package and you’ll got a tarball into the target/ folder, untar it and you’ll have a nice running script for your whole application.

Bonus track

I prefer to use Logback as my logging system, and in the old days we had to modify the vert.x distribution and the executable to get this support.
Nowadays you just add System.setProperty(LoggerFactory.LOGGER_DELEGATE_FACTORY_CLASS_NAME, SLF4JLogDelegateFactory.class.getName()); as the first line of your main, add the ch.qos.logback:logback-classic:jar:1.1.3:runtime dependency and you are there.
For the extra lazy, here is a simple logback.xml:

      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender" level="INFO">
          <pattern>[%-5level] %logger{15} - %msg%n</pattern>
      <logger name="io.vertx" level="INFO">
        <appender-ref ref="STDOUT" />
      <logger name="com.hazelcast" level="ERROR">
        <appender-ref ref="STDOUT" />
      <logger name="io.netty.util.internal.PlatformDependent" level="ERROR">
        <appender-ref ref="STDOUT" />
      <root level="INFO">

I also like to have an user accessible logging configuration, for this, you must add the following to the dist.xml file


and modify the java invocation line in to include -Dlogback.configurationFile=file:$DIR/logback.xml

I hope you find this useful and enjoy the great things Vert.x 3 has to offer.


I’ve been thinking and I rather see unnecessary to have my own main class which at the end will imitate the provided io.vertx.core.Starter. So I’ve simplified my initial deployment removing all references to my custom mainClass and with this

    #!/usr/bin/env bash
    DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
    java -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.impl.SLF4JLogDelegateFactory \
         -Dlogback.configurationFile=file:$DIR/logback.xml \
         -classpath "$DIR/libs/*" io.vertx.core.Starter run main.js \
         -conf $DIR/conf.json

Also, if you want to run your application using maven (useful for debugging) you just need to configure the org.codehaus.mojo:exec-maven-plugin like this:


Turn your Java apps Gnome-Shell friendly
August 30, 2011

The Problem

When you try to add a java application as favorite into the Gnome Shell‘s lateral dock and run it you’ll end up having duplicated icons, one for the launcher and one for the running app. This happens b/c the shell uses an application based system for grouping tasks, so the idea is, if you add an application as a favorite launcher and you start it you’ll end having that launcher icon highlighted. Internally the shell matches the running process with the Exec clause of the .desktop file .
This works well except for applications running inside a VM or being interpreted b/c those will share the same running process. On that situation the shell inspects the WM_CLASS X Window property [1] and matches it with the full name of the desktop file. E.g. if your applications has the WM_CLASS set as “mySwingApp”, for this to successfully matched in the dock with its launcher, that launcher must be called mySwingApp.desktop located according XDG.

Note: for inspecting that value on any window you just need to run xprop WM_CLASS and click into the target window

Why is this happening?

Even if you are creating a swing application from scratch there is no easy way to tweak that X Window property using plain and portable APIs. Taking a look into openjdk sources, this is how them manages it

String mainClassName = null;

StackTraceElement trace[] = (new Throwable()).getStackTrace();
int bottom = trace.length - 1;
if (bottom >= 0) {
    mainClassName = trace[bottom].getClassName();
if (mainClassName == null || mainClassName.equals("")) {
    mainClassName = "AWT";
awtAppClassName = getCorrectXIDString(mainClassName);

As you may note what is used for this value is the name of the class running the Swing main loop.

Da solution

Digging around the web I founded a java agent and a pretty similar explanation on what’s going on.
So what I did was to fork that agent and improve it a little bit. What I did was to move it into a maven structure and remove its packaging as a fat-jar (I’m radically against fat-jars as you can see in my comments here).

The forked project is located in my github here:
and please take a look to the README there

A practical example

My first motivation on doing this was based on IntelliJ IDEA so I’ll paste here my environment.

  • Download the agent-1.0.jar and put it wherever you want (I put it into IntelliJ’s bin/ folder)
  • Edit the file bin/idea.vmoptions adding this line


  • Create the file ~/.local/share/applications/intellij-ultimate.desktop with the following content

    [Desktop Entry]
    Name=IntelliJ IDEA Ultimate Edition
    Comment=The Most Intelligent Java IDE
    Exec=env IDEA_CLASSPATH\=../lib/asm.jar /home/diego/bin/ideaIU-10.5/bin/

Latest notes

If you download the agent-1.0.jar into another location (or with another name) you must adjust the -javaagent: parameter.
Of course, change the path in the Exec entry to point to your own executable.

Hope this helps somebody, it took me a while to figure out the-right-things-to-do™ :)

[1]: Application Based GNOME 3