Erreur de configuration de Guice: aucune implémentation liée
Je suis en train de faire DI avec Guice travail, faire (il me semble) exactement ce qui est dans le manuel.
Je ne peux pas expliquer le problème parce que je ne comprends pas vraiment - tout semble très logique et devrait fonctionner.. mais il ne le fait pas. Donc, je ne peux que joindre le code et le stacktrace:
public class Runner {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TestModule());
//next line throws the exception
JMeterComponent jMeterComponent =
injector.getInstance(JMeterComponent.class);
....
}
}
Comme vous pouvez le voir, j'essaie d'instancier un objet de JMeterComponent
classe. C'est le constructeur (comme vous le verrez plus tard) accepte les 3 arguments: ils doivent également être instancié par le Cio et les injecté.
Et voici le TestModule
avec la configuration de ces 3 arguments:
public class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(Callable.class).annotatedWith(Names.named("JMeter"))
.to(JMeterTask.class);
bind(Processor.class).annotatedWith(Names.named("JMeter"))
.to(JMeterResultsProcessor.class);
bind(Renderer.class).annotatedWith(Names.named("JMeter"))
.to(JMeterResultsWikiRenderer.class);
}
}
Maintenant, regardons ceux des implémentations concrètes - JMeterTask
JMeterResultsProcessor
et JMeterResultsWikiRenderer
(tous ont un faux corps pour la simplicité):
public class JMeterTask implements Callable<JMeterRawResults> {
public JMeterRawResults call() throws Exception {
return new JMeterRawResults();
}
}
public class JMeterResultsProcessor implements
Processor<JMeterRawResults, JMeterResults> {
public JMeterResults process(JMeterRawResults raw) {
return new JMeterResults();
}
}
public class JMeterResultsWikiRenderer implements Renderer<JMeterResults> {
public Map<String, String> render(JMeterResults jMeterResults) {
Map<String, String> results = Maps.newHashMap();
...
return results;
}
}
Et maintenant, regardons les JMeterComponent
classe, instance de la construction est le but de l'ensemble de la DI liées à des trucs ici:
public class JMeterComponent extends AbstractComponent<String, String> {
@Inject
public JMeterComponent(@Named("JMeter") Callable<String> task,
@Named("JMeter")Processor<String, String> processor,
@Named("JMeter")Renderer<String> renderer) {
super(task, processor, renderer);
}
}
Et voici la stacktrace:
Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:
1) No implementation for stat.domain.Processor<java.lang.String, java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating stat.domain.Processor<java.lang.String, java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 1 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating cstat.components.jmeter.JMeterComponent
2) No implementation for stat.domain.Renderer<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating stat.domain.Renderer<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 2 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating stat.components.jmeter.JMeterComponent
3) No implementation for java.util.concurrent.Callable<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating java.util.concurrent.Callable<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 0 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating stat.components.jmeter.JMeterComponent
Quelques faits:
- - Je utiliser guice-2.0 (avec
featured
étiquette) - Il n'y a plus aucune annotation à partir d'
com.google.inject
paquet dans une autre classe dans le code - Interfaces
Processor
etRenderer
sont placés dans un module, et leurjmeter
-implémentations (JMeterResultsProcessor
et autres) etJMeterComponent
classe sont placés dans un autre module.
C'est à peu près tout, il y a à dire à ce sujet.
Désolé pour ce long post et merci pour votre patience de le lire jusqu'à la fin.
Toutes les idées sur pourquoi les erreurs se produisent et comment le résoudre?
source d'informationauteur Roman | 2010-12-27
Vous devez vous connecter pour publier un commentaire.
Il y a plusieurs problèmes que je vois ici.
D'abord,
Callable
etCallable<String>
sont différents. Si vous voulez injecter unCallable<String>
(ouProcessor<String, String>
etc.) dans Guice, vous devez lier quelque chose àCallable<String>
pasCallable
.Deuxièmement, vous êtes liaison
Callable
àJMeterTask
qui implémenteCallable<JMeterRawResults>
mais vous êtes l'injection deCallable<String>
dansJMeterComponent
'constructeur (même chose pourProcessor
etRenderer
). Je vais supposer queJMeterComponent
devrait avoirCallable<JMeterRawResults>
etc. injecté.De toute façon, ce que vous devez faire est de générique liaisons à l'aide de
TypeLiteral
: