jModInfGen
Tool for generating a module-info file from existing java sources.
Version 1.0.0.Final Nov 15, 2017
Overview
The jModInfGen project provides a utility to assist in the construction of a JDK 9 module-info.java file for your code. This tool uses the output from the JDK's "Java [static] class dependency analyzer", jdeps[1] utility and any existing module-info file in the project to generate a module-info.java file.
Build
This tool must be built using JDK 8.
Dependencies
jModInfGen requires the presents of classes.dot file(s) that jdeps generates. jdeps can be run manually or with the org.apache.maven.plugins:maven-jdeps-plugin.
Limitations
-
It is likely this tool will not be able to identify all the module names of all the packages reported by jdeps. jModInfGen makes the best effort to identify external module names. It reports unknown packages in the generated module.info file for the user to address.
-
The
export
directive allows the declared package to be exported only to a set of specifically-named modules, and to no others. This restriction can not be determined by this tool. The generated file may need to be editied by the user. -
The
uses
directive allows the programmer to identify a service residing in an external module that is used in this module. This is an element this tool can not detect. The user may need to provide edits to the generated module-info file. -
The
open
directive allows all of the non-public elements of the declared package to be accessed by this module. This is an element this tool can not detect. The user may need to provide edits to the generated module-info file. -
The
requires
directive has optional qualifierstransitive
andstatic
. This is information that can not be detected by this tool and may required user editing of the generated file.
Usage
jModInfGen-maven-plugin
A functioning example of the jModInfGen-maven-plugin
is provided on jboss-cxf's code base. See
https://github.com/rsearls/jbossws-cxf/blob/jModInfGen-example.
Setup
The setup entailed adding plugins maven-jdeps-plugin
and jModInfGen-maven-plugin
to the project's
root pom.xml
file. https://github.com/rsearls/jbossws-cxf/blob/jModInfGen-example/pom.xml#L1369
In order for classes.dot
files to be generated by maven-jdeps-plugin
the dotOutput
configuration
element MUST be set (line 1384). jModInfGen-maven-plugin
requires the dotOutput
directory to be in
the project's target
directory.
The jModInfGen-maven-plugin
(line 1390) declares 3 optional configuration elements. Element report
(line 1407) causes the summary report to be written to a file rather than the console. verbose
causes detailed information to be written in the summary and in each generated module-info file.
propertyFile
declares a properties file that contains package-name/module-name mappings that will
be added to jModInfGen for reference. File myExternalModMap.properties
can be see here,
(https://github.com/rsearls/jbossws-cxf/blob/jModInfGen-example/myExternalModMap.properties)
Executing The Project
Three steps are required in generating the module-info files.
- mvn clean install // jdeps requires compiled code
- mvn jdeps:jdkinternals // generate the jdeps' *.dot files
- mvn jModInfGen:generate-module-info // generates
generated module-info.java
files
Summary Report
A verbose summary report can be see here, https://github.com/rsearls/jbossws-cxf/blob/jModInfGen-example/jModInfGen-Summary-Report.txt
If the verbose
element has not been declared the default (short) summary report would look as follows.
Fri Oct 27 18:31:19 EDT 2017
jModInfoGet Summary Report
13 root directories processed
0 module-info.java files found
6 classes.dot files found
7 directories without classes.dot files
14 service provider files found
6 generated-module-info.java files written
*** Duplicate Package Names ***
1 duplicate package names found in the following modules.
package: org.jboss.wsf.stack.cxf in modules
client
server
Take particular note of any duplicate package names. Action may need to be taken to make the package names unique. The, "State of the Module System" (http://openjdk.java.net/projects/jigsaw/spec/sotms/) section 2.3 states,
"... every module reads at most one module defining a given package, and that modules defining
identically-named packages do not interfere with each other."
or described another way
... two different modules may export the same package if - at build time and at run time - no module
depends on both A and B at the same time and if A and B don't depend on each other. In theory you
could have two modules that export the same package, and use them one at a time with another
depending module.
Generated Files
Here is the list of files generated by maven-jdeps-plugin
and jModInfGen-maven-plugin
for jboss-cxf
.
The jdeps plugin generates the classes.dot
and summary.dot
files. jModInfGen plugin
generates the generated-module-info.java
files and jModInfGen-Summary-Report.txt
. Only the classes.dot
files contain information that is useful in generating a generated-module-info.java
file. No processing
is performed in any project that does not have a `classes.dot file.
These files are in the branch for your perusal
jModInfGen-Summary-Report.txt
modules/addons/transports/http/undertow/target/gen-jdeps/classes.dot
modules/addons/transports/http/undertow/target/gen-jdeps/summary.dot
modules/addons/transports/http/undertow/target/gen-jdeps/generated-module-info.java
modules/addons/transports/udp/target/gen-jdeps/classes.dot
modules/addons/transports/udp/target/gen-jdeps/summary.dot
modules/addons/transports/udp/target/gen-jdeps/generated-module-info.java
modules/client/target/gen-jdeps/classes.dot
modules/client/target/gen-jdeps/summary.dot
modules/client/target/gen-jdeps/generated-module-info.java
modules/jaspi/target/gen-jdeps/classes.dot
modules/jaspi/target/gen-jdeps/summary.dot
modules/jaspi/target/gen-jdeps/generated-module-info.java
modules/server/target/gen-jdeps/classes.dot
modules/server/target/gen-jdeps/summary.dot
modules/server/target/gen-jdeps/generated-module-info.java
modules/test-utils/target/gen-jdeps/classes.dot
modules/test-utils/target/gen-jdeps/summary.dot
modules/test-utils/target/gen-jdeps/generated-module-info.java
modules/resources/target/gen-jdeps/summary.dot
modules/endorsed/target/gen-jdeps/summary.dot
generated-module-info.java Sample
https://github.com/rsearls/jbossws-cxf/blob/jModInfGen-example/modules/test-utils/target/gen-jdeps/generated-module-info.java
This file shows what the output looks like when the verbose
element is enabled and external
packages that this project uses have been defined in the user provided properies file, myExternalModMap.properties
.
The header comment lists date of generation and the files used in the analysis and generation of this file. If a pre-existing module-info.java have had been present in the project it would have been listed here.
/**
Sat Oct 28 12:33:49 EDT 2017
File generated by jModInfoGet
Analysis of /home/rsearls/j1/jbws/jbossws-cxf/modules/test-utils
/home/rsearls/j1/jbws/jbossws-cxf/modules/test-utils/target/gen-jdeps/classes.dot
**/
The (generated) module-name is the name of the project directory. If a module-info.java file had been present, the module-name declared there would have been used instead.
module test-utils {
The single line comments after each requires
declarations is identifying which packages
residing in the required module that this project is referencing. This is merely debugging
information and does not appear when verbose
is not active.
Note that the org.jboss.shrinkwrap
module mapping provided in the myExternalModMap.properties
is referenced here.
requires java.xml.ws;
//javax.xml.ws - package referenced
//javax.xml.ws.handler - package referenced
//javax.xml.ws.soap - package referenced
requires org.jboss.shrinkwrap;
//org.jboss.shrinkwrap.api - package referenced
//org.jboss.shrinkwrap.api.exporter - package referenced
//org.jboss.shrinkwrap.api.spec - package referenced
At the end of the file is a comment containing a list of packages this project references but for which jModInfGen does not have a module-name.
/**
The module names for these packages are unknown.
User intervention may be needed.
requires org.jboss.logging;
requires org.jboss.ws.common;
requires org.jboss.ws.common.concurrent;
requires org.jboss.ws.common.io;
requires sun.net.util;
**/
jModInfGen Executable Jar
An executable jar is provided so that jModInfGen can be run from the command-line.
Input options can be see via the --help
option.
java -jar analyzer-1.0.0-Final.one-jar.jar --help
jModInfoGen command-line options
-d --inputDirectory Path to the directory from which to start analysis.
Default directory is the one from which jModInfGen is run.
-f --file Path to a java properties file that contains package name to module name mappings.
The file format is <qualified package name>:<module name>
(e.g. java.applet:java.desktop
javax.jws:java.xml.ws
org.omg.CosNaming:java.corba )
--help Print the command-line options
-r --report Write the Summary Report to a file rather than the console.
-v --verbose The Summary Report will contains a detailed list of files found and processed.
Project Structure
-
Project module,
mod-info-parser
uses lexical analyzer JFlex and LALR Parser Generator for Java java_cup in extracting data from each module-info.java file. This tool does not process module-info.class files as this would require JDK9. -
Project module,
analyzer
processes the data written toclasses.dot
by utilityjdeps
and a module-info.java file found in the project directory. It generates a module-info file of the analyzed data. -
Project
maven-plugin
provides a plugin to be used on multi-module maven projects. It will identify cross module dependences. This plugin relies on the output from org.apache.maven.plugins:maven-jdeps-plugin.maven-jdeps-plugin
must be configured to generateclasses.dot
files.
Related Tools
Currently there are 2 other known 3rd party projects related to addressing
JSR 376: "The Java Platform Module System" in Project Jigsaw[2],
maven-jdeps-plugin
[3] and moditect
[4].
-
The
maven-jdeps-plugin
uses the JDK's jdeps tool to analyze the classes in each maven module of a project. The plugin can run on each module of a multi-module project but it does not perform dependency analysis across modules. (jModInfGen when pointed to the root directory of a multi-module maven project does perform a cross module analysis of the jdeps analysis files and generates references to the inter-project modules.) -
Moditect
is a maven plugin. It generates a module-info.java file for given artifacts for Maven dependencies or local JAR files in the project. The module directives can be declared within configuration elements of the plugin definition.
moditect and jModInfGen differ in the following ways,
- moditect requires JDK 9 in order to run. Your app can't make use of this tool to generate module-info files until it can build with JDK 9. jModInfGen will run using JDK 8.
- moditect allows the project to retain pre-defined module directives in the pom.xml. The focus of jModInfGen is to initially generate the module directives. jModInfGen could be used to generate the initial module information and plug that data into the moditect configuration declarations.