Holy classloader recursion, Batman!
I've installed about 40 random plugins on Jenkins on Tomcat and run the code above on it to get the sense of how long it takes to run them. Each full lookup is taking a whopping 500ms!
5595
5628
5604
5610
5573
5622
5783
6417
5703
5687
The problem is that AntClassLoader.findResources is calling parent.getResources() when it really shouldn't. The parent classloader in this case is DependencyClassLoader, which tries every dependency. The net result is that Tomcat classloader gets hit O(E*V) times for the number of edges and nodes in the plugin dependency graph.
But this makes no sense, because we specifically call AntClassLoader.findResources(String) to prevent recursion into parent classloader. The reason this happens is because AntClassLoader has the following line:
parent!=getParent() indeed because Ant doesn't call the superclass constructor and pass in the specified parent classloader.
After fixing this in 9a2882dd704bece9b7ca51a52347dad15d79f843, this went down to the following:
69
13
15
14
10
10
10
9
8
9
Problem solved!
jglick suggests I should use "who-am-i" as a benchmark.