Possibility to provide classpath dir. Updated help and documentation.
[javainspect.git] / doc / index.org
1 #+TITLE: JavaInspect - Utility to visualize java software
2
3 * (document settings) :noexport:
4 ** use dark style for TWBS-HTML exporter
5 #+HTML_HEAD: <link href="https://bootswatch.com/3/darkly/bootstrap.min.css" rel="stylesheet">
6 #+HTML_HEAD: <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
7 #+HTML_HEAD: <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
8 #+HTML_HEAD: <style type="text/css">
9 #+HTML_HEAD:   footer {background-color: #111 !important;}
10 #+HTML_HEAD:   pre {background-color: #111; color: #ccc;}
11 #+HTML_HEAD: </style>
12
13 * General
14 - This program is free software: you can redistribute it and/or modify
15   it under the terms of the [[https://www.gnu.org/licenses/lgpl.html][GNU Lesser General Public License]] as
16   published by the Free Software Foundation, either version 3 of the
17   License, or (at your option) any later version.
18
19 - Program authors:
20   - Svjatoslav Agejenko
21     - Homepage: https://svjatoslav.eu
22     - Email: mailto://svjatoslav@svjatoslav.eu
23     - [[https://www.svjatoslav.eu/projects/][Other software projects hosted at svjatoslav.eu]]
24
25   - Tony Bargnesi
26     - GitHub fork for the project:
27       https://github.com/abargnesi/javainspect
28
29 ** Source code
30 :PROPERTIES:
31 :ID:       032b7997-f582-4203-b31a-43ef7b654ed6
32 :END:
33 - [[https://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=snapshot;h=HEAD;sf=tgz][Download latest snapshot in TAR GZ format]]
34
35 - [[https://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=summary][Browse Git repository online]]
36
37 - Clone Git repository using command:
38   : git clone https://www2.svjatoslav.eu/git/javainspect.git
39
40 * Goal and operating principle
41 Goal: simplify/speed up understanding the computer program code by
42 automatically visualizing its structure.
43
44 [[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]].
45
46 JavaInspect can be used as a [[id:acf1896a-74b4-4914-acf6-a77075e07f25][standalone commandline utility]] as well as
47 [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][java library]]. JavaInspect uses primarily Java built-in reflection to
48 discover and visualize any part of Java program.
49
50 JavaInspect currently has no graphical user interface, configuration
51 files, embedded scripting support, direct Maven, Gradle or Ant
52 integration. See [[id:2ad2889e-6c95-4662-b3f4-2c341fc74522][usage]] to learn how to instuct Javainspect what to do.
53
54 After discovering application structure and optionally filtering out
55 unimportant parts, JavaInspect produces GraphViz dot file that
56 describes data to be visualized. Then launches [[https://graphviz.org/][GraphViz]] to generate
57 bitmap graph in PNG or SVG format.
58
59 Notes:
60 + JavaInspect is developed and tested so far only on GNU/Linux.
61
62 * Example graphs
63 + A very simple example:
64
65     [[file:example.png][file:example-thumbnail.png]]
66
67     Graph legend:
68
69     file:legend.png
70
71
72 + [[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]].
73
74 * Installation
75 [[http://www.graphviz.org/][GraphViz]] - shall be installed on the computer.
76
77 On Ubuntu/Debian GraphViz can be installed using:
78 #+BEGIN_SRC sh
79 sudo apt-get install graphviz
80 #+END_SRC
81
82 To use JavaInspect via Java API, no further installation is
83 needed. JavaInspect will be embedded into your project as dependency.
84 This is described in [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][usage via Java API]]. It will expect GraphViz to be
85 available in the system.
86
87 To use JavaInspect as a commandline tool, JavaInspect source
88 repository has to be cloned locally: See [[id:032b7997-f582-4203-b31a-43ef7b654ed6][Source code]].
89
90 Then study and execute installation script:
91 : commandline launcher/install
92
93 After installation, new commandline tool should be available
94 : javainspect
95
96 Quick commandline usage help can be viewed by issuing
97 : javainspect --help
98
99 * Usage
100   :PROPERTIES:
101   :ID:       2ad2889e-6c95-4662-b3f4-2c341fc74522
102   :END:
103 JavaInspect can be controlled in 2 different ways:
104 + [[id:acf1896a-74b4-4914-acf6-a77075e07f25][as standalone commandline utility]]
105 + [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][as embedded Java library via Java API]]
106
107 ** Usage as commandline utility
108    :PROPERTIES:
109    :ID:       acf1896a-74b4-4914-acf6-a77075e07f25
110    :END:
111 *** Available commandline arguments
112 #+BEGIN_VERSE
113 -j (existing files)...
114     JAR file(s) to render.
115
116 -c (existing directories)...
117     Classpath directories
118
119 -n (string)
120     Graph name. (default: "graph")
121
122 --debug
123     Show debug info.
124
125 -h, --help
126     Show commandline usage help.
127
128 -k
129     Keep dot file.
130
131 -ho
132     Hide orphaned classes.
133
134 -w (one to many strings)...
135     Whitelist glob(s).
136
137 -b (one to many strings)...
138     Blacklist glob(s).
139
140 -r (one to many strings)...
141     root class(es).
142
143 -d (existing directory)
144     Target directory. Default is current directory.
145
146 -t (options: png, svg)
147     Target image type. Default is: svg.
148 #+END_VERSE
149 *** Specifying classes to render
150 Normal Java application has immense complexity. In addition to code
151 that was directly written by particular project developers, lots of
152 functionality is typically added as frameworks or libraries to the
153 project. In addition there is significant Java standard library.
154
155 Because JavaInspect uses reflection, it does not easily distinguish
156 between those. In normal situation you would rather want to visualize
157 only code that was developed specifically for your project and leave
158 frameworks like Spring etc. out. If you visualize all classes that are
159 possibly reachable from you project, you will easily get huge and
160 incomprehensible graph.
161
162 JavaInspect can digest compiled Java classes in 2 modes:
163 1. Provide list of Jar files. Use *-j* option.
164 2. Provide list of filesystem directories that can be used as
165    classpath root. Use *-c* option.
166
167 Currently JavaInspect uses following algorithm to add classes to
168 rendered graph:
169
170 - All classes that were found in Jar files are added to graph by default.
171 - None of the classes that were found in filesystem directories are
172   added to the graph by default (unless explicitly referenced). (TODO:
173   for consistency it would be better to add them too by default)
174 - If whitelist is specified (*-w* option) everything that is not
175   matched by whitelist pattern(s) will be removed from the graph.
176 - If blacklist is specified (*-b* option) everything that is matched
177   by blacklist pattern(s) will be removed from the graph.
178 - Root classes can be specified using *-r* option. Root classes will
179   be added to the graph. JavaInspect will then try to recursively
180   discover all classes that were referenced by root class and add
181   those also to the graph.
182
183 ** Usage via Java API
184    :PROPERTIES:
185    :ID:       bbeeffc8-3767-440d-8d93-ec9124dd60ee
186    :END:
187 Requires that classes to be visualised are available in the classpath.
188
189 To get JavaInspect into same classpath with your projecs I so far came
190 up with 2 solutions:
191
192 1. Add JavaInspect library in your project as a dependency.
193
194 2. Create new Java project for the purpose visualizing your other
195    projects and include JavaInspect and your projecs binary artifacts
196    (Jar's) into new project classpath. Built binary Jar's (with no
197    source code) are sufficient because JavaInspect operates via
198    reflection.
199
200 Simple Java based control/configuration code needs to be written for
201 each project. I usually put such code into directories devoted for
202 JUnit tests. Because it needs not to be compiled/embedded into final
203 product or project artifact I'm just willing to visualize.
204
205 Control code in general does the following:
206 1. Create graph object.
207 2. Java reflection/classloaders does not provide mechanism for
208    discovering all classes under given package. Therefore you need to
209    declare at least some classes to be added to the graph by manually
210    adding individual classes to the graph. For every class added to
211    the graph, GraphViz will recursively inspect it and add all
212    referecned classes to the graph as well.
213 3. Graphs easilly get very big and complex so optionally we filter
214    important code using classname [[https://en.wikipedia.org/wiki/Glob_(programming)][glob]] patterns based blacklist and/or
215    whitelist.
216 4. Optionally we can tune some rendering parameters like:
217    + Possibility to remove orphaned classes (classes with no
218      references) from the graph.
219    + Specify target directory for generated visualization
220      files. (Default is current directory)
221    + Keep intermediate GraphViz dot file for later inspection.
222 5. Render graph.
223
224
225 *** Example 1: individually picked objects
226 This example demonstrates generating of class graph from hand picked
227 classes and visualizing GraphViz itself.
228
229 #+BEGIN_SRC java
230
231 // Create graph
232 final ClassGraph graph = new ClassGraph();
233
234 // Add some random object to the graph. GraphViz will detect Class from
235 // the object.
236 graph.add(graph);
237
238 // Also add some random class to the graph.
239 graph.add(Utils.class);
240
241 // Keep intermediary GraphViz DOT file for reference.
242 graph.setKeepDotFile(true);
243
244 // Produce bitmap image titled "JavaInspect.png" to the user Desktop
245 // directory
246 graph.generateGraph("JavaInspect");
247
248 #+END_SRC
249
250 Note: if desired, more compact version of the above:
251 #+BEGIN_SRC java
252 new ClassGraph().add(randomObject, RandomClass.class)
253                 .setKeepDotFile(true).generateGraph("JavaInspect");
254 #+END_SRC
255
256
257 Result:
258     - Generated DOT file: [[file:JavaInspect.dot][JavaInspect.dot]]
259     - Generated PNG image: [[file:JavaInspect.png][JavaInspect.png]]
260
261 *** Example 2: GraphViz embedded in another project
262 1. Download project Sixth [[https://www2.svjatoslav.eu/gitweb/?p=sixth.git;a=snapshot;h=HEAD;sf=tgz][code snapshot]].
263 2. Inspect and run *DataGraph.java*.
264
265 *** Embedding JavaInspect in your Maven project
266
267 Declare JavaInspect as dependency:
268 #+BEGIN_SRC xml
269 <dependencies>
270     ...
271     <dependency>
272         <groupId>eu.svjatoslav</groupId>
273         <artifactId>javainspect</artifactId>
274         <version>1.7</version>
275     </dependency>
276     ...
277 </dependencies>
278 #+END_SRC
279
280
281 Add Maven repository to retrieve artifact from:
282 #+BEGIN_SRC xml
283 <repositories>
284     ...
285     <repository>
286         <id>svjatoslav.eu</id>
287         <name>Svjatoslav repository</name>
288         <url>http://www2.svjatoslav.eu/maven/</url>
289     </repository>
290     ...
291 </repositories>
292 #+END_SRC
293
294 * TO DO
295 Note: Because this is side project (and I have many of them) I can
296 only contribute few hours per year at average. Any help is welcome.  A
297 LOT of cool ideas could be implemented. For intstance:
298
299 - BUG: Should not hide references if there are too many of them to
300   classes if referring classes are not visible anyway because of
301   blacklist/whitelist rules. Basically reference counting should
302   exclude not visible classes.
303
304 - BUG: Orphaned class removal does not work always. There are many
305   bugs and corner cases to find and fix still.
306
307 - BUG: Code is not very readable. Document and refactor for better
308   maintainability.
309
310 - FEATURE: Create installable DEB package.
311   - Submit it to some Debian developer for integration or become
312     Debian package maintainer.
313
314 - FEATURE: Make it modular. That is: central part, an application
315   model could be standalone and serializable.
316
317   - There could be multiple ways to acquire model:
318     - By introspecting application via Java reflections (current mode
319       of operation).
320     - By parsing java source. (unfinished)
321
322   - There could be ways to manipulate model:
323     - Store/load/compare.
324     - Trim uninteresting parts.
325     - Highlight important parts.
326
327   - There could be multiple ways to render model:
328     - PNG/SVG (currently implemented)
329     - PlantUML (TODO)
330     - Interactive 3D visualization (TODO)
331
332 - FEATURE: Implement (or integrate existing java parser
333   https://javaparser.org/) to be able to produce code visualizations
334   based on source code (in addition to current reflection based
335   approach).
336
337 - FEATURE: Integarte with [[http://plantuml.com/class-diagram][PlantUML]].
338
339 - FEATURE: Add dark theme for generated graphs.
340
341 - FEATURE: Sort Class fields by alphabet.
342
343 - FEATURE: Visualize also concrete field values so it could be used as
344   ultra cool runtime logging/debugging framework.
345
346 - FEATURE: Possibility to visualize structure and data from JVM
347   snapshot.
348
349 - FEATURE: Possibility to attach to remote process to visualize
350   data/structure using JVM debug port and mechanism.
351
352 - FEATURE: Possibility to attach to JVM using JVM agent.
353
354 - FEATURE: Possibility to inspect graphs in 3D using [[https://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D engine]].
355
356 - FEATURE: Possibility to select classes/fields/values to be
357   visualized in some graph query language. For greater flexibility in
358   comparison to currently supported glob syntax.
359
360 - FEATURE: Add option to control JavaInspect via JSON or XML config
361   file. For example different graphs for given project could be
362   defined once in plain text config, possibly with the aid of some
363   interactive utility. Then defined graphs could be updated as part of
364   project build or release process.
365
366 - FEATURE: Configurable maven plugin to generate graphs as part of the
367   project build/release process.
368 * See also
369 Similar or alternative solutions:
370 + http://www.class-visualizer.net/
371 + [[https://github.com/pahen/madge][Madge - similar tool for JavaScript]]