Tim, I appreciate a non-circular dependency graph.  But, that should be my 
decision to want that, not something that tools demand.  What happens 
typically, is that it forces you to actually make the wrong decision about how 
to create that graph and then requires extra work to build a non-circular view 
which eventually deteriorates into a huge mess because there are too many 
branches that attempt to introduce an interface to decouple the circular 
dependency for compiling, but you still have to create a circular dependency in 
class loading because that's how the beast fits together. 

The JVM is indeed a great example of how it's inseparable because of inter 
package dependencies.  A dependency analysis tool can help you draw the 
picture, and I use one to create downloadable jars with minimal content to 
reduce download and disk storage overhead.

Drawing the dependency graph to understand how separation works at interface 
boundaries is a fine idea.  The reality is that there is never a non-circular 
dependency  situation in mature software from a class loading perspective.  

Collections are the typical implementation that is everywhere.  Well, things 
like logging are also everywhere.  Just because logging uses collections to 
hold records of loggers, properties, handlers etc., and collections uses 
logging to allow insight into it's behaviors doesn't mean that they need to 
always be in the same package.

Indeed, interfaces could allow them to be independent, yet, they are not 
because there are not interfaces that describe all the behaviors that each uses 
from the other.

If we had interfaces everywhere, it would be nightmarish to keep up with all of 
the interface definitions and use those when there isn't any real ability to do 
that because of construction not being done with factories everywhere.  But 
then you'd have dependencies on factory classes and it would still not work.

So in the end, it's pointless to use the circular dependency concept as a 
problem statement.  It's unsolvable!  The right answer is to actually make 
tools which can deal with the concept of incomplete dependency graphs so that 
you can move on.

The fact that Java doesn't deep resolve all class dependencies on the first 
class loaded is partially a solution to incomplete dependency graphs.  It 
allows all kinds of flexibility it what can happen to resolve classes.

There are so many other tooling issues that Java needs to address to be able to 
be fully exploited for the power that the class loading mechanisms really 
provide.

Why isn't there a mechanism in the platform for the jar to define invisible 
dependencies (classes loaded with Class.forName(), or otherwise invisible 
dependencies)?

Why isn't there a dependency tool set that builds minimal sized jar files?

Why aren't nested jars possible so that I could just put everything I needed 
into one jar and use jar:jar:jar:… urls to load them?

Why has the entire java industry prolifically dictated that their jars (by 
licensing) can not be pulled apart into just the needed components?

What is most frustrating is that the monolithic assembly of Java-EE has caused 
people to focus on all of the wrong solutions to creating a Java "application".

OSGi tries to solve the packaging problem by introducing so many bits and 
pieces of the system, replicated over and over in multiple places.  It's 
supposed to make tooling be the mechanism for solving dependency problems, yet 
its not part of the development process in such a way that the dependency graph 
is always visible.

That's what is actually needed.  Dependencies should be a primary thing as part 
of the development process, and development time dependencies should not become 
the deployment time dependencies.

Gregg Wonderly

On Sep 6, 2013, at 10:22 PM, Tim Boudreau <niftin...@gmail.com> wrote:

> Gregg,
> 
> We've worked together and I respect your judgement.  That said, I have to 
> disagree pretty strongly with the idea of *not* enforcing that dependencies 
> be a directed acyclic graph as the default.
> 
> Fundamentally, if you are developing two things, and there is a circular 
> dependency between them, you do not have *two* things - you have one thing 
> which you enjoy pretending is two.  If neither can exist without the other, 
> their independence is in illusion.
> 
> I agree that sometimes you need that sort of thing, dealing with legacy 
> software and so forth.  Not too long ago, I did some detangling of a project 
> for a company that could only compile their software if they compiled against 
> (and shipped) two historical versions of their own product, and not a soul 
> there actually knew what got loaded and linked at runtime.  Terrifying but 
> true.
> 
> But that being the default is the source of a *lot* of problems.  And having 
> to understand dependencies teaches understanding of dependencies, which 
> affects how developers think about designing software.
> 
> And explicit, non-cyclical dependencies make possible - trivial, even - very 
> useful sorts of static analysis.
> 
> I've developed a similar attitude toward Maven.  Flexibility can be harmful, 
> especially when there's no obvious right way to do things - it gives you 
> enough rope to hang yourself.  I've seen so many Make and Ant based projects 
> where there was only one person in the organization who understood how their 
> build system worked.  Maven is inflexible in the extreme - there's a lot I 
> really dislike about it.  But it is utterly unambiguous.
> 
> Managed dependencies are like that.  You *want* inflexibility as a default.  
> Sure, you also want the ability to write your own classloader (IMO, 
> bytecode-over-the-wire is still one of the actually interesting things about 
> Java) and do what you want - the occasions are rare, but when you need it, 
> you need it.  But even when you *do* need it, what are you loading those 
> classes *from*?  If it's non-trivial and you want it to work, you need...its 
> dependencies!  So I suspect even when you're doing wild-west classloading, 
> there are still benefits to having this stuff be explicit and unambiguous.
> 
> I understand that for a lot of people, this JSR is about making the JDK 
> leaner and meaner.  But I think there are opportunities here to do things 
> that dramatically reduce the maintenance cost of new software written in 
> Java, and it would be a pity not to seize the opportunity to kill two birds 
> with one stone.
> 
> -Tim

Reply via email to