views:

18

answers:

2

Trying to use javax.imageio.spi.ServiceRegistry to dynamically register request processors for an HttpServlet:

    private static final Class PROVIDER_CLASS = IRequestProcessor.class;

 private void loadProviders() throws ClassNotFoundException {
  _serviceRegistry = new ServiceRegistry(ServiceRegistry.lookupProviders(PROVIDER_CLASS));
 }

The error I get is:

 java.lang.ClassCastException: org.confused.servlet.GetStandardCodesProcessor
javax.imageio.spi.ServiceRegistry.<init>(ServiceRegistry.java:103
org.confused.servlet.MyServlet.loadProviders(.java:100)
 org.confused.servlet.MyServlet.checkProviders(.java:106)
 org.confused.servlet.MyServlet.service(.java:44)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

The class GetStandardCodesProcessor implements IRequestProcessor. The call ServiceRegistry.lookupProviders() is getting a list of classes from the file META-INF/services/org.confused.servlet.IRequestProcessor. It seems I am missing a nuance about how to pass in the iterator from ServiceRegistry.lookupProviders().

This page shows pretty much what I'm doing, albeit assigning the the return from lookupProviders() to an untyped Iterator, which in turn gets passed to the ServiceRegistry constructor. That technique gives the same error for me.

Lastly, I am running this in Eclipse Gallileo (build 20100218-1602), if that matters.

Regards, Drew

+1  A: 

I have never used this SPI class before, however, from the API documentation, the constructor of ServiceRegistry takes in an Iterator with categories, not providers. You may want to register your providers with registerServiceProviders() instead?

yclian
Thanks for taking the time to answer.While I could 'manually' add the classes via registerServiceProviders(), I was looking to take advantage of the automagic class recognition that ServiceRegistry.lookupProviders() offers. I thought the Iterator in ServiceRegistry(Iterator<Class<?>>) was expected to be the list of classes to register; is it looking for the interfaces instead?
Werd
But the truth is, the constructor(Iterator<Class<?>>) is not meant for providers to register but categories of providers.
yclian
Thank you, now I understand.I'd +1 your answer, but I'm not worthy yet. :(
Werd
No worries. You can mark it "answered" I suppose, but if you can't, that's fine.
yclian
+1  A: 

yclian, thanks for the "bonk on the head".

The constructor is indeed expecting the list of 'categories', which are the interfaces that the registry can search for. Once I corrected that part, and populated the ServiceRegistry as you said, the rest works great.

The new code:

private void loadProviders() throws ClassNotFoundException {
    Iterator iterCategories = (Collections.singletonList(PROVIDER_CLASS)).iterator();
    _serviceRegistry = new ServiceRegistry(iterCategories);
    _serviceRegistry.registerServiceProviders(ServiceRegistry.lookupProviders(PROVIDER_CLASS));
}
Werd