Receive notification in the system tray on server startup (Tomcat, Hybris)

On many large e-commerce projects server startup can take up to 6-10 minutes. Hybris projects I worked at are not exception. So usually when I start the tomcat server I can do lots of other things. e.g. reading the spec, browsing the net or even continue development in my IDE. So after 5-6 minutes I can forget about the fact that my server is starting up. So I thought that it would be great to have a tool that can notify me as soon as tomcat starts up and I decided to develop  it. So basically what the tool has to do is to understand when tomcat server finishes startup and call OS utility to notify me about it.

OOTB hybris uses  Growl to notify developer about init/update actions. To activate it you need to install Growl for windows or Grow for OS X and add it your PATH.

Unfortunately Hybris does not support “server is ready” notification. But there is very simply way to do that. First of all tomcat has The LifeCycle Listener Component that can let us know about different events in tomcat server.

public interface Lifecycle {
	String BEFORE_INIT_EVENT = "before_init";
	String AFTER_INIT_EVENT = "after_init";
	String START_EVENT = "start";
	String BEFORE_START_EVENT = "before_start";
	String AFTER_START_EVENT = "after_start";
	String STOP_EVENT = "stop";
	String BEFORE_STOP_EVENT = "before_stop";
	String AFTER_STOP_EVENT = "after_stop";
	String AFTER_DESTROY_EVENT = "after_destroy";
	String BEFORE_DESTROY_EVENT = "before_destroy";
	String PERIODIC_EVENT = "periodic";
	String CONFIGURE_START_EVENT = "configure_start";
	String CONFIGURE_STOP_EVENT = "configure_stop";
}

From the list above AFTER_START_EVENT is the most appropriate event we can listen to. OK, it clear about event, but how should we put notification in the system tray? Basically there are two options:

  1. Use Growl via command line tool as Hybris does
  2. Use Java’s SystemTray class

As a good developer I think we should support both versions. So when Growl exists – use it, if does not exist – use default system tray. Lets write our implementation.

Step 1 – Create a project that can be packed as jar

As maven is still the most popular build tool lets create project from maven archetype.

mvn archetype:generate -DgroupId=com.wordpress.nikitapavlenko
-DartifactId=tomcat-notification
-DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false

My maven pom.xml is following:

<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>com.wordpress.nikitapavlenko</groupId>
    <artifactId>tomcat-notification</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>tomcat-notification</name>
    <url>http://maven.apache.org</url>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>7.0.12</version>
        </dependency>
    </dependencies>
</project>

Step 2 – Implement org.apache.catalina.LifecycleListener

package com.wordpress.nikitapavlenko;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;

import java.awt.*;
import java.awt.TrayIcon.MessageType;
import java.io.IOException;
import java.net.URL;
import java.util.Calendar;
import java.util.Map;

public class TomcatListener implements LifecycleListener {

    @Override
    public void lifecycleEvent(LifecycleEvent event) {
        if (Lifecycle.AFTER_START_EVENT.equals(event.getType())) {
            if (growlExist()) {
                notifyViaGrowl();
            }
            else {
                notifyViaDefaultSystemTray();
            }
        }
    }

    private void notifyViaGrowl() {
        try {
            String message = "\"Server successfully started. [" + Calendar.getInstance().getTime()+"]\"";
            Runtime.getRuntime().exec("growlnotify /t:Tomcat " + message);
            System.out.println("Growl notification sent");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean growlExist() {
        Map<String, String> env = System.getenv();
        String path = env.get("Path");
        return path != null && path.toLowerCase().contains("growl");
    }

    private void notifyViaDefaultSystemTray() {
        SystemTray tray = SystemTray.getSystemTray();
        TrayIcon trayIcon = createTrayIcon();
        try {
            tray.add(trayIcon);
            trayIcon.displayMessage("Tomcat", "Server successfully started.", MessageType.INFO);
            System.out.println("System tray notification sent");
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    private TrayIcon createTrayIcon() {
        URL resource = getClass().getClassLoader().getResource("icon.png");
        Image image = Toolkit.getDefaultToolkit().createImage(resource);
        TrayIcon trayIcon = new TrayIcon(image, "Tomcat");
        trayIcon.setImageAutoSize(true);
        trayIcon.setToolTip("Hybris server");
        return trayIcon;
    }

}

Step 3 – Package sources as jar file

mvn clean package

At this moment you will have an artifact “tomcat-notification-1.0-SNAPSHOT.jar”

Step 4 – Register listener in the server.xml

For the based hybris app open config/tomcat/conf/server.xml and add a new listener there:

...
<Listener className="com.wordpress.nikitapavlenko.TomcatListener" context="GenericJavaBeanResource"/>
...

Step 5 – Add our jar to tomcat lib folder

For the hybris based project add this jar to config/customize/platform/tomcat/lib and don’t forget to run customize target before ant all.

Step 6 – Results

When growl is in system’s Path:
growl.png

When growl is not in the system’s Path:

default.png

The source code is available my Github. Thanks for reading!

Advertisements

Author: nikitapavlenko

I am Software Engineer from Kharkiv, Ukraine. I develop e-commerce web applications using Hybris platfrom mostly using Java.

3 thoughts on “Receive notification in the system tray on server startup (Tomcat, Hybris)”

    1. Hi Denis,

      Sorry not answering your question. It was my employer working station with preselected OS.
      I use Ubuntu at the moment. I can’t say I prefer unix over windows, but for developer unix is more friendly sometimes

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s