Эта статья демонстрирует, как мы можем визуализировать граф модуля Jigsaw в приложении Java. API модуля может перечислять модули Jigsaw и их зависимые элементы, как показано ниже.
Set<Module> modules = ModuleLayer.boot().modules();
Set<Requires> requires = module.getDescriptor().requires();
С помощью этих двух простых команд мы можем получить доступ к графу связей модулей в запущенном приложении.
Для визуализации отношений модуля можно использовать vis.js. С помощью vis.js. легко создавать сетевые графики. Взгляните на следующий фрагмент кода!
// create an array with nodes
var nodes = new vis.DataSet([
{id: 'java.base', label: 'java.base'},
{id: 'java.logging', label: 'java.logging'},
{id: 'java.sql', label: 'java.sql'}
]);
// create an array with edges
var edges = new vis.DataSet([
{from: 'java.sql', to: 'java.base'},
{from: 'java.sql', to: 'java.logging'},
{from: 'java.logging', to: 'java.base'}
]);
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {};
var network = new vis.Network(container, data, options);
Вид должен быть похож на изображение ниже:
Давайте создадим целый живой визуализатор графов модулей. Сначала введите следующее:
public class Node {
private String id;
private String label;
// getters, setters, constructors
}
Node.java представляет данные узла. У каждого имени модуля будет один узел:
public class Edge {
private String from;
private String to;
// getters, setters, constructors
}
Edge.java представляет ребро между двумя узлами:
@RestController
public class ModuleGraphController {
@GetMapping("/modules")
public Map<String, HashSet<?>> moduleInfo() {
var nodes = new HashSet<Node>(); // <1>
var edges = new HashSet<Edge>(); // <2>
fillNodeAndEdges(nodes, edges); // <3>
return Map.of("nodes", nodes, "edges", edges); // <4>
}
private void fillNodeAndEdges(HashSet<Node> nodes, HashSet<Edge> edges) {
Set<Module> modules = ModuleLayer.boot().modules(); // <5>
for (Module module : modules) {
String moduleName = module.getName();
if (moduleNotContain(moduleName, "jdk")) { // <6>
nodes.add(new Node(moduleName));
}
Set<Requires> requires = module.getDescriptor().requires(); <7>
for (Requires require : requires) {
edges.add(new Edge(moduleName, require.name())); <8>
}
}
}
private boolean moduleNotContain(String moduleName, String text) {
return !moduleName.startsWith(text);
}
}
1 |
Создать набор узлов |
2 |
Создать набор ребер |
3 |
Заполнить наборы узлов и ребер |
4 |
Возвращает набор ребер и узлов на карте |
5 |
Список модулей доступа |
6 |
Пропустите внутренние модули jdk для ясности |
7 |
Доступ к модулям |
8 |
Заполнить грань между модулем и зависимым |
ModuleController — это REST-контроллер, который возвращает отношения модулей в формате JSON. Чтобы получить доступ к этим данным на стороне JS, мы можем использовать fetch api. Давайте посмотрим на это.
function showGraph(json) {
var container = document.getElementById('placeholder');
var data = {
nodes: json.nodes,
edges: json.edges
};
var options = {};
network = new vis.Network(container, data, options);
}
fetch("/modules") // <1>
.then(function (res) {
return res.json()
})
.then(showGraph); // <2>
1 |
Запрос / модули json |
2 |
Показать все модульные отношения |
Это все!
Вот окончательный результат:
Чтобы запустить демо, выполните следующие действия:
mvn clean install
java -jar target/module-graph.jar
// Then open http://localhost:8080
или
mvn clean install
docker build -t rahmanusta/module-graph .
docker run -it -p 8080:8080 rahmanusta/module-graph
// Then open http://localhost:8080
Вы можете получить полный исходный код здесь: https://github.com/rahmanusta/module-graph .