Way back in 1968, Edsger Dijkstra almost caused a riot at the ACM conference. His audacious crime? "Use of GOTO considered harmful." No one there could imagine writing code without GOTO's. Yet, of course, within a few years, GOTO-oriented programming faded away, replaced by structured, modular, and object-oriented programming. Structured programming has become such the mainstream that we don't even refer to that feature of the language anymore: we never say that C is a "Non-GOTO" language.
Fast forward to today. In the same way that C isn't a "Non-GOTO" language, I contend that Java is no longer an object-oriented language. Sure, the object abstraction is still there, but it has sunk so far down into the infrastructure we don't even think about it anymore. This blog really drove it home for me: Java is a library oriented language. Think about it: when was the last time you downloaded a single class from the Internet to use in an application? Libraries and frameworks are the code reuse mechanisms in Java. Ultimately, the class is just too fine grained to really achieve reuse, but libraries can.
This explains tools like Maven and Ivy. While Java is a library oriented language, no good facilities exist within the language to manage libraries. Some work has been done on the "module" specification, but word from insiders say that is has essentially collapsed into two warring factions: the OSGI vs. Maven camps. Consequently, it looks doubtful that a module facility will appear anytime soon for Java. That's OK: we'll keep doing what we've always done while waiting for ratification of infrastructure -- use open source tools that solve this problem.
Ultimately, we need to embrace the idea of Java as a Library-Oriented Language. That means treat libraries (and dependencies between libraries) as first class citizens in your projects. Developers tend to try to avoid nasty coupling and circular references with classes, yet too often tolerate it with their JAR files. Looking at Java in this light forces you to think about how you create project directory structure (Maven helps with this, as well as tools like AppFuse, which creates consistent directory structures for different kinds of web applications). Convention over configuration was one of the "breath of fresh air" approaches from Ruby on Rails. It makes building tools and plugins for Rails easy because you can always rely on a standard directory structure for projects. Of course, it's too late now to create the universal standard Java project structure, but you can do this within your own company. Once you have a consistent structure, it makes writing little utilities that can do things to all your projects much easier.
Consistency is the key to automation.
A consistent directory structure for all projects makes it easy to plug into continuous integration, write test helper classes, manage dependencies across projects, and a slew of other benefits. Start treating Java like a library oriented language, think hard about dependencies, versions, and where things live. And, finally, create consistency across projects so that you can take advantage of economy of scale.