X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=blobdiff_plain;f=doc%2Findex.org;h=91ef69908a7b9c5b5484d23848e10403ec038f05;hb=249e21dca059ebeea2e1b5761b0c1abcea985883;hp=8ec6dcb8f53e381ca10ef4378829cf50c3b18d78;hpb=8886bb51f2caf11b8e778bacb4c8ea18ac7f1027;p=javainspect.git diff --git a/doc/index.org b/doc/index.org index 8ec6dcb..91ef699 100644 --- a/doc/index.org +++ b/doc/index.org @@ -1,128 +1,371 @@ #+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: -- [[http://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=snapshot;h=HEAD;sf=tgz][download]] -- [[http://svjatoslav.eu/programs.jsp][other applications hosted at svjatoslav.eu]] -- Program author: - - Svjatoslav Agejenko - - Homepage: http://svjatoslav.eu +* 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: https://svjatoslav.eu - Email: mailto://svjatoslav@svjatoslav.eu + - [[https://www.svjatoslav.eu/projects/][Other software projects hosted at svjatoslav.eu]] -* General + - Tony Bargnesi + - GitHub fork for the project: + https://github.com/abargnesi/javainspect + +** Source code +:PROPERTIES: +:ID: 032b7997-f582-4203-b31a-43ef7b654ed6 +:END: +- [[https://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=snapshot;h=HEAD;sf=tgz][Download latest snapshot in TAR GZ format]] + +- [[https://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=summary][Browse Git repository online]] + +- Clone Git repository using command: + : git clone https://www2.svjatoslav.eu/git/javainspect.git + +* Goal and operating principle Goal: simplify/speed up understanding the computer program code by automatically visualizing its structure. -JavaInspect is a Java library that you can embed into your Java -project with a few lines of Maven configuration and then visualize any -part of your Java program structure with few simple JavaInspect API -calls at application runtime. +[[https://www3.svjatoslav.eu/projects/sixth-3d/graphs/][See example produced graphs]] for [[https://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D - 3D engine project]]. -JavaInspect uses Java reflection to discover class relations and -structure and produces GraphViz dot file that describes your -application. Then launches GraphViz to generate bitmap graph in PNG -format on your Desktop directory. +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. -* Current status -This is simple utility, quickly written. Tested on GNU Linux (can be -relatively simply ported to other operating systems too). So far I -used it for my own needs. There might be bugs and missing -features. Feedback and code contributions are welcome. +JavaInspect currently has no graphical user interface, configuration +files, embedded scripting support, direct Maven, Gradle 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 [[https://graphviz.org/][GraphViz]] to generate +bitmap graph in PNG or SVG format. + +Notes: ++ JavaInspect is developed and tested so far only on GNU/Linux. * Example graphs -Example visualization of [[http://www2.svjatoslav.eu/gitbrowse/sixth/doc/][Sixth]] project: [[http://www2.svjatoslav.eu/projects/sixth/codegraphs/][architecture graphs]]. ++ A very simple example: -A very simple example: + [[file:example.png][file:example-thumbnail.png]] -[[file:example.png][file:example.resized.png]] + Graph legend: + file:legend.png -Graph legend: -file:legend.png ++ [[https://www3.svjatoslav.eu/projects/sixth-3d/graphs/][See example produced graphs]] for [[https://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D - 3D engine project]]. -* Usage example 1 +* Installation +[[http://www.graphviz.org/][GraphViz]] - shall be installed on the computer. + +On Ubuntu/Debian GraphViz can be installed using: +#+BEGIN_SRC sh +sudo apt-get install graphviz +#+END_SRC + +To use JavaInspect via Java API, no further installation is +needed. JavaInspect will be embedded into your project as dependency. +This is described in [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][usage via Java API]]. It will expect GraphViz to be +available in the system. + +To use JavaInspect as a commandline tool, JavaInspect source +repository has to be cloned locally: See [[id:032b7997-f582-4203-b31a-43ef7b654ed6][Source code]]. + +Then study and execute installation script: +: commandline launcher/install + +After installation, new commandline tool should be available +: javainspect + +Quick commandline usage help can be viewed by issuing +: javainspect --help + +* 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: +*** Available commandline arguments +#+BEGIN_VERSE +-j (existing files)... + JAR file(s) to render. + +-c (existing directories)... + Classpath directories + +-n (string) + Graph name. (default: "graph") + +--debug + Show debug info. + +-h, --help + Show commandline usage help. + +-k + Keep dot file. + +-ho + Hide orphaned classes. + +-w (one to many strings)... + Whitelist glob(s). + +-b (one to many strings)... + Blacklist glob(s). + +-r (one to many strings)... + root class(es). + +-d (existing directory) + Target directory. Default is current directory. + +-t (options: png, svg) + Target image type. Default is: svg. +#+END_VERSE +*** Specifying classes to render +Normal Java application has immense complexity. In addition to code +that was directly written by particular project developers, lots of +functionality is typically added as frameworks or libraries to the +project. In addition there is significant Java standard library. + +Because JavaInspect uses reflection, it does not easily distinguish +between those. In normal situation you would rather want to visualize +only code that was developed specifically for your project and leave +frameworks like Spring etc. out. If you visualize all classes that are +possibly reachable from you project, you will easily get huge and +incomprehensible graph. + +JavaInspect can digest compiled Java classes in 2 modes: +1. Provide list of Jar files. Use *-j* option. +2. Provide list of filesystem directories that can be used as + classpath root. Use *-c* option. + +Currently JavaInspect uses following algorithm to add classes to +rendered graph: + +- All classes that were found in Jar files are added to graph by default. +- None of the classes that were found in filesystem directories are + added to the graph by default (unless explicitly referenced). (TODO: + for consistency it would be better to add them too by default) +- If whitelist is specified (*-w* option) everything that is not + matched by whitelist pattern(s) will be removed from the graph. +- If blacklist is specified (*-b* option) everything that is matched + by blacklist pattern(s) will be removed from the graph. +- Root classes can be specified using *-r* option. Root classes will + be added to the graph. JavaInspect will then try to recursively + discover all classes that were referenced by root class and add + those also to the graph. + +** 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. 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 [[https://en.wikipedia.org/wiki/Glob_(programming)][glob]] 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 current 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. +classes and visualizing GraphViz itself. #+BEGIN_SRC java - // Create graph - final ClassGraph graph = new ClassGraph(); - // While classes and objects can be immediately passed to ClassGraph - // constructor as arguments, it is also possible to add them one by - // one as in the following example. +// 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); - // Add some object to the graph. - graph.addObject(graph); +// Keep intermediary GraphViz DOT file for reference. +graph.setKeepDotFile(true); - // Add some class to the graph. - graph.addClass(Utils.class); +// Produce bitmap image titled "JavaInspect.png" to the user Desktop +// directory +graph.generateGraph("JavaInspect"); - // Produce bitmap image titled "JavaInspect.png" to the user Desktop - // directory and keep intermediary GraphViz DOT file for reference. - graph.generateGraph("JavaInspect", true); #+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]] -* Usage example 2 -Recursively scan current directory for Java source code and attempt to -detect class names from there to be added to the graph. - -#+BEGIN_SRC java - graph.addProject("."); - - // Blacklist example classes from being shown on the graph - graph.getFilter().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 2: GraphViz embedded in another project +1. Download project Sixth [[https://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 +*** Embedding JavaInspect in your Maven project Declare JavaInspect as dependency: #+BEGIN_SRC xml - - ... - - eu.svjatoslav - javainspect - 1.3 - - ... - + + ... + + eu.svjatoslav + javainspect + 1.7 + + ... + #+END_SRC Add Maven repository to retrieve artifact from: #+BEGIN_SRC xml - - ... - - svjatoslav.eu - Svjatoslav repository - http://www2.svjatoslav.eu/maven/ - - ... - + + ... + + svjatoslav.eu + Svjatoslav repository + http://www3.svjatoslav.eu/maven/ + + ... + #+END_SRC -* Requirements +* 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: -[[http://www.graphviz.org/][GraphViz]] - shall be installed on the computer. +- 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: Implement (or integrate existing java parser + https://javaparser.org/) to be able to produce code visualizations + based on source code (in addition to current reflection based + approach). + +- 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 [[https://www3.svjatoslav.eu/projects/sixth-3d/][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. -On Ubuntu/Debian use: -: sudo apt-get install graphviz +- FEATURE: Configurable maven plugin to generate graphs as part of the + project build/release process. +* See also +Similar or alternative solutions: ++ http://www.class-visualizer.net/ ++ [[https://github.com/pahen/madge][Madge - similar tool for JavaScript]]