Adjacency matrix code visualizer

Table of Contents

1 Description

This page describes how an adjacency matrix can be used to visualize class dependencies in java code.

We present a tool to generate adjacency matrices from java code.

We then describe what an adjacency matrix can tell you about your code. And shows adjacency matrices for selected java applications.

2 News

  • 18 Apr 2016: Updated code to 1.1 with new "Order by tree" that highlights cyclic dependencies. Updated adjacency matrix examples.
  • 13 Apr 2016: Initial

3 Adjacency matrix

An Adjacency matrix is a representation of a graph in the form of a NxN matrix. If row 2 and column 4 are colored, that means there exists an edge from node #2 to node #4.

Adjacency matrices are useful because they can visualize very big graphs. Drawing nodes as circles with lines between them gets confusing at about 100 nodes.

4 Adjacency matrix examples

4.1 JDK 1.8

Adjacency matrix for JDK 1.8 (3.8M)

Run on jdk1.8.0_45/jre/lib/rt.jar. It took 1 minute to generate.

4.2 Guava 19.0

Adjacency matrix for Guava 19.0 (116K)

Run on guava-19.0.jar. It took 2 seconds to generate.

4.3 Minecraft 1.9.2

Adjacency matrix for Minecraft 1.9.2 (422K)

Run on 1.9.2.jar. It took 3 seconds to generate.

Note: Minecraft code is obfuscated. Class and packages names are random. I do not know if the obfuscation also messed with the connections between classes.

4.4 Netty 4.0.36

Netty 4.0.36 (246K)

Run on netty-4.0.36.Final/jar/*.jar excluding *-sources.jar.

4.5 GWT 2.7.0

Adjacency matrix for GWT 2.7.0 (3.1M)

Run on gwt-user.jar and gwt-dev.jar. It took 46 seconds to generate.

4.6 Eclipse mars2

Adjacency matrix for Eclipse mars2 (11M)

Run on eclipse/plugins/org.eclipse.*.jar. It took 5 minutes to generate.

4.7 Hibernate 5.1.0

Adjacency matrix for Hibernate 5.1.0 (834K)

Run on core-5.1.0.Final.jar and core-5.1.0.Final.jar. It took 6 seconds to generate.

4.8 Apache commons

Adjacency matrix for Apache Commons (331K)

Run on commons-cli-1.3.1.jar, commons-io-2.4.jar, commons-math3-3.6.1.jar, commons-compress-1.11.jar, commons-lang3-3.4.jar. It took 2 seconds to generate.

4.9 JUnit 4.11

Adjacency matrix for JUnit 4.11 (54k)

Run on junit-4.11.jar. It took 1 second to generate.

4.10 adjmatrix 1.1

Adjacency matrix for adjmatrix 1.1 (27k)

Run on adjmatrix.jar. It took 1 second to generate.

Note: Very boring.

5 What adjacency matrices can tell you about your code

If you order nodes so nodes in e.g. the same package are neighbors in an adjacency matrix, you can tell interesting things about the graph:

  1. If a neighborhood forms a square around the diagonal, then the neighborhood is tightly connected to each other.
  2. If there are many dots above and below the neighborhood, then this neighborhood is being used by many other nodes in the graph.
  3. If there are many dots to the left and right of the neighborhood, then this neighborhood uses many of the other nodes in the graph.

5.1 See how connected your packages are

Best seen when the nodes are sorted and colored by Package. Nicely separated packages will have box shapes along the diagonal in the same color, and not many points above or next to this box.

A box of the same color shows that classes within a package uses each other. The adjacency matrix for Guava shows a nice separation between packages. We see a big blue box, followed by small orange, teal and red boxes.

Having few points above or next to the box means that package is not connected to other packages. A Tools packages would have many points above and below it because it is being used by all classes. In the adjacency matrix for Guava the pink and dark green packages at the top left look like tools packages because of all the dots below them. The classes in those areas are mainly com.google.annotations.GwtCompatible and com.google.common.base.

5.2 Highlight groups of highly connected classes

Best seen when the nodes are sorted by similarity and colored by package. Sorting by similarity groups together classes that are highly connected to each other and not highly connected to others.

You should see boxes along the diagonal. If a box has two colors, then two packages are heavily connected. The middle group in Figure 1 shows 3 different colors forming a box around the diagonal. Those 3 colors mean that 3 packages are tightly connected to each other.

adjmatrix_several_packages_are_connected.png

Figure 1: Several packages that are highly connected, taken from the GWT adjacency matrix.

If there are two boxes with the same color, then that package could perhaps be split into two packages. If we sort the adjacency matrix for Guava by similarity, we see that the blue package is split into a big, tightly connected box in the top left corner, and we barely see another blue box in the center.

5.3 Detect cyclic dependencies

A cyclic dependency is when class/package A uses class/package B, and B uses A (cycles of more than 2 classes/packages are also possible).

When you sort by tree, sort package, similarity, or jar, any dot below the diagonal is a link in a cyclic dependency. When sorting by packages/similarity/jar, classes in the same package/group/jar will have been sorted by tree.

5.4 Identify base classes

Base classes are the classes in your code that are used everywhere.

They are best seen when sorting by used and zooming in to the top-left corner.

If you see colors in the full height at the left part you have classes that are heavily used from all your classes. Some most used classes are: CoreException from Eclipse, HibernateException from Hibernate, and Object from JDK.

You can also find classes that are not used at all. These classes might be dead or untested (if you included your unittests in the adjacency matrix).

5.5 Identify God classes

God classes are classes that control everything and have way too much responsibility.

They are best seen when sorting by uses and zooming in to the top-left corner.

Some classes that use the most other classes are: Workbench from Eclipse, ModelBinder from Hibernate, JavasScriptConfiguration from GWT, and XToolKit from JDK.

5.6 Find Bacon

All classes in the JDK are at most 6 dependencies away from the class sun.tools.jar.resources.jar_zh_TW. The class java.lang.Object connects to all but one other classes after 3 steps. The one class that is 4 connections away from java.lang.Object is com.sun.corba.se.internal.Interceptors.PIORB, a rather boring class.

If you just want java.util.ArrayList, you still need 1684 other classes from the JDK. I found this by zooming in to the node representing ArrayList, then clicking "Add uses" until no new classes were added to the matrix.

You can play with this by filtering/zooming until a single class is showing. And then clicking the "Add connected", "Add uses", and "Add used" buttons.

6 Tool to generate adjacency matrices

The code is available at github: Adjacency matrix code visualizer.

You can also download a fat jar of version 1.1: adjmatrix.jar.

The tool is a java command line tool. It uses Classycle to extract the dependencies from .jar files. It then generates a stand-alone html/javascript file with the adjacency matrix data, instructions, and editing capabilities.

Its most basic usage is:

$ java -jar adjmatrix.jar library-to-visualize.jar
$ firefox output.html

Author: Dan Amlund Thomsen

Created: 2019-05-09 Thu 19:53

Validate