Each of the files or classes of a projects source code represents a tree (AST). Looking at dependencies to other classes besides inheritance creates a graph though. Field types and method parameters are also implicit dependencies. Storing this information in a graph database like Neo4j allows for interesting queries and insights. Class-Graph provides that and is available as open-source github project.
6. But there is more
๏Visualize & query Method, Field
dependencies
๏Collaborative filtering (co-usage)
๏Ranking
๏God classes
๏Paths between classes
6
6
7. Welcome to Class-Graph
๏take a JAR
๏put it under ASM
๏scan it superfast
๏pull everything into Neo4j
๏add categories, indexes
๏Have Fun
http://github.com/jexp/class-graph 7
7
9. Interactive Hands-On Session
๏Lots of tasks
๏use Cypher to solve them
http://neo4j.org/resources/cypher
๏be creative, work together
๏ask !
๏Server http://bit.ly/innoq-neo4j
๏just the beginning
9
9
12. Task: Subclasses of Number?
•Return just the name
•Order them alphabetically
11
11
13. Task: Subclasses of Number?
START n=node:types(name="java.lang.Number")
MATCH n<-[:SUPER_TYPE]-s
RETURN s.name
ORDER BY s.name;
•Return just the name
•Order them alphabetically
11
11
14. Task: Which Methods does it have / how many
•Find the top 5 classes with the most members
12
12
15. Task: Which Methods does it have / how many
START n=node:types(name="java.lang.Number")
MATCH n-[:METHOD_OF|FIELD_OF]->m
RETURN m;
•Find the top 5 classes with the most members
12
12
16. Task: Calculate the fan-out of
java.lang.StringBuilder
•Calculate fan-in
•Which class has the highest fan-out
•What about package-level? 13
13
17. Task: Calculate the fan-out of
java.lang.StringBuilder
START o=node:types(name="j.l.StringBuilder")
MATCH o-[:FIELD_OF]->f-[:FIELD_TYPE]->tf,
o-[:METHOD_OF]->m-[:PARAM_TYPE]->tp,
m-[:RETURN_TYPE]->tr
RETURN o,count(distinct tf)
+ count(distinct tp)
+ count(distinct tr) as fan_out;
•Calculate fan-in
•Which class has the highest fan-out
•What about package-level? 13
13
19. Task: Find longest Inheritance Path
start c=node:types(name="java.lang.Object")
match path=p<-[:SUPER_TYPE*]-c
return extract(n in nodes(path) : n.name),
length(path) as len
order by len desc
limit 5;
14
14
20. Task: Find the class that used IOException
most often
15
15
21. Task: Find the class that used IOException
most often
START ex=node:types(name="java.io.IOException"
MATCH ex<-[:THROWS]-m<-[:METHOD_OF]-c
RETURN c, count(*)
ORDER BY count(*)
LIMIT 5;
15
15
22. Task: Which other classes did classes that
threw IOException use most often?
•What could be a source of IOExceptions
16
16
23. Task: Which other classes did classes that
threw IOException use most often?
START ex=node:types(name="java.io.IOException")
MATCH ex<-[:THROWS]-m<-[:METHOD_OF]-c,
mbr<-[:METHOD_OF|FIELD_OF]-c,
mbr-[:FIELD_TYPE|PARAM_TYPE|
RETURN_TYPE|THROWS]->other_type
WHERE other_type.name =~ /.+[.].+/
RETURN other_type.name, count(*)
ORDER BY count(*) desc
LIMIT 10;
•What could be a source of IOExceptions
16
16
24. Task: Find a class you like and add a field with
your name and some type
17
17
25. Task: Find a class you like and add a field with
your name and some type
START c=node:types(name="void"),
t=node:types(name="java.lang.reflect.Proxy")
CREATE c-[:FIELD_OF]->(field {name:“Michael“})
-[:FIELD_TYPE]->t;
17
17
26. Task: Delete the most annoying class and all its
methods, fields and their relationships
18
18
27. Task: Delete the most annoying class and all its
methods, fields and their relationships
START c=node:types(name="java.awt.List"),
MATCH c-[r1:FIELD_OF|METHOD_OF]->mbr-[r2]-()
c-[r]-()
DELETE c,mbr,r1,r2,r;
18
18