title: How is the Java Service Provide API supposed to work?
body: <p>It seems like everybody has had an unpleasant brush with the <a href="http://download.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Service%20Provider" rel="noreferrer">Java Service Provider</a>, that thing you can do with a file named like META-INF/services/com.example.Interface, but that nobody uses except for trying to load the right XML parser.  I'm trying to work with a library that uses the Service Provider API, and trick it so that I can provide some runtime-extended classes (using cglib) that don't actually implement the interface but can be made to do so easily.</p>
  
  <p>Basically, I think the steps I need to perform are:<ol>
  <li>Create a custom class loader that will respond to getResources(...) and return an "extra" URL</li>
  <li>Also have that class loader hook getResourceAsStream(...) to return a list of the classes I am going to manipulate with cglib, when asked for the "extra" resource</li>
  <li>Finally, have that class loader load those classes when requested</li></ol></p>
  
  <p>But here's where I get lost.  For example, when the library tries to determine what implementers are out there, it calls getResources(...) which returns a bunch of URLs.  But getResourceAsStream(...) doesn't take URLs, it takes "names".  Names which seem to be classpath-relative, and therefore the same everywhere.  So META-INF/services/com.example.Interface in has the same "name" as META-INF/services/com.example.Interface in their JAR, right?  Except somehow this works with those blasted XML parsers...</p>
  
  <p>Of course, all of this assumes they were smart/kind enough to call ClassLoader.getSystemClassLoader() rather than using ClassLoader.getSystemResources(...), ClassLoader.getSystemResourceAsStream(...), etc., as in the latter case there's no way to hook the ClassLoader and provide the faked file.</p>
  
  <p>I guess in that case I could use BCEL to manipulate the class files when my code is being packaged by Maven, rather than waiting until runtime to do it with cglib?</p>