ANTLR4 project with Maven – Tutorial (episode 1)

Introduction

I’ve always been fascinated by Language Theory and the related technologies. Since I have been prevalently a Java guy, I used to use Javacc and JJTree to build parsers and interpreters. Nowadays it seems that the big name in the field of language recognition is ANTLR. I have wanted to learn more about ANTLR for a long time and lately I finally had the opportunity to spend some time on it. I thought it would have been a good idea to share the sample projects I created in the process.

I plan to write at least three parts:

  1. Setup of the project with all the basic pieces working.
  2. Implementation of a visitor.
  3. Grammar refinement to include self-embedding and implementation of a second visitor.

Through this series I will design a language to give the specification of the position of some geometrical shapes that will be used later to add shapes to the gravity simulator 3D scene (at least this is the idea).

The whole source code is available for download at https://github.com/Rospaccio/learnantlr. The project contains some tags that are related to the various episodes of the tutorial (unfortunately not always with the corresponding sequence number, but I will make sure to reference the right tag for each episode).

Disclaimer: this is not a comprehensive guide to ANTLR and I am not an expert in the field of Language Theory nor in ANTLR. It’s just a sharing of my (self) educational process. The focus is almost entirely on the setup of a build process through Maven, not on the internals of ANTLR itself nor the best practices to design a grammar (though I will occasionally slip on that topics).

Project setup (Git tag: v0.1)

Outline:

  1. first version of the language;
  2. basic pom.xml;
  3. specification of the grammar;
  4. first build.

First version of the language

the first version of the language is going to be very trivial and it is supposed to be just a pretext to show how a possible pom looks like. We want to be able to recognize strings like the following:

cube 0 0 0
sphere 12 2 3
cube 1 1 1
cube 4 3 10
<etc...>

where the initial keyword (“cube” or “sphere”) specifies the nature of the shape and the following three number specify the coordinates of the shape in a three dimensional space.

Basic POM

ANTLR has a very good integration with Maven: every necessary compile dependency is available from the central repository. Plus, there’s a super handful plugin that invokes the antlr processor, thus it is possible to define and tune the entire build process through the pom.xml file. But enough of these words, let’s vomit some code.

You can start the project as a default empty Maven project with jar packaging. First, you need to add the ANTLR dependency in your pom.xml file. Here’s the fragment:

<properties>
	<antlr4.plugin.version>4.5</antlr4.plugin.version>
	<antlr4.version>4.5</antlr4.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.antlr</groupId>
		<artifactId>antlr4-runtime</artifactId>
		<version>${antlr4.version}</version>
	</dependency>

	<dependency>
		<groupId>org.antlr</groupId>
		<artifactId>antlr4-maven-plugin</artifactId>
		<version>${antlr4.plugin.version}</version>
	</dependency>
</dependencies>

Here I am using version 4.5, which is the latest available at the time I am writing, because it supports Javascript as a target language, a feature that I am going to use later in the tutorial.

The first dependency, antlr4-runtime, as the name suggests, is the runtime support for the code generated by ANTLR (basically it’s what you need to compile the generated code and execute it). It contains the base types and classes used by the generated parsers.

The second, antlr4-maven-plugin, is the plugin that can be used in the “generate-sources” phase of the build. To actually use it, the following fragment is also needed:

<build>
	<plugins>
		<plugin>
			<groupId>org.antlr</groupId>
			<artifactId>antlr4-maven-plugin</artifactId>
			<version>${antlr4.plugin.version}</version>
			<configuration>
				<arguments>
					<argument>-visitor</argument>
					<!-- <argument>-Dlanguage=JavaScript</argument> -->
				</arguments>
			</configuration>
			<executions>
				<execution>
					<goals>
						<goal>antlr4</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

Note that you can pass argument to the ant command: I user the -visitor option because it generates a handful interface that you can implement in a Visitor class for the parse tree.

Specification of the grammar

In order to have something that makes sense, let’s add a grammar file in the appropriate folder. Create the file (in this case ShapePlacer.g4) inside src/main/antlr4. Make also sure to build a folder structure that mimic the package structure that you want for the generated classes. For example, if you place the grammar file inside src/main/antlr4/org/my/package, the generated classes will belong to the package with name org.my.package.

Here’s our first grammar:

grammar ShapePlacer;
program : (shapeDefinition)+ ;
shapeDefinition : sphereDefinition | cubeDefinition ;
sphereDefinition : SPHERE_KEYWORD coordinates ;
cubeDefinition : CUBE_KEYWORD coordinates ;
coordinates : NUMBER NUMBER NUMBER ;
SPHERE_KEYWORD : 'sphere' ;
CUBE_KEYWORD : 'cube' ;
NUMBER : [1-9]+ ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines ;

Not a very interesting language, but we must only try and see if the build works.

First build

In order to do that, type mvn clean package in a terminal window and see what happens.

What’s happend

During the generate-sources phase of the Maven build (i.e. certainly before compile), the ANTLR plugin is activated and its default goal (“antlr4”) is called. It invokes the antlr4 processor on the grammar file (by default, it looks recursively inside src/main/antlr4 and compiles every .g4 files it finds). If the goal executes with no error, the generated source files are placed in target/generated-sources/antlr4, and they are automatically taken into account for the compile phase.

As we do not have any manually-written source file yet, only the generated files are compiled and included in the jar.

Test

Let’s try and test the parser. To do that we can add a JUnit test case with a test that looks like the following (please browse the source code to find out more about details like the TestErrorListener class):

@Test
	public void testExploratoryString() throws IOException {

		String simplestProgram = "sphere 12 12 12 cube 2 3 4 cube 4 4 4 sphere 3 3 3"

		CharStream inputCharStream = new ANTLRInputStream(new StringReader(simplestProgram));
		TokenSource tokenSource = new ShapePlacerLexer(inputCharStream);
		TokenStream inputTokenStream = new CommonTokenStream(tokenSource);
		ShapePlacerParser parser = new ShapePlacerParser(inputTokenStream);

		parser.addErrorListener(new TestErrorListener());

		ProgramContext context = parser.program();

		logger.info(context.toString());
	}

Lubuntu on VMWare Tutorial – “Behind a Proxy” Edition

A Lubuntu virtual machine on VMWare Player is currently one of my standard tools for developing and testing software. I had a Hard Time (c) the first time I installed and fully configured such an instance because I was (suspense, suspense…) behind a proxy! The need for this setup has been triggered by the fact that I like my VMWare machines to be able to resize the desktop as I resize the VMWare window that contains them. That feature is available in most Linux distros only if you install the VMWare-tools package on the guest machine. That, in turn, requires the build-essential package (gcc, make, and the like).

Here’s the outline:

  1. set the system-wide proxy;
  2. tell apt to use the proxy (’cause no, it won’t use the fucking system proxy);
  3. update and upgrade apt;
  4. install build-essential with apt-install;
  5. install VMWare-tools.

Now that I read it, it seems like an easy thing to do, but it took me some time to have all the pieces set up, so I guess it’s worth to write a brief tutorial to share what I have learned. Of course, I did not find out all these things by myself: this a just a summary of the knowledge that I gathered from the Internet (thank you, Internet).

1. Set the system-wide proxy.

Interestingly, Lubuntu does not have a nice GUI to let you set the proxy, so you have to do it some other way. For me, the best way is to just set the appropriate variable inside the /etc/environment file, so that it is shared across all users. Since it is going to be a development box I do not care about which user logs in at all. I just want the variable available and I want it fast.

to do that, open the aforementioned file with:

sudo nano /etc/environment

or with your favourite text editor (I am sorry if it’s vim), and make sure that the following lines are added:

http_proxy=http://101.101.101.101:3456
https_proxy=http://101.101.101.101:3456
ftp_proxy=http://101.101.101.101:3456
no_proxy="localhost,127.0.0.1"

(As you might imagine, you have to replace the fake IP addresses and ports with your proxy’s ones). To make the change effective you must log out and log in again.

2. Tell apt to use the proxy.

Because otherwise it won’t. Open the file /etc/apt/apt.conf for edit. If it does not exist, create it. Add the following lines:

acquire::http::proxy "http://101.101.101.101:3456"
acquire::https::proxy "https://101.101.101.101:3456"
acquire::socks::proxy "socks://101.101.101.101:3456"
acquire::ftp::proxy "ftp://101.101.101.101:3456"

again, replace the “101” and “3456” placeholders with your actual addresses and ports, and save it.

3. update and upgrade apt.

Run the following command to make apt up to date:

sudo apt-get update
sudo apt-get upgrade

4. Install build-essential with apt-install.

Now you are ready to use apt commands behind your proxy. Type

sudo apt-get install build-essential

to install the necessary build tools.

5. Install VMWare-tools

Now that you have all the prerequisites, you are ready to install the VMWare-tools. Select the menu item as in the picture below, follow the instructions that VMWare Player prompts to you, and you should be fine.

player-tools

Stress reducing tools and methodologies

A brief list of things that made me a better developer and a less anxious person.

Test Driven Development: Even if nobody in your team is doing TDD and your manager thinks it is just building a servlet for each back end Web Service, you can start applying TDD today and become a better developer. Of all the good natural consequences of TDD, what I like most is its stress reducing effect. If I feel afraid that something might be broken or it might fail in production, I just add more and more test cases, until every edge case is covered. I no longer wake up in the middle of the night worried of what could happen tomorrow when the servers will be restarted. Everything can still go wrong like it used to, but your level of confidence in your code and your reaction speed are greatly improved. You just feel better. And a fix is usually much easier to implement than without tests. Let alone the fact that stupid bugs will actually appear far less frequently than before…

Git: I hated the beast and avoided it like hell until I found an illuminating video on Youtube where a clever guy managed to explain with great clearness how Git actually works and how you can use it effectively. That has been a turning point. I realized that I was unable to use it because of lack of understanding. And once you see what branching and merging really means, you feel powerful, and a whole new world of possibilities unfolds before your eyes. It’s like living in three dimensions after having spent your whole life in Flatland. As of TDD, you do not have to wait until your company understands that leaving SVN and transitioning to Git is the right thing to do (Here I don’t even want to take into consideration SourceSafe, ClearCase or other hideous abominations): you can start using it today. Just “git init” a repository inside the root directory of a project; it does not matter if it’s under SVN source control, if you “gitignore” the right things the two do not interfere which each other. And your are ready to go. Now I wonder how could I have lived so long without Git.

Maven: you can say that it is verbose, it is slow, it eats up a lot of disk space, it’s ugly… I don’t care. I have personally seen what a build system without proper dependency management could be and what can cost in terms of time, money and stress: it’s not even a build system, it’s a destruction system. Maven is currently my default. There is only one thing that pisses me off more than a project not using Maven: one that uses it badly. If a person is not able to checkout a project and run a clean build at his first try, you are doing something wrong.

Sonarqube: A Wonderful free tool that helps you improve your code. It’ a bunch of tools that perform static analysis of code, integrated in a web application that keeps track of how the various parameters of the projects evolve from build to build. You can always learn something from the issues detected by Sonarqube and their relative descriptions. And it feels good to see how the color of a project shifts from red, to yellow, to green as you become a better programmer.

Virtual Machines: This is incredibly important, fundamental, if you happen to work in a hybrid environment. A usual situation for me is having a development machine running Windows and a deployment environment (for test, UAT, production, etc…) completely based on Linux. This is not so strange if you work with JavaEE: most applications and systems actually behave in the same way in Windows and Linux… almost… That is why you always want to give them a spin in a Linux box, before releasing it. After trying almost every virtualization software, my current choice is VMWare Player + Lubuntu. The first is available free of charge for non commercial use and works surprisingly well, the second is a lightweight Linux distro based on Ubuntu that gets rid of the super ugly desktop environment of Canonical and replaces it with LXDE, which requires few resources and performs well in virtual machines and older computers.

Fear Driven Development – Enterprise Induced Worst Practices (part 0)

The Internationalization Antipattern

Some years ago I was still working for Big Time Consulting but I was not even a proper employee. I was a contractor from a company owned by BTC. Well, you figure out the real names. I was sort of an in shore indian developer. We had this huge system built upon Liferay. The system was composed of hundreds of portlets, scattered across tens of WARs. The portal was heavily customized. The language strings for every portlet were all defined in a single Language.properties file at the portal level. That’s right: WARs did not have their own Language file: everything was defined centrally. That meant that if you needed to change the label of a button, you had to modify the portal Language file, build an artifact that belonged to the architectural sector of the system (i.e. it impacted ALL the portlets) and then, once deployed, restart the servers involved in the process.

Nowhere along this path there was an automated test.

As you might imagine, quite often things went wrong. The less severe issue that you could get was the total replacement of the Language strings with their corresponding keys (that was the default behavior in that version of Liferay: if the string was not found, it was simply set to its key). So, after the reboot, everything on every page looked something like “add.user.button.text”, “customer.list.title”, “user.not.found.error.message” and so on. Everywhere. In every single application. The default reaction in the team was “The Strings have been fucked up. Again.”

On the extreme end of the spectrum there was a funny set of poltergeist bugs. Mysterious NoClassDefFoundError, ClassCastException, Liferay showing a bare white page, Liferay showing every graphical component in the wrong place, portlets not deploying, etc…

After being forced to spend a couple of looong evenings to fix this issue (Did I mention that the entire process of compiling, packaging and deploying was excruciatingly long?) I learned my lesson: never mess with the strings again. I decided to apply my personal internationalization antipattern: always include a default value for every string with

LanguageUtil.get(Locale locale, String key, String defaultValue)

and don’t even try to package the architectural artifact (AA, from now on). Just modify and commit the Language file. Then deploy the WAR: the next day the strings magically appear on the screen, and nobody will ever notice that they are hardcoded. Wait until the next release cycle of the AA to have the strings file available. Luckily you won’t be the one needing to deploy it so, if something goes wrong, you can blame someone else and save your evenings.

How I spent my Christmas holidays

gravity02

The Christmas tradition here at Codevomit is to spend some hours in front of our computers and churn out code as soon as it comes to our minds. After all, that is what codevomit is all about.

The goal of the past year holidays was to gain some basic knowledge of Scalable Vector Graphics and, possibly, of Git. I see SVG employed almost everywhere today and I am always impressed by the nice visual results that you can get. I wondered what I would have been able to do with it. In order to achieve such an ambitious result, I choose an example that I first implemented in Visual Basic when I was about seventeen and since then it always kept going around my mind. This is the outcome I am sooo proud to present to you. It took about 8 – 9 hours to get the basic engine to work, then another countless hours of relentless play to fix some major issues and have a lot fun. The source code is here and it’s still under development since I am currently working on a 3D version (and it works surprisingly well!).

The application is a 2D discrete simulation of celestial bodies interacting with each other according to Newton’s Law of Universal Gravitation. Technically, it is simply a web page with a couple of javascript files or, as they like to call it nowadays, an HTML5 + Javascript application. No server side work is done except for the good old Apache serving the page.

Instructions

First, you have to select the kind of celestial body that you want to add to the simulation. In order to do that, click on one of the “mass” buttons. Then, click on the canvas and, while you are still holding the left mouse button, drag. You will see that a red line follows your mouse movement: that line is the initial speed vector that your body will have. The longer it is, the faster your object will go.

speed-vector

At this point, the objects are still immobile. The simulation can be started, stopped, reset, etc…, with the buttons at the bottom of the canvas. You can also enable traces with the corresponding button and get some nice draws like the one I pasted at the beginning of the post.

When you get a nice configuration, you can save it with the “SAVE” button. The state of the simulation is serialized to text (XHTML + JSON) and written in the textbox, from which you can copy it. You can restore it at any time: just paste the text back to the textbox and click the “RESTORE” button.

Setting up a restlet with Camel in JBoss Fuse

If you have already successfully gone through the steps of the previous tutorial, this is going to be quite fast and straightforward. All you need to know is that in Camel you can set up a restlet to listen to a specific URL/port with the “restlet” prefix.

Let’s assume that we want to listen for REST request and turn the body of the request into a message to be queued on one of our (already existent) ActiveMQ. As in the previous example, we can accomplish the task without even write a line of Java code.

We can add the following elements to our blueprint.xml file:

    <route>
        <from uri="restlet:http://localhost:8282/demo-endpoint?restletMethod=POST"></from>
        <camel:setBody>
            <simple>test=true</simple>
        </camel:setBody>
        <log message="The request body is: ${body}"></log>
        <to uri="activemq:sink-queue" pattern="InOnly"></to>
        <to uri="mock:result"></to>
    </route>

Here I’m specifying the restletMethod parameter, which tells Camel to only respond to GET HTTP request (i.e. any other HTTP verb will result in the request to be discarded). The setBody element is used for making thigs simpler: it sets the body of the exchange to the child value, as you might expect. Now we can “clean-install” the project as usual and switch to the Karaf console. Update the package with a osgi:update command (here, 251 is the ID of my bundle, you will probably have a different one. You can find out what ID your bundle has by executing a “list” command):

JBossFuse:karaf@root> osgi:update 251

After this, execute “list” and take a look at the output. In correspondence with the updated bundle you should see something like this:

[ 251] [Active     ] [GracePeriod ] [       ] [   60] A Camel Blueprint Route (1.0.0)

This is because the bundle has a missing dependency: the camel-restlet Feature. The bundle has been successfully installed, but it cannot be started until the missing dependency is satisfied. The missing feature is not installed by default in Fuse. Luckily, you can easily get it by typing the following command:

JBossFuse:karaf@root> features:install camel-restlet

To learn more about Features, refer to the official documentation.

Restart your bundle. The restlet is now ready. You can try and call it with whatever method you prefer. For simplicity, i present you the command used to perform a test with curl:

curl --data "test=true" http://localhost:8282/demo-endpoint

 

Simple Camel route in JBoss Fuse

For this tutorial and the following ones, I am going to use a Fuse instance on a Lubuntu Linux box. My IDE is Eclipse Luna and the build system is Apache Maven v. 3.5.2. Eclipse is actually running on Java 8 but it does not matter since I’m going to run all the builds from a terminal.

Let’s see how we can implement and deploy a simple Camel route in JBoss Fuse. We start by defining our requirements that, in this case, are going to be very trivial: we want to read messages from a queue, process them and the write them back to another queue. The processing step is going to be simple too: we will just log the message body.

First of all, we need two queues. Start Fuse and reach the console (see the previous post). In the menu bar, click on “ActiveMQ”. Then click on “+Create” on the submenu, select “queue” in the radio buttons group, type the appropriate name in the text box (I’m choosing “source-queue”) and finally click the “Create Queue” button (see pictures below). Repeat the process and create a “sink-queue” queue, it will be our destination queue. Later, we will be going to need to queue a message in the source queue through the web panel. In order to be able to do that, we have to set the username and password. In the web console, go to the drop down menu in the top right corner (where your username appears). Select “preferences”. Go to the “ActiveMQ” tab and insert your administrative username and password. The settings are automatically saved. Now that we have the infrastructure ready, let’s switch to the development side.

activemq-menu

create-queue

If you are going to develop projects for Fuse, Maven is the way to go. The default way you install new components in Fuse, is by telling it to get the artifacts from a Maven repository. For this tutorial I assume that you are quite familiar and comfortable with Maven and that you have a working installation of Maven on your system.

We can create the initial skeleton of the project starting from a Maven archetype. Open a Terminal and type:

mvn archetype:generate

choose the archetype named camel-archetype-blueprint (in my case is the number 449) and complete the process. Here is a dump of my terminal:

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 510: 449
Choose org.apache.camel.archetypes:camel-archetype-blueprint version:
1: 2.8.0
[...]
42: 2.14.1
Choose a number: 42: 42
Downloading: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.jar
Downloaded: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.jar (17 KB at 14.1 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.pom (3 KB at 10.9 KB/sec)
Define value for property 'groupId': : org.merka
Define value for property 'artifactId': : fuse-demo-blueprint
Define value for property 'version':  1.0-SNAPSHOT: : 1.0
Define value for property 'package':  org.merka: : org.merka.demo
[INFO] Using property: camel-version = 2.14.1
[INFO] Using property: log4j-version = 1.2.17
[INFO] Using property: maven-bundle-plugin-version = 2.3.7
[INFO] Using property: maven-compiler-plugin-version = 2.5.1
[INFO] Using property: maven-resources-plugin-version = 2.6
[INFO] Using property: slf4j-version = 1.7.7
Confirm properties configuration:
groupId: org.merka
artifactId: fuse-demo-blueprint
version: 1.0
package: org.merka.demo
camel-version: 2.14.1
log4j-version: 1.2.17
maven-bundle-plugin-version: 2.3.7
maven-compiler-plugin-version: 2.5.1
maven-resources-plugin-version: 2.6
slf4j-version: 1.7.7
Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: camel-archetype-blueprint:2.14.1
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.merka
[INFO] Parameter: artifactId, Value: fuse-demo-blueprint
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: package, Value: org.merka.demo
[INFO] Parameter: packageInPathFormat, Value: org/merka/demo
[INFO] Parameter: maven-bundle-plugin-version, Value: 2.3.7
[INFO] Parameter: maven-resources-plugin-version, Value: 2.6
[INFO] Parameter: groupId, Value: org.merka
[INFO] Parameter: maven-compiler-plugin-version, Value: 2.5.1
[INFO] Parameter: slf4j-version, Value: 1.7.7
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: log4j-version, Value: 1.2.17
[INFO] Parameter: camel-version, Value: 2.14.1
[INFO] Parameter: package, Value: org.merka.demo
[INFO] Parameter: artifactId, Value: fuse-demo-blueprint
[INFO] project created from Archetype in dir: /home/merka/workspace/fuse-demo-blueprint
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:20 min
[INFO] Finished at: 2014-12-23T20:29:24+01:00
[INFO] Final Memory: 13M/60M
[INFO] ------------------------------------------------------------------------

Now we can import the project in our IDE of choice and open it. Just to be sure that everything is OK, run a first build with the command mvn -DskipTests=true clean package from the shell and wait for the required dependencies to be downloaded.

The archetype project comes with a couple of “hello world” files that you can completely ignore at this point: they only serves as an example. It’s actually better if you delete all the hello-world-related stuff, unit test included.  Open the blueprint.xml file in the folder OSGI-INF/blueprint and comment out the existing route. You should also delete the “helloBean” definition. The file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/blueprint"
       xsi:schemaLocation="
       http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
       http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">

  <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<!--     <route id="timerToLog"> -->
<!--       <from uri="timer:foo?period=5000"/> -->
<!--       <setBody> -->
<!--           <method ref="helloBean" method="hello"/> -->
<!--       </setBody> -->
<!--       <log message="The message contains ${body}"/> -->
<!--       <to uri="mock:result"/> -->
<!--     </route> -->
  </camelContext>

</blueprint>

Before the camelContext element, add the following bean definition: it provides Camel with the credentials to access the ActiveMQ Broker:

	<!-- connect to the local ActiveMQ broker -->
	<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
		<property name="brokerURL" value="tcp://localhost:61616" />
		<property name="userName" value="merka" />
		<property name="password" value="merka" />
	</bean>

Then, add the following snippet inside the camelContext element. It defines a route that satisfies our requirements:

    <route id="queue2queue">
        <from uri="activemq:source-queue"></from>
        <log message="the message body is: ${body}" loggingLevel="INFO"></log>
        <to uri="activemq:sink-queue"></to>
    </route>

It is quite readable. The from element defines a consumer endpoint: it will read messages from the queue named source-queue (that we have just created), as soon as they are available. The message body is logged, thanks to the log element, and then it is written to sink-queue.

Build the project with Maven (mvn clean install). This puts the artifact in the local Maven repository, thus making it available to Fuse. To install the artifact in Fuse, go to the Karaf prompt and type

osgi:install mvn:org.merka/fuse-demo-blueprint/1.0

With this command you tell Karaf to search for the artifact with the given groupId/artifactId/version. If found, it answers with the id of the installed osgi bundle:

JBossFuse:karaf@root> osgi:install mvn:org.merka/fuse-demo-blueprint/1.0
Bundle ID: 251

You can see all the installed components typing list. Start the bundle with the commnand start <bundle-id>. Check the log for possible errors with log:display or log:tail. If no errors are found, go to the web console and manually send a message into the source-queue queue. The message is immediately consumed from the queue, the message body appears in the log and a brand new message is sent to sink-queue.

 send-msg

JBoss Fuse installation tutorial

At work I was given the task to study JBoss Fuse and become sufficiently comfortable developing and deploying basic projects on this platform. I’m going to write a series of post to share my experience and considerations.


Some random thoughts

I’m not going to rigorously explain you what Fuse actually is. But if you start from scratch, without any previous knowledge of a Service Bus middleware, it’s quite hard to get the essence of the system. And if you try to make an idea through what you find online, good luck. It’s hard to find something that tells you what you can really use Fuse for, possibly with some insightful examples. In fact, it is almost impossible. Sure you can find some “case studies” or articles that tell you how good Fuse is at integrating systems and how big a shitload of money they saved by using it instead of, say, building a similar monster from scratch. But those are only marketing mumbo jumbo and do not give you any useful tip on the technical side of the matter, which is what I really care about. What help me the most in these cases is bringing it down to a very trivial use case description and a set of practical examples. And this is what I am trying to do here.

Fuse is huge, very huge. It is a collection of subsystems taped together by Karaf, an OSGi container developed by the Apache Foundation. Here are only some of the subsystem included. I only knew the name of most of them until now, and some were completely unknown:

  • Karaf,
  • Camel,
  • CXF,
  • Hawtio,
  • Felix,
  • ActiveMQ,

JBoss Fuse is basically a Service Bus, a middleware, that allows you to host services and integrate a wide variety of heterogeneous systems. But this is not very helpful. So, this is the picture that I have after spending several hours using Fuse and developing tutorial and demo projects: if you have, say, a desktop application developed for Windows, a bunch of Web Services hosted in Tomcat in a Linux box, an external database that needs somehow to be updated and you want to let this system talk to each other, then Fuse might be the way to go. You can set up a Web Service in Fuse (REST or SOAP doesn’t matter) and use Apache Camel to connect the various pieces in a so called “route”. There already are a lot of components that automagically let you call an external web service, read and/or write to a database, reading or write a text file over FTP, reading or writing a directory over LDAP and whatnot. Here is a list of what is available. I particularly enjoyed the SSH connector and I’m looking forward to give it a try in a real project.

Another possible scenario is an Enterprise application that needs to interface with a legacy system. Think about an organization that wants, for some reasons, a new, cool, bleeding edge, good looking front end to amaze and fool the customers, but does not want to get rid of its 30-year-old COBOL code base running on IBM mainframes (nobody wants to do that). You can use Fuse to translate messages (from XML/JSON to plain text and back again), decouple the systems by using queues, log, and so on. Again, this is how I currently picture Fuse in my mind, I do not claim to give you a full coverage of the possible, numerous use cases.


Installation

Finally. Fuse is as easy to install and launch as Liferay, Alfresco and Pentaho (just to name few that I recently had to install). Even easier, in a sense. That is what you expect, since it’s completely Java based. Just unpack the tarball or the zip archive and launch <FUSE_DIR>/bin/fuse or <FUSE_DIR>\bin\fuse.bat, depending on what OS you are on. Keep in mind that the current release of Fuse (6.0.1) requires Java 7 and does not support Java 8. If you have your JAVA_HOME environment variable set to something different, you have to change it by either editing /etc/environment or the startup script. To do the second, which I recommend, Open the “<FUSE_DIR>/bin/karaf” script and add the variable definition, just like this:

#explicitly sets the value of JAVA_HOME to a compatible JDK
JAVA_HOME=/opt/jdk1.7.0_71

DIRNAME=`dirname "$0"`
PROGNAME=`basename "$0"`

#etc...

...

Now run the script named fuse and, if everything is OK, the Karaf console starts showing a prompt like the following:

JBossFuse:karaf@root>

The first thing that we want to do is to create an administrative user in order to access the Web console. So type:

JBossFuse:karaf@root> esb:create-admin-user

And there we go, we can now open a browser and navigate to http://localhost:8181, and have full access to the management web application.

Starting Android Studio behind a proxy

I recently installed the latest (stable) version of the new Android Studio, the one based on IntelliJ IDEA.
The installation went OK but when i started the program, it remained stuck in the splash screen, with a message box saying: “getting Android SDK Component information” or something like that. Then, after 10 minutes or something, it finally timed out and loaded another screen, the Setup Wizard, that should help you configure Android Studio on the first startup. Same thing happend, it remained stuck for about 20 minutes, then told me that something was wrong and so the application could not be started. That’s it, it seems that you can’t do anything about that.
As you might imagine, it’s a network related problem. Actually it is clearly stated that you should have a stable internet connection to run Android Studio without incurring into any problem. The point is I had a stable and fast Internet connection so the problem came down to the network proxy. After I tried to start AS without Internet (it failed immediately) and with a tethering connection with my phone (it quickly moved on from the first screen and greedily tried to download all the things from my phone), I was in a weird situation where I really needed to tell AS to use a proxy before starting but, unluckily, I could not do that without starting it and, without the right proxy setting, it won’t start.
Or will it… I also have a clean Intellij IDEA installation on my computer so I thought that, since they are basically the same thing, I could try to set the proxy on IDEA and see what happens. Hopefully it stores the information in some human readable configuration file and I can steal that snippet and paste it on the corresponding AS file.
After a bit of searching, it turns out that it is exactly the case. I found the file other.xml in the folder %HOME%\.IdeaIC12\config\options, where %HOME% is, quite obviously, your home folder under Windows.
The desired snippet is the following:


<component name="HttpConfigurable">
    <option name="PROXY_TYPE_IS_SOCKS" value="false" />
    <option name="USE_HTTP_PROXY" value="true" />
    <option name="USE_PROXY_PAC" value="false" />
    <option name="PROXY_HOST" value="101.116.3.251" />
    <option name="PROXY_PORT" value="3128" />
    <option name="PROXY_AUTHENTICATION" value="false" />
    <option name="PROXY_LOGIN" value="" />
    <option name="PROXY_PASSWORD_CRYPT" value="" />
    <option name="KEEP_PROXY_PASSWORD" value="false" />
    <option name="myGenericPasswords">
      <map />
    </option>
    <option name="myGenericCancelled">
      <set />
    </option>
    <option name="PROXY_EXCEPTIONS" value="localhost,127.0.0.1,101.*" />
  </component>

You can copy and paste it under the corresponding other.xml under %HOME%\.AndroidStudio\config\options and it will do the trick.
Done this, AS started without any problem.

Pivotal Web Services trial

Preconditions: Windows 7.

The Story:

Yesterday I received an invitation for a two-month free trial of the rising Pivotal Web Services. It’s kinda OpenShift, kinda Azure, etc. but with a bit of hipster style blended in. Just a bit.

Since the very first moment that I knew something about this service, I have been very intrigued by the promise that you can simply type something like

deploy just-this-war.war

in you terminal window and have your application up and running in the Internet. Something that I have been searching for since a looong time ago. I do not know why they sent me the invitation and I do not even remeber when I asked for it (It was probably a late drunk friday night) but here it is. Today I found some time to try the wordeful and valuable capabilities that Pivotal provides you with.

Sadly, the beginning has not been one of the most memorable. Or probably it has been, but in a not-so-positive sense. Just like OpenShift, Pivotal Web Services (PWS), require that you install some client side command line utilities to remotely manage your applications. Unlike OpenShift though, you do not have to go through an infinite sequence of installations. In this case you just have to install their little tiny lighweight client: cf.exe (cf stands for Cloud Foundry, I guess). Don’t get me wrong, it is a great improvement with respect to the paramount load of things that you have to install in order to manage your OpenShift instance. The only problem is that, once you’ve run the cf installer, no known command works anymore. “mvn package something“? No way: “mvn is not recognized as an internal or external command, operable program or batch file“. What?! Even if you type “cmd” you get the same laconic answer. You could already figure out the problem: the cf installer completely erases the ‘path’ environment variable. If you have been working with your machine for almost two years, as I did, installing tons and tons of programs, tools and utilities, this puts you in a very uncomfortable situation.

Luckily I found a solution to this problem online. Thank you to the guy who answered and thank you Internet. This saved me a lot of troubles.

At this point I was a bit upset, as you might imagine. But!… When the cf command is set up and working properly, the steps to deploy a Java webapp are the following:

first, tell cf which API endpoint to use with the command

cf api api.run.pivotal.io

then, you have to log in with:

cf login

API endpoint: https://api.run.pivotal.io

Username> xxx.xxx@gmail.com

Password>
Authenticating...
OK

API endpoint: https://api.run.pivotal.io (API version: 2.2.0)
User: xxx.xxx@gmail.com
Org: xxx
Space: stubgen

and, finally, the real magic:

cf push stubgen -p <path-to-your-war-file>

and voilà, the application is deployed and works like a charm.