Michael Hunger’s talk had an elegant solution
to an actual, unsolved problem of mine



After attending a software development conference, you usually return back home with a bunch of new ideas and cool things you want to try out. But most of the time your ideas remain in experimental stage, since it’s often hard to find a problem that’s just right for all newfound solutions…

But returning from GeekOut 2014 was different – Michael Hunger’s talk “Using Ascii Art to Analyze Your Source Code with Neo4j and OSS Tools” had an elegant solution to an actual, unsolved problem of mine that had surfaced just a couple of weeks earlier.


A system I am involved in as a developer relies on custom parsing of the source code to find all concrete subclasses of a particular class, excluding inner classes. These subclasses represent units for which user access can be configured. If this list is incomplete, the configuration will be incomplete, which in turn means missing user access. We had just seen our first case of generics showing up in this class hierarchy, and the parser couldn’t handle that properly.


The objective is to extract all concrete subclasses of a particular class into a custom format file, and this should be part of the build. This file serves as a template for access control configuration for the scanned rich client application.

If you have a Maven project, this can be done quite easily with jQAssistant and Neo4j. Here are the basic steps:

  1. Setup jQAssistant
  2. Build your Maven project
  3. Scan your compiled classes with jQAssistant to create a Neo4j representation of your code
  4. Query the database to extract the information you need
  5. Generate the result

The steps will be described in more detail below, using this sample project. It’s a real-world example, but the actual code scanned and the custom report plugin have been replaced with sample code.

Step 1 – Setting Up jQAssistant

To set up jQAssistant, make sure you have the following:

  • JDK 7
  • Maven 3 and access to Maven Central Repository
  • A Maven project

Add the following to your settings.xml, located in the .m2 folder of your home directory:

This makes it easier to run jQAssistant from the command line. Now you’re good to go.

Step 2 – Build Your Maven Project

Since jQAssistant scans bytecode, you need to build your Maven project.

Step 3 – Scan Your Compiled Classes

Before you can scan your application, you need to add the jQAssistant Maven plugin to your POM:

This also includes configuration of the report writer described later, the file to which the result should be written.

Now you can scan your code using

Step 4 – Query the Neo4j Database

With your code scanned, it’s time to write your Cypher query. The Neo4j web interface is very useful for experimenting with queries, start it by executing

Now you can browse to https://localhost:7474 and start writing and testing your queries.

Neo4j web interface

First, let’s locate the base class that we want to find concrete subclasses for. In the sample code we have a hierarchy of animals, with the base class Animal. So, to find that class, we can use the following query:

Executing that query in the web interface will return one node, the Animal class:


Now, if we extend the query a little bit we can get all subclasses instead.


Clicking the nodes will reveal that we now have found some animals, but also some abstract classes such as Fish and Insect. To get rid of those, we enhance the query:


Now we only have concrete subclasses left. The final thing to get rid of is the inner class declared by GoblinShark.


Now only we have a query that returns all concrete subclasses of Animal, inner classes excluded.

To stop the server, return to the console from where it was started and hit Enter.

Now it’s time to create a rule file to integrate the query into the build. Rule files are XML files located in the jqassistant folder.


Step 5 – Generate the Result

Now that we have a query that do the extraction from the compiled code, we just need to put that in a file. In this example, we just want to write the fully qualified name for each class found by the query. To do that, we implement a custom report writer:

When we plug in this report writer, the result from the query will be available in the Result parameter passed to the setResult method. The rows can be retrieved and written to a file in the desired format.

To let jQAssistant know about your plugin, create a file called jqassistant-plugin.xml and place it in the META-INF folder of your report writer project.

The final step is to let jQAssistant execute your query and generate the report, which is done by executing

As simple as that.

Thanks to Michael Hunger for a great talk on jQAssistant and Neo4j at GeekOut 2014, and many thanks to Dirk Mahler for helping out, sharing knowledge and enhancing jQAssistant to allow plugging in your own custom report writer. Awesome.

For more details check out https://jqassistant.org where you’ll also find reference documentation and examples.


Please feel free to share