I've been researching Java package structure and dependency patterns over the last few weeks. One of the common threads across the writings on the subject is the simple rule that package dependencies should form a directed acyclic graph (DAG). Author Robert Martin even formalized the Acyclic Dependencies Principle (ADP), which states
The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure.
A few Java libraries do adhere to this simple rule. Namely, Spring Framework libraries (spring-core, spring-web, etc) and Google Guava.
However, to my surprise, the majority of leading open-source Java projects do not!
The following open-source projects have circular dependencies among packages:
- Netflix Hystrix (every package is part of a cycle!)
- AWS SDK
- Commons-Lang
- Commons-Collections
- Dagger
- Google Gson
- Google Guice
- Hibernate ORM
- Hibernate Validator
- Jackson Core
- Joda Time
- Play Framework
- Junit
- Logback
- Jetty
- AspectJ
- Netty
- java.util
- java.lang
Have I misunderstood the software engineering principle? Or do developers discount this package organization technique?