Our system was written by neophyte troglodytes who didn't follow standards of any kind. They coded whatever they wanted, however they wanted, whenever they wanted, wherever they wanted. Usually via copy/paste/plagiarize.

In particular, we have a class called Tree. More accurately, there are 18 (yes, that's e-i-g-h-t-e-e-n) Tree classes; one each for: char, byte, short, int, long, float, double, Character, Byte, Short, Integer, Long, Float, Double, String, BigInteger, BigDecimal and Object[]. One might think: Hey! Let's use generics: Tree<T>. Nope! Each one is needlessly just a little bit different. Some implement the same methods with different types. Some have methods with completely different implementations to do the same thing. Some use completely different names for the same methods. Sometimes, the methods are identically named, and the parameters are the kind that can be auto-up-cast (e.g.: short -> int):

  public class Tree { // com.wtfinc.blah.Tree; project A
     public void doThing(short x) { /* do stuff */ }
  }

  public class Tree { // com.wtfinc.blah.Tree; project B
     public void doThing(int x) { /* do Different stuff */ }
  }

This means that if you accidentally reference the project-B Tree when you wanted the project-A tree, and pass a short, it will work due to auto up-casting, but not do what you thought. However, all 18 are in different projects, but with the exact same path: com.wtfinc.blah.Tree.

While this is annoying to mere humans, they all look different and distinct to an IDE like Eclipse, and it puts the right Tree in the right jar.

However, when you use wildcards to build your classpath, the jars are loaded alphabetically, and if you've led a good life, leads to all sorts of nearly impossible-to-track NoSuchMethodExceptions because when you click through in the IDE, it takes you to the correct method.

Add to this the fact that all of our servers (dev, qa, preprod and prod) have different OS patch levels (even across servers within the same environment), and the glob expansion of the classpath '*' wildcard doesn't always bring back the jars in alphabetical order, which causes an 8th circle of hell: the class loader finds a Tree which by dumb luck has a matching method because of auto up-casting. Now you may not even get an exception when the wrong method is called!

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!