Java#

The Java module supports the ability to read in data from jar files, zip files and directories containing class files. War and ear files are treated just like directories that you can browse within and and select the classes and jar file to load.

Options and Partition Options allow a further degree of control.

Users can investigate dependencies at any level - from a jar, directory, package to a class, interface, inner class, inner interface, method and field level.

Options#

CreateNewProject_java_include_exclude_classes

Member Level Processing#

Using LDM’s member level functionality, classes and interfaces can be further expanded down to methods and fields.

Do Not Load Members

This is the default. By default, LDM creates a project whose leaf elements are Classes and Interfaces. All references between the leaf elements are aggregated to the Class or Interface level.

Load Members for Specified Elements

You can specify the list of elements which are expanded down to their members.

Load All Members

Members are enabled for the entire project.

Note that you can also enable member level functionality after a project is loaded:

  1. Right click on a subsystem to bring up a list of menus. You can expand the entire project by right clicking on $root.

  2. Select Expand Members.

  3. If you did not have members turned on, a project update dialog will come up. Click OK to update the project.

Enable Line Number Processing#

With this option turned on, you can navigate to the line in code for a specific dependency. Note that you con configure in an editor of your choice through Preferences.

Include only classes matching these patterns#

Specify Java regular expressions (which are like Perl style regular expressions) and those classes and interfaces whose names match the expression will be loaded in. Note that the class and interface names are fully qualified names.

For example a pattern of the form .*Test.* will match any name which contains the string Test, while Test.* will only match any name that starts with Test. You have a great deal of flexibility since these are Java regular expression. For instance, .*[tT]est.* will match any name that contains either Test or test.

Exclude classes containing these patterns#

Specify Java regular expressions (which are like Perl style regular expressions) and those classes and interfaces whose names match the expression will not be loaded. Note that the class and interface names are fully qualified names.

For example a pattern of the form .*Test.* will match any name which contains the string Test, while Test.* will only match any name that starts with Test. You have a great deal of flexibility since these are Java regular expression. For instance, .*[tT]est.* will match any name that contains either Test or test.

Revision Field Name#

User can specify a string that represents the name of a Java String constant. If the java plugin finds a String constant with the given name, the constant value will be read and stored in an atom property named “revision”.

Hide Synthetic Variables#

With this option turned on, synthetic variables that the Java compiler has added to the bytecode (e.g. this$0) will be ignored.

Partition Options#

The New Project Dialog has partition options which allows user control over how partitions are generated.

Create Subsystems for Jar Files/Class Path#

This option creates a partition for each top level file that is loaded in. Thus a partition is generated for each jar file and each directory that is loaded in. Each file partition in turn contains a package and class hierarchy. The Java plugin, by default, will turn this option on when there are multiple jars, zips, and directories being loaded. If this option is turned off, the top level partitions are all packages. This option should be set after you have specified the input.

Ignore Duplicate Classes and Interfaces#

By default, duplicate classes and interfaces are ignored. With this option turned on, duplicate classes and interfaces are displayed. However, their dependencies are not displayed.

Atom Types and Dependency Kinds#

The Java module generates a number of atom types and dependency kinds. This enables filtering, rule specification and usage display based on the value of atom types and dependency kinds.

The Java module generates the following types of atoms:

  • Class

  • Class.Method

  • Class.Field

  • Interface

  • Interface.Method

  • Interface.Field

The Java module generates the following kinds of dependencies:

  • Class Reference: Reference to class name

  • Invokes: Method call - there are three subkinds: virtual (regular Java method), static and interface (calling a method on a java interface)

  • Inherits: Inheritance - there are two subkinds: inherits, implements

  • Data Member Reference: Reference to a field in class or interface

  • Constructs: Constructor call - there are two subkinds: constructor without arguments, constructor with arguments

Filtering based on dependency kinds can be used to gauge the level of effort required for refactoring to clean up the architecture

Example: Filter Weak Dependencies#

Weak Dependencies are defined as dependencies only on the name of the class. Such dependencies imply that little or no design knowledge of that class is required. If removing dependencies between subsystems is desirable, Weak Dependencies are the easiest to cleave apart.

For Java systems, the following Dependency Kinds would be Weak Dependencies

  • Class Reference

  • Null Constructor (no arguments)

In order to filter out these dependencies:

  1. Select View –> Filter Dependencies.

  2. Uncheck the checkbox, Class Reference.

  3. Uncheck the checkbox, Null Constructor (no arguments).

  4. Click on Apply

When fixing problematic dependencies, weak dependencies are often the easiest ones to eliminate.

Example: Filter Static Invocation#

A very common use for static methods is as utility functions. Generally, they are created in classes to which they are related. If they are related to multiple classes then they can sometimes be placed in the wrong (from an architectural perspective) class. If that is the case, they can often be moved from one class to another. To filter out static methods:

  1. Select View –> Filter Dependencies

  2. Make sure that all items are checked and then Uncheck the checkbox, Static Invocation.

  3. Click on Apply

Note that with Lattix you can even go down to member level and move a method from one class to another to figure out the right level for a method.

Example: Allowing Dependency only on Interfaces#

Use atom types to allow a subsystem to depend on another but only through interfaces. By default, all subsystems are allowed to use one another. Simply add a rule which disallows one subsystem to use another while filtering out dependencies where the target/provider atom is of type Interface.

Limitations#

  1. Constants are inlined by the Java compiler and cannot be seen in class files. Here is an example of such a constant:

    public final static int MAX_COUNT = 4;

    All references to the variable MAX_COUNT will use the number ‘4’ instead of the variable.

    Lattix provides an additional Java Constant Analyzer utility that analyzes source code to extract dependencies that are based on constants.

  2. The Lines of Code metric for each class is extracted from the debug information within a class file. If the debug information is not available, it will be reported as zero. Lines of code information is not available for interfaces.