Building Dependency Webs in J2EE
by Alex Iskold and Daniel Kogan01/29/2003
J2EE applications are fundamentally complex. A typical system may contain thousands of EJBs, Java classes, JSP pages, and servlets, which are linked into an intricate web of numerous dependencies. Managing this complexity is the key to building stable and flexible J2EE applications. To deal with complexity, it is important to focus on the structure of the dependencies between all components in the system. Excessive, unnecessary dependencies lead to chaotic, unmanageable, and costly systems. On the other hand, stable software is always well-structured and does not contain extraneous dependencies.
Cutting-edge science supports the importance of dependency-centric thinking. The emerging Complexity Science studies common patterns and themes in biological, economic, social, and physical systems. These systems are made of parts organized into a network, or a Dependency Web. The interactions between the parts of this network give rise to the greater whole -- the system itself.
From this perspective, any software can be thought of as a network of components and interactions. Complexity Science says that the structure of the overall Dependency Web is one of the determining factors in the stability and longevity of the entire system. This article will illustrate how to apply the concepts of Dependency Web Theory to your J2EE applications.
Dependency Webs
The structure of a J2EE application is the Dependency Web of components and the relationships between them. The rule is: if component A knows about component B, it depends on it. Put differently, if the code of component A refers to component B, then component A depends on component B.
For example, in Pet Store, customer.jsp contains the following
code:
<c:out value="${customer.account.contactInfo.givenName}"/>
This implies that customer.jsp depends on
CustomerEJB, AccountEJB, and
ContactInfo.
Similarly, the following code in CustomerEJB.java makes
CustomerEJB dependent on AccountEJB:
public abstract void setAccount(AccountLocal account);
You can map dependents and dependencies for every EJB, JSP page, or servlet. Put it all together to create the Dependency Web for your J2EE application.
An Example of a Java Dependency Web

Figure 1 -- example of an UML Dependency Web in Java
To analyze a Dependency Web effectively, you need to make sure to identify all nodes and dependencies correctly.
First, let's look at a simple example. Instead of considering all nodes of a J2EE Dependency Web, let's consider the basic ones that come from the Java language. In Java, the nodes are Classes, Interfaces, and Packages. Classes and Interfaces are linked by means of standard UML relationships: Uses, Contains, Extends, and Implements.
|
Related Reading
|
Figure 1 shows an example of a piece of Java code translated into its
corresponding Dependency Web. The class JFrame extends
Frame and implements SwingConstants, so it depends on
the Frame class and the SwingConstants interface.
Also, the keyEvent method of JFrame takes a
KeyEvent class as an argument, which makes JFrame
dependent on KeyEvent. The method getGlassPanel of
JFrame returns Component, which implies that
JFrame depends on the Component class. Finally, since
JFrame contains the variable rootPane of type
JRootPane, the JFrame class depends on the
JRootPane class.
An Example of a J2EE Dependency Web
J2EE has a richer Dependency Web than J2SE. In addition to classes, interfaces, and packages, J2EE has Enterprise Java Beans, JSP pages, servlets, HTML pages, XML configuration files, and .jars.
Let's take a look at an example of a J2EE Dependency Web from Pet Store. We
will consider the dependencies in the neighborhood of the
CatalogDAO interface.
We will only focus on the dependencies that are specific to the Pet Store application; that is, we will ignore the core Java and J2EE classes and interfaces. We will also ignore the dependencies on inner classes and exceptions.

Figure 2 -- CatalogDAO dependencies

Figure 3 -- CatalogDAO dependents
Figure 2 shows how the method signatures in the CatalogDAO
interface give rise to the four Uses dependencies. Based on this code,
CatalogDAO uses the Category, Page,
Product, and Item classes.
In Figure 3, you see extracts from four different files that show the
dependents of the CatalogDAO interface. First, we see that
CatalogDAOFactory returns CatalogDAO in the
getDAO method. GenericCatalogDAO depends on the
CatalogDAO interface because it implements it.
CatalogHelper and CatalogEJB both depend on
CatalogDAO because they contain an instance of this interface.
In any Dependency Web, if component A depends on component B, we say that A
and B are one degree away from each other. So all immediate dependents and
dependencies of the CatalogDAO interface are considered to be one
degree away from it. However, the complete Dependency Web of
CatalogDAO may be very large, since it includes all objects that
are in some way linked to this interface.
We will now show how you can build the second degree Dependency Web for
CatalogDAO. For this, we simply need to consider the dependents
and dependencies of the objects that are one degree away from this
interface.
For classes Category, Page, Product,
Item, GenericCatalogDAO, and
CatalogDAOFactory, the dependencies are identified in exactly the
same way that we described above. We want to focus instead on additional
dependencies that are induced by CatalogHelper and
CatalogEJB.
The CatalogHelper is used in several JSP pages. For example,
the product.jsp contains a use bean tag that refers to
CatalogHelper bean (see Figure 4), so product.jsp
depends on the CatalogHelper.

Figure 4 -- product.jsp uses CatalogHelper

Figure 5: ejb-jar.xml uses CatalogEJB
Figure 5 illustrates yet another kind of J2EE dependency. The XML deployment
descriptor ejb-jar.xml for the CatalogEJB refers to
the bean and, thus, depends on it.
If we put together all of the described dependencies, we get the following Dependency Web:

Figure 6 -- a second-degree Dependency Web for CatalogDAO
Legend:

Note that arrows always point from the independent object to dependent, creating the direction of the flow of change.
Let's look at the interdependencies between the classes that surround
CatalogDAO to make sure that we understand what we are seeing.
GenericCatalogDAO and CloudscapeCatalogDAO both
implement the CatalogDAO interface. This implies that they should
depend on Item, Page, Category, and
Product, and this is exactly what we see in Figure 6.
Thinking in Terms of Dependency Webs
In this article, we have shown how you can construct a simple J2EE Dependency Web. Dependency Webs are representations of the intricate networks of dependencies within your software. Thinking about dependencies helps to simplify complex J2EE applications.
Dependency Webs are important because they offer compact visual representations of local and global structures in our systems. While we are buried knee-deep in code, we often forget to think about the big picture. The visuals of the Dependency Web are always informative and revealing. By looking at and analyzing Dependency Webs, we often uncover the unexpected or unnecessary dependencies.
Notes
- For a broad introduction to Complexity Science see Complexity, by M. Mitchell Waldrop (ISBN 0671872346).
- We have used Pet Store 1.3.1 for this article.
- Factories always depend on the objects that they instantiate, since they "know" about them.
- A complete Dependency Web includes all transitive dependencies; that is, A -> B, B -> C implies A -> C.
Alex Iskold is a founder of Information Laboratory, a New York based company that created Small Worlds, a Software Analysis and Visualization tool.
Daniel Kogan is a founder of Information Laboratory, a New York based company that created Small Worlds, a Software Analysis and Visualization tool.
Return to ONJava.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 6 of 6.
-
Transitive Dependencies
2003-02-03 08:37:13 anonymous2 [Reply | View]
Your example is not a software example. But perhaps I am confused about your definition of dependency. You state it in your website and in this article as a reference in the source file. Again, by this definition, there are no transistive dependencies.
Secondly, your use of complexity science to justify your product is very suspect. Perhapas you should instead categorize this under "Systems Theory". Complexity theory is primarly focused on the simple generative rules that create these complex systems, it has little to say about the resultant complex system, it is systems theory that has been devoted to the study of the complex interconnected networks you describe.
In additon, your "case studies" and white papers make wide claims about productivity increases and the benefits of keeing dependencies low. You however make no reference to ANY justification to these claims.
interfaces are often used to break a dependency between two objects, yet one clearly exists that your product does not account for. As a quick example, classA implements B, and classC calls a method on B. Class C depends on class A behaving a certain way as prescribed by the interface, yet there is no reference in the source or class from C to A.
Perhpas your definition of dependency needs to be clarified?
I have no doubt that your tool helps in the understanding of a system. But the claim that code metrics have any bearing on code quality, maintainability, and performance is far fetched.
-
Transitive Dependencies DO exist!
2003-02-02 20:40:25 iskold [Reply | View]
Let me address the points that you have made one by one.
First, transitive dependencies do exist in software just like they exist in any complex system. For example, companies depend on people, and economy depends on companies, so it also depends on people.
Perhaps it was not made clear that there 2 sorts of dependencies: immediate and transitive. Immediate dependencies are the ones explicit in the source files. Transitive are the consequences of several immediate dependencies.
Next, you are saying that we do distinguish between the kinds of relationships that exist between components. Of course we do, look at the example of Java relationships. Moreover, we assign the weight to each relationship based on the number of interactions.
It is not true that you always end up with highly interconnected graphs. At Information Laboratory, we have studies hundreds of open source and commercial systems. The only systems that are highly interconnected are the bad, unstable ones. Good systems exhibit complex hierarchical structures that resemble balanced binary trees.
Dependency Web thinking is inspired by cutting edge ideas in the science of network of mathematical graphs. It allows engineers to focus on what is essential about components.
I suggest that you try the tool that we have developed on your code http://www.thesmallworlds.com before you call Dependency Webs useless.
Alex
-
Transitive dependencies do not exist., and your graphs are useless
2003-02-02 16:41:27 anonymous2 [Reply | View]
You state
"A complete Dependency Web includes all transitive dependencies; that is, A -> B, B -> C implies A -> C. "
This is not the case, A does not depend on C by your definition. There is no reference to C in A, in either the source or class file.
I would further argue, that your definition of dependency is very weak. And your example graphs are far from usefull artifacts.
You define "depends on" as simply reffering to another component in the source (you don't even consider the class file, but you should). Your definition does not account for the actuall demands that A will place on B. There are many contracts that exists between components, and dealing only with "reffers to" relationship is not usefull at all. You will typically end up with a highly interconnected graph. Espically if you draw the graph at the class level, as you have done.
Drawing such dependency graphs at a higher level, sucha as package, or even web application level will yield more usefull information. But like I said, these diagrams don't provide much information about contract and protocol. And I find there use highly suspect for this reason.
-
Transitive dependencies do not exist., and your graphs are useless
2003-05-01 10:34:46 anonymous2 [Reply | View]
Do you even understand what the word dependency means?
if class A->B and class B->C then A->C is certainmy true, for a change in the interface of C might imply a change of the interface of B and hence of the interface of A.
So before making a fool of yourself, think! And if these graphs are too difficult for you maybe you should start thinking of looking for another job, because it's exactly people like you that are making bad overly complex code due to a lack of understanding of dependency. -
Transitive dependencies do not exist., and your graphs are useless
2005-09-20 03:34:25 Janick388 [Reply | View]
I absolutely agree.
In my experience the biggest single factor which leads to high quality, easily maintainable software is an understanding the importance of dependency relationships.
High quality software should not exhibit any dependency cycles (not just between packages, but between classes within packages too). This is a key principle and the most important difference between software 'engineering' and simply hacking out code.
For me but the crunch point came several years ago when I ran the source code for my current project through a dependency analysis tool. The code written by the senior developers on my team was 100% free of cycles - but mine was not. Consequently I had to recode everything I had written before anyone else noticed! Since then I have not looked back.
Unfortunately, most software is not well engineered when you run it through a dependency analysis tool - but then high quality software engineering seems a pretty rare thing.
N





Systems theory and Complexity Theory, agree that
Complex Systems are networks of interacting components. Moreover, these networks are nested. It is exactly this nested nature of these networks that gives rise to transitivity.
Complexity scientists agree that modeling complex systems as networks is an essential step towards understanding them. I would recommend you to read latest book by Duncan Watts, called Six Degrees.
The claims that we make are substantiated as follows. We compute average impact of change and stability metrics based on the Dependency Webs that we construct. We then correlated these metrics with incidences of undesirable structures such as cyclic dependencies, hubs, etc. Poorly written systems exhibit high average impact of change, low stability and large number of undesirable structures.
Your example:
ClassA implements B, and class C calls a method on B. Class C depends on class A behaving a certain way as prescribed by the interface, yet there is no reference in the source or class from C to A.
I think that I already clarified this above. This is a transitive dependency. If you remove Class A, Class C will not work.
The claims that we make are not far fetched. First of all we have data to back them up. Secondly, they are common sense. If you are careless about creating dependencies and pay little attention to the structure of your software you will soon end up with the system that is complete out of your control. Ask any good engineer.
Alex