#+TITLE: JavaInspect - Utility to visualize java software * (document settings) :noexport: ** use dark style for TWBS-HTML exporter #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: * General - This program is free software: you can redistribute it and/or modify it under the terms of the [[https://www.gnu.org/licenses/lgpl.html][GNU Lesser General Public License]] as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Program authors: - Svjatoslav Agejenko - Homepage: http://svjatoslav.eu - Email: mailto://svjatoslav@svjatoslav.eu - [[http://www.svjatoslav.eu/projects/][Other software projects hosted at svjatoslav.eu]] - Tony Bargnesi - GitHub fork for the project: https://github.com/abargnesi/javainspect ** Source code - [[http://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=snapshot;h=HEAD;sf=tgz][Download latest snapshot in TAR GZ format]] - [[http://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=summary][Browse Git repository online]] - Clone Git repository using command: : git clone http://www2.svjatoslav.eu/git/javainspect.git * Goal and operating principle Goal: simplify/speed up understanding the computer program code by automatically visualizing its structure. [[http://www3.svjatoslav.eu/projects/sixth-3d/graphs/][See example produced graphs]] for [[http://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D - 3D engine project]]. JavaInspect can be used as a [[id:acf1896a-74b4-4914-acf6-a77075e07f25][standalone commandline utility]] as well as [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][java library]]. JavaInspect uses primarily Java built-in reflection to discover and visualize any part of Java program. JavaInspect currently has no GUI, configuration files, embedded scripting support, direct Maven or Ant integration. See [[id:2ad2889e-6c95-4662-b3f4-2c341fc74522][usage]] to learn how to instuct Javainspect what to do. After discovering application structure and optionally filtering out unimportant parts, JavaInspect produces GraphViz dot file that describes data to be visualized. Then launches GraphViz to generate bitmap graph in PNG or SVG format. By default on your Desktop directory when operated in library mode or current working directory when operated as standalone commandline application. Notes: + JavaInspect is developed and tested so far only on GNU/Linux. + See: [[https://github.com/pahen/madge][Madge - similar tool for JavaScript]] * Example graphs + A very simple example: [[file:example.png][file:example.resized.png]] Graph legend: file:legend.png + [[http://www3.svjatoslav.eu/projects/sixth-3d/graphs/][See example produced graphs]] for [[http://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D - 3D engine project]]. * Usage :PROPERTIES: :ID: 2ad2889e-6c95-4662-b3f4-2c341fc74522 :END: JavaInspect can be controlled in 2 different ways: + [[id:acf1896a-74b4-4914-acf6-a77075e07f25][as standalone commandline utility]] + [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][as embedded Java library via Java API]] ** usage as commandline utility :PROPERTIES: :ID: acf1896a-74b4-4914-acf6-a77075e07f25 :END: To enable commandline support, (study and) execute script: : commandline launcher/install Warning: It was tested only on Debian Stretch linux. Available commandline arguments: #+BEGIN_VERSE -j (existing files)... JAR file(s) to render. -n (mandatory, string) Graph name. --debug Show debug info. -k Keep dot file. -h Hide orphaned classes. -w (one to many strings)... Whitelist glob(s). -b (one to many strings)... Blacklist glob(s). -d (existingdirectory) Target directory. Default is current directory. -t (options: png, svg) Target image type. Default is: svg. #+END_VERSE ** usage via Java API :PROPERTIES: :ID: bbeeffc8-3767-440d-8d93-ec9124dd60ee :END: Requires that classes to be visualised are available in the classpath. To get JavaInspect into same classpath with your projecs I so far came up with 2 solutions: 1. Add JavaInspect library in your project as a dependency. 2. Create new Java project for the purpose visualizing your other projects and include JavaInspect and your projecs binary artifacts (Jar's) into new project classpath. Built binary Jar's (with no source code) are sufficient because JavaInspect operates via reflection. Simple Java based control/configuration code needs to be written for each project. I usually put such code into directories devoted for JUnit tests. Because it needs not to be compiled/embedded into final product or project artifact I'm just willing to visualize. Control code in general does the following: 1. Create graph object. 2. Java reflection/classloaders does not provide mechanism for discovering all classes under given package. Therefore you need to declare at least some classes to be added to the graph by: + Manually adding individual classes to the graph. + and/or: Let GraphViz recursively scan and parse specified directories with Java source code files to discover class names. + For every class added to the graph, GraphViz will recursively inspect it and add all referecned classes to the graph as well. 3. Graphs easilly get very big and complex so optionally we filter important code using classname wildcards patterns based blacklist and/or whitelist. 4. Optionally we can tune some rendering parameters like: + Possibility to remove orphaned classes (classes with no references) from the graph. + Specify target directory for generated visualization files. (Default is user desktop directory) + Keep intermediate GraphViz dot file for later inspection. 5. Render graph. *** example 1: individually picked objects This example demonstrates generating of class graph from hand picked classes and visualizing GraphViz itself. #+BEGIN_SRC java // Create graph final ClassGraph graph = new ClassGraph(); // Add some random object to the graph. GraphViz will detect Class from // the object. graph.add(graph); // Also add some random class to the graph. graph.add(Utils.class); // Keep intermediary GraphViz DOT file for reference. graph.setKeepDotFile(true); // Produce bitmap image titled "JavaInspect.png" to the user Desktop // directory graph.generateGraph("JavaInspect"); #+END_SRC Note: if desired, more compact version of the above: #+BEGIN_SRC java new ClassGraph().add(randomObject, RandomClass.class) .setKeepDotFile(true).generateGraph("JavaInspect"); #+END_SRC Result: - Generated DOT file: [[file:JavaInspect.dot][JavaInspect.dot]] - Generated PNG image: [[file:JavaInspect.png][JavaInspect.png]] *** example 2: scan java code, apply filters #+BEGIN_SRC java // Create graph final ClassGraph graph = new ClassGraph(); // Recursively scan current directory for Java source code and attempt // to detect class names from there to be added to the graph. graph.addProject("."); // Blacklist example classes from being shown on the graph graph.blacklistClassPattern("eu.svjatoslav.inspector.java.structure.example.*"); // do not show single classes with no relationships on the graph graph.hideOrphanedClasses(); // Produce bitmap image titled "JavaInspect full project.png" to the // user Desktop directory. graph.generateGraph("JavaInspect full project"); #+END_SRC Result: - Generated PNG image: [[file:JavaInspect%20full%20project.png][JavaInspect full project.png]] *** example 3: GraphViz embedded in another project 1. Download project Sixth [[http://www2.svjatoslav.eu/gitweb/?p=sixth.git;a=snapshot;h=HEAD;sf=tgz][code snapshot]]. 2. Inspect and run *DataGraph.java*. *** Embedding JavaInspect in your Maven project Declare JavaInspect as dependency: #+BEGIN_SRC xml ... eu.svjatoslav javainspect 1.6 ... #+END_SRC Add Maven repository to retrieve artifact from: #+BEGIN_SRC xml ... svjatoslav.eu Svjatoslav repository http://www2.svjatoslav.eu/maven/ ... #+END_SRC * Requirements [[http://www.graphviz.org/][GraphViz]] - shall be installed on the computer. On Ubuntu/Debian use: #+BEGIN_SRC sh sudo apt-get install graphviz #+END_SRC * TO DO Note: Because this is side project (and I have many of them) I can only contribute few hours per year at average. Any help is welcome. A LOT of cool ideas could be implemented. For intstance: - BUG: Should not hide references if there are too many of them to classes if referring classes are not visible anyway because of blacklist/whitelist rules. Basically reference counting should exclude not visible classes. - BUG: Orphaned class removal does not work always. There are many bugs and corner cases to find and fix still. - BUG: Code is not very readable. Document and refactor for better maintainability. - FEATURE: Create installable DEB package. - Submit it to some Debian developer for integration or become Debian package maintainer. - FEATURE: Make it modular. That is: central part, an application model could be standalone and serializable. - There could be multiple ways to acquire model: - By introspecting application via Java reflections (current mode of operation). - By parsing java source. (unfinished) - There could be ways to manipulate model: - Store/load/compare. - Trim uninteresting parts. - Highlight important parts. - There could be multiple ways to render model: - PNG/SVG (currently implemented) - PlantUML (TODO) - Interactive 3D visualization (TODO) - FEATURE: Replace internal java parser in package eu.svjatoslav.inspector.java.methods with: https://javaparser.org/ - FEATURE: Integarte with [[http://plantuml.com/class-diagram][PlantUML]]. - FEATURE: Add dark theme for generated graphs. - FEATURE: Sort Class fields by alphabet. - FEATURE: Visualize also concrete field values so it could be used as ultra cool runtime logging/debugging framework. - FEATURE: Possibility to visualize structure and data from JVM snapshot. - FEATURE: Possibility to attach to remote process to visualize data/structure using JVM debug port and mechanism. - FEATURE: Possibility to attach to JVM using JVM agent. - FEATURE: Possibility to inspect graphs in 3D using [[http://www2.svjatoslav.eu/gitbrowse/sixth-3d/doc/index.html][Sixth 3D engine]]. - FEATURE: Possibility to select classes/fields/values to be visualized in some graph query language. For greater flexibility in comparison to currently supported glob syntax. - FEATURE: Add option to control JavaInspect via JSON or XML config file. For example different graphs for given project could be defined once in plain text config, possibly with the aid of some interactive utility. Then defined graphs could be updated as part of project build or release process. - FEATURE: Configurable maven plugin to generate graphs as part of the project build/release process.