One thing that's still missing is a good way to reason about dependencies, in a way that's integrated with the code itself.
For example, let's say someone has written this code in my project:
import org.awesome.SuperclassFromSomewhere;
public class MySubclass extends SuperclassFromSomewhere {
...
}
Where does the superclass come from? Is it in my project? Is it being imported from a library? What if there are multiple libraries providing a class with the same fully qualified name? What if there are multiple versions of the class, within multiple versions of the library?
After doing a little refactoring, maybe I get rid of the dependency on the superclass.
Can I remove any libraries from my classpath? And when I remove those libraries, do I also get rid of other dependencies?
Current solutions (like maven) only simplify the process of over-cluttering a project with dependencies. They don't address the challenge of reasoning about and eliminating dependencies.
I'm working on a project right now that has over 60 libraries in its classpath, and it's very hard to understand where all the code comes from and how all those different libraries interact. I think I only have 10 or 15 direct dependencies, but then each of those libraries requires its own list of dependent libraries.
And thanks to dependency injection, and reflective class-loading, it's virtually impossible to figure out what the REAL dependencies are, short of running the code and inspecting the guts of the JVM.
It's entirely possible that some of those dependent libraries are only being used in one or two places within my project (or zero, for all I know), and I could eliminate thousands of dependent classes, from dozens of libraries, just by rewriting a method or two. But without any good tools for reasoning about dependencies, I don't really know.