2010-07-21 3 views
0

Essayer d'utiliser javax.imageio.spi.ServiceRegistry pour enregistrer dynamiquement les processeurs de demande d'HttpServlet:constructeur ServiceRegistry échoue avec ClassCastException sur la classe concrète

private static final Class PROVIDER_CLASS = IRequestProcessor.class; 

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

L'erreur que je reçois est:

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) 

La classe GetStandardCodesProcessor implémente IRequestProcessor. L'appel ServiceRegistry.lookupProviders() obtient une liste de classes à partir du fichier META-INF/services/org.confused.servlet.IRequestProcessor. Il semble que je manque une nuance sur la façon de passer dans l'itérateur de ServiceRegistry.lookupProviders().

This page montre à peu près ce que je fais, tout en assignant le retour de lookupProviders() à un Iterator non typé, qui à son tour est passé au constructeur ServiceRegistry. Cette technique donne la même erreur pour moi. Enfin, je cours cela dans Eclipse Gallileo (build 20100218-1602), si cela est important.

Cordialement, Drew

Répondre

2

Je n'ai jamais utilisé cette classe SPI avant, toutefois, de la API documentation, le constructeur de ServiceRegistry prend dans une Iterator avec des catégories et non fournisseurs. Vous souhaiterez peut-être enregistrer vos fournisseurs avec registerServiceProviders() à la place?

+0

Merci d'avoir pris le temps de répondre. Alors que je pouvais ajouter manuellement les classes via registerServiceProviders(), je cherchais à tirer parti de la reconnaissance de classe automagique que propose ServiceRegistry.lookupProviders(). Je pensais que l'Iterator dans ServiceRegistry (Iterator >) devait être la liste des classes à enregistrer; cherche-t-il les interfaces à la place? – Werd

+0

Mais la vérité est, le constructeur (Iterator >) n'est pas destiné aux fournisseurs d'enregistrer mais des catégories de fournisseurs. – yclian

+0

Merci, maintenant je comprends. Je donnerais +1 à votre réponse, mais je ne suis pas encore digne. :( – Werd

1

yclian, merci pour le "bonk sur la tête".

Le constructeur attend en effet la liste des 'catégories', qui sont les interfaces que le registre peut rechercher. Une fois que j'ai corrigé cette partie, et rempli le ServiceRegistry comme vous l'avez dit, le reste fonctionne très bien.

Le nouveau code:

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