Pour la vie de moi, je ne peux pas obtenir de Jersey avec HK2 pour découvrir automatiquement les classes annotées de @service et les injecter. J'ai essayé de suivre tous les conseils sur la documentation de la pile, le maillot et le HK2 et toujours pas de chance. J'essaie d'injecter un service d'écho simple dans une ressource en jersey. Le squelette est généré à partir du simple archétype WebApp Maven pour Jersey, que j'ai essayé de s'étendre. C'est ce que j'ai jusqu'à présent:
pom.xml p> web.xml p> my.backage .jerseytest.application.Application.Application P> SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/sandbox] threw exception [A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=EchoService,parent=MyResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,932014249)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of my.package.jerseytest.resource.MyResource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on my.package.jerseytest.resource.MyResource
] with root cause
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=EchoService,parent=MyResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,932014249)
5 Réponses :
Essayez d'ajouter les packages qui ont besoin numérisé dans votre constructeur d'applications. Le paramètre "vrai" sur les packages signifie numériser le package récursivement:
public class Application extends ResourceConfig { public Application() { packages(true, "my.package.jerseytest"); ServiceLocator locator = ServiceLocatorUtilities.createAndPopulateServiceLocator(); } }
Essayé, désolé, j'ai toujours la même exception. Vous vous demandez simplement: si les noms des classes à injecter sont collectés dans un fichier par le générateur d'habitant, alors pourquoi dois-je numériser des packages?
Utiliser les paquets (true, "my.package.jerseyest"); code>
Et utilisez
org.glassfish.jersey.spi.contract code> pas
org.jvnet.hk2.notations.contract code> annotation.
Et utilisez des interfaces simples sans génériques. P>
Essayé avec et sans une interface annotée @Contract correspondante au service, n'a pas aidé. Si j'ai bien compris la documentation correctement, il n'est pas nécessaire d'avoir une interface pour le service (bien que je l'obtiens à partir d'un point de vue du code propre, il est agréable d'avoir)
Essayez d'ajouter @Statoire code>
Bonjour, merci pour la réponse ... nous avons emménagé avec le projet et ont finalement abandonné le HK2; Au lieu de cela, nous comptons sur le pont de printemps et le printemps pour DI.
Comment la décision d'utiliser le pont de printemps et le printemps di? Sans regret?
L'un des avantages de l'utilisation du ressort est d'être indépendant du conteneur. Vous ne verrez pas de différence dans l'utilisation de Glassfish, Wildfly ou Tomcat par exemple.
Je combine la perspicacité que j'ai gagnée de ces deux questions:
Tout d'abord, utilisez le Générateur de métadonnées HK2 (ou le générateur d'habitant) de votre chaîne de construction (comme vous le faites déjà). Cela scannera votre source et créera Deuxièmement, créez un nouveau maintenant Jersey a son propre serveurélocator et il n'est pas facile d'essayer d'obtenir une référence à celle-ci. Nous pourrions donner à Jersey à notre serveurélocator, mais Jersey crée toujours toujours son propre localisateur et le peuplera avec notre localisateur. P>
blockQuote> méta-inf / hk2-locator / par défaut code>. P>
Servicelocator code>, peuplé avec les services de Les métadonnées: p>
grizzly code>. Citant @peeskillet : p>
J'ai résolu mon problème comme celui-ci à l'aide d'une classe qui prolonge Abstractbinder, l'instanciant et l'enregistrant avec l'application.
/** * dependency injection bindings. * Jersey requires that service implementations are bound to their contracts this way. */ public final class DependencyBinder extends AbstractBinder { @Override protected final void configure() { bind(StatusServiceImpl.class).to(StatusService.class); } }
Mise en garde! Toute personne utilisant cette solution ne doit pas essayer de le rendre générique. Nous avons essayé de le faire et avons ajouté 2 paramètres de constructeur à ce type de liant. Le résultat était terrible. Jersey n'a enregistré que la première instance basée sur le type de classe. Donc, la première dépendance serait injectée, mais tout ce qui est rejeté, car il est déjà ajouté selon Jersey.
Nope, abandonné. Il y avait quelque chose à propos de deux versions différentes de l'annotation @Inject, mais le projet git a passé cela et nous avons décidé d'utiliser le pont de printemps de Jersey et le conteneur Spring DI.
Juste curieux, pourquoi pas simplement CDI?
Honnêtement, je ne pense pas que quiconque y pensait. Étant donné que d'autres parties du projet utilisent le printemps, c'était soit cela, soit quelque chose qui sortit de la boîte avec Jersey.
voir Stackoverflow.com/Questtions/39003933/...