I'd like to visualize method chains of our codebase (which method invokes which method) starting from a given method with jqassistant.
For normal method calls the following Cypher query works. workupNotification
is the method I am starting from:
MATCH (begin:Method {name: "workupNotification"}) -[INVOKES*1..20]-> (method:Method) WHERE not method:Constructor and exists(method.name) RETURN begin, method, type
But many of the methods calls in our software are calls to interfaces of which the implementation is not known in the method (SOA with Dependency Inversion).
serviceRegistry.getService(MyServiceInterface.class).serviceMethod();
How can I select the implementation of this method (There are two classes implementing each interface. One is automatically generated (Proxy), the other is the one I'm interested in.)
You need to do what the JVM is performing at runtime for you: resolving virtual method invocations. There's a predefined jQAssistant concept that propagates INVOKES relations to implementing sub-classes: java:InvokesOverriddenMethod
. You can either reference it as a required concept from one of your own rules or apply it from the command line, e.g. with Maven:
mvn jqassistant:analyze -Djqassistant.concepts=java:InvokesOverriddenMethod
The rule is documented in the manual, see http://buschmais.github.io/jqassistant/doc/1.6.0/#java:InvokesOverriddenMethod
(The name of the concept is not intuitive, it would be better to replace it with something like java:VirtualInvokes
).