Create module-info.java
in some directory.
module viz { requires java.se; }
Create class app.App.java
(in the app
sub-directory)
package app; import java.lang.module.ModuleDescriptor.Requires; import java.util.HashSet; import java.util.Set; /** * This is the main application to generate graph code. * * @author Mikalai Zaikin (mzaikin@gmail.com) */ public class App { public static void main(String[] args) { App app = new App(); var edges = app.getEdges(); var modules = app.getModules(); // System.out.println(modules); StringBuffer sb = new StringBuffer("digraph Java11 {\n"); sb.append(" ratio = fill;\n"); sb.append(" node [style=filled];\n"); edges.forEach((e) -> { sb.append(String.format(" \"%s\" -> \"%s\";%n", new Object[]{e.getFrom(), e.getTo()})); }); modules.forEach((m) -> { sb.append("\""+m+"\" [color=\"" + (m.startsWith("jdk") ? "darkseagreen" : "cyan") + "\"];\n"); }); sb.append("}"); System.out.println(sb); } private HashSet<Edge> getEdges() { var edges = new HashSet<Edge>(); Set<Module> modules = ModuleLayer.boot().modules(); modules.forEach((module) -> { String moduleName = module.getName(); if (!("viz".equals(moduleName))) { Set<Requires> requires = module.getDescriptor().requires(); requires.forEach((require) -> { edges.add(new Edge(moduleName, require.name())); }); } }); return edges; } private HashSet<String> getModules() { var mods = new HashSet<String>(); Set<Module> modules = ModuleLayer.boot().modules(); for (Module module : modules) { String moduleName = module.getName(); if ("viz".equals(moduleName)) continue; mods.add(moduleName); } return mods; } }
Create class app.Edge.java
(in the app
sub-directory)
package app; import java.util.Objects; /** * This is the class to encapsulate edge of the graph. * * @author Mikalai Zaikin (mzaikin@gmail.com) */ public class Edge { private String from; private String to; public Edge(String from, String to) { this.from = from; this.to = to; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Edge edge = (Edge) o; return Objects.equals(from, edge.from) && Objects.equals(to, edge.to); } @Override public int hashCode() { return Objects.hash(from, to); } @Override public String toString() { return from + "->" + to; } }
Run the code from the directory where module-info.class
is located:
C:\USERS\IBM_ADMIN\DOCUMENTS\NETBEANSPROJECTS\VIZ\BUILD\MODULES └───viz │ module-info.class │ └───app App.class Edge.class
"C:\Program Files\Java\jdk-11.0.2\bin\java.exe" --module-path . -m viz/app.App
There should be similar output:
digraph Java11 { ratio = fill; node [style=filled]; "java.management.rmi" -> "java.base"; "java.sql" -> "java.xml"; "java.se" -> "java.management.rmi"; "java.xml.crypto" -> "java.base"; "java.se" -> "java.scripting"; "java.sql" -> "java.base"; "jdk.scripting.nashorn" -> "java.base"; "jdk.security.jgss" -> "java.security.sasl"; "java.smartcardio" -> "java.base"; "jdk.naming.dns" -> "java.naming"; "java.xml.crypto" -> "java.xml"; "java.prefs" -> "java.base"; "java.se" -> "java.rmi"; "java.sql.rowset" -> "java.base"; "java.compiler" -> "java.base"; "jdk.localedata" -> "java.base"; "jdk.security.auth" -> "java.security.jgss"; "jdk.naming.rmi" -> "java.rmi"; "java.desktop" -> "java.prefs"; "java.prefs" -> "java.xml"; "java.rmi" -> "java.logging"; "jdk.security.jgss" -> "java.logging"; "jdk.jdeps" -> "jdk.compiler"; "java.se" -> "java.instrument"; "jdk.accessibility" -> "java.desktop"; "jdk.jfr" -> "java.base"; "jdk.accessibility" -> "java.base"; "java.logging" -> "java.base"; "jdk.jdeps" -> "java.base"; "jdk.naming.rmi" -> "java.naming"; "jdk.jlink" -> "jdk.jdeps"; "java.se" -> "java.base"; "jdk.unsupported.desktop" -> "java.desktop"; "jdk.crypto.cryptoki" -> "jdk.crypto.ec"; "jdk.security.auth" -> "java.base"; "java.sql.rowset" -> "java.sql"; "jdk.compiler" -> "java.base"; "jdk.jdeps" -> "java.compiler"; "jdk.internal.opt" -> "java.base"; "jdk.naming.dns" -> "java.base"; "java.rmi" -> "java.base"; "jdk.management.jfr" -> "java.base"; "jdk.security.jgss" -> "java.security.jgss"; "java.sql" -> "java.transaction.xa"; "java.scripting" -> "java.base"; "java.management" -> "java.base"; "jdk.dynalink" -> "java.logging"; "jdk.management.jfr" -> "java.management"; "java.se" -> "java.sql"; "java.se" -> "java.transaction.xa"; "jdk.javadoc" -> "jdk.compiler"; "jdk.scripting.nashorn" -> "java.scripting"; "java.se" -> "java.logging"; "jdk.crypto.mscapi" -> "java.base"; "java.se" -> "java.compiler"; "jdk.jlink" -> "jdk.internal.opt"; "java.sql" -> "java.logging"; "java.security.jgss" -> "java.naming"; "jdk.scripting.nashorn" -> "java.logging"; "jdk.charsets" -> "java.base"; "java.desktop" -> "java.datatransfer"; "jdk.crypto.ec" -> "java.base"; "java.xml.crypto" -> "java.logging"; "java.sql.rowset" -> "java.logging"; "jdk.management.jfr" -> "jdk.jfr"; "jdk.naming.rmi" -> "java.base"; "jdk.management.jfr" -> "jdk.management"; "jdk.jartool" -> "java.base"; "java.naming" -> "java.base"; "java.transaction.xa" -> "java.base"; "java.se" -> "java.xml"; "jdk.javadoc" -> "java.xml"; "java.datatransfer" -> "java.base"; "java.se" -> "java.desktop"; "jdk.management" -> "java.base"; "jdk.compiler" -> "java.compiler"; "jdk.crypto.cryptoki" -> "java.base"; "java.security.sasl" -> "java.base"; "java.se" -> "java.security.sasl"; "java.se" -> "java.prefs"; "java.security.jgss" -> "java.base"; "jdk.security.auth" -> "java.naming"; "jdk.jlink" -> "java.base"; "jdk.zipfs" -> "java.base"; "java.net.http" -> "java.base"; "java.desktop" -> "java.xml"; "java.se" -> "java.sql.rowset"; "java.management.rmi" -> "java.naming"; "jdk.security.jgss" -> "java.base"; "java.desktop" -> "java.base"; "jdk.scripting.nashorn" -> "jdk.dynalink"; "jdk.unsupported.desktop" -> "java.base"; "jdk.management" -> "java.management"; "java.se" -> "java.management"; "java.instrument" -> "java.base"; "java.naming" -> "java.security.sasl"; "java.xml" -> "java.base"; "jdk.javadoc" -> "java.base"; "java.sql.rowset" -> "java.naming"; "java.se" -> "java.xml.crypto"; "jdk.javadoc" -> "java.compiler"; "java.se" -> "java.datatransfer"; "jdk.dynalink" -> "java.base"; "java.management.rmi" -> "java.management"; "java.security.sasl" -> "java.logging"; "java.se" -> "java.security.jgss"; "java.se" -> "java.naming"; "java.se" -> "java.net.http"; "java.management.rmi" -> "java.rmi"; "jdk.management.jfr" [color="darkseagreen"]; "java.sql" [color="cyan"]; "java.rmi" [color="cyan"]; "jdk.charsets" [color="darkseagreen"]; "java.transaction.xa" [color="cyan"]; "java.xml.crypto" [color="cyan"]; "java.logging" [color="cyan"]; "java.xml" [color="cyan"]; "jdk.jfr" [color="darkseagreen"]; "java.datatransfer" [color="cyan"]; "jdk.crypto.cryptoki" [color="darkseagreen"]; "java.naming" [color="cyan"]; "java.desktop" [color="cyan"]; "java.se" [color="cyan"]; "java.prefs" [color="cyan"]; "java.net.http" [color="cyan"]; "jdk.compiler" [color="darkseagreen"]; "jdk.naming.rmi" [color="darkseagreen"]; "jdk.internal.opt" [color="darkseagreen"]; "java.security.sasl" [color="cyan"]; "jdk.zipfs" [color="darkseagreen"]; "java.base" [color="cyan"]; "jdk.crypto.ec" [color="darkseagreen"]; "jdk.javadoc" [color="darkseagreen"]; "jdk.crypto.mscapi" [color="darkseagreen"]; "java.management" [color="cyan"]; "java.sql.rowset" [color="cyan"]; "jdk.jlink" [color="darkseagreen"]; "java.smartcardio" [color="cyan"]; "jdk.scripting.nashorn" [color="darkseagreen"]; "java.instrument" [color="cyan"]; "java.security.jgss" [color="cyan"]; "jdk.management" [color="darkseagreen"]; "java.compiler" [color="cyan"]; "jdk.security.auth" [color="darkseagreen"]; "java.scripting" [color="cyan"]; "jdk.dynalink" [color="darkseagreen"]; "jdk.unsupported.desktop" [color="darkseagreen"]; "jdk.jdeps" [color="darkseagreen"]; "jdk.accessibility" [color="darkseagreen"]; "jdk.jartool" [color="darkseagreen"]; "java.management.rmi" [color="cyan"]; "jdk.naming.dns" [color="darkseagreen"]; "jdk.security.jgss" [color="darkseagreen"]; "jdk.localedata" [color="darkseagreen"]; }
Use this graph text definition to generate image at http://www.webgraphviz.com or http://viz-js.com.
The result will look as follows:
![]() ![]() ![]() |