2016-06-07 2 views
3

Faisant suite à this SO thread, ma question est de savoir si je fais quelque chose de fondamentalement mauvais ici:injection constructeur Jersey avec @Context ne fonctionne pas

aide GlassFish 4.1, je suis en train d'écrire un MessageBodyReader qui a un constructeur comme ceci:

package com.acme; 

import javax.ws.rs.core.Context; 
import javax.ws.rs.ext.Provider; 
import javax.ws.rs.ext.Providers; 
import javax.ws.rs.Consumes; 

@Provider 
@Consumes("application/xml") 
public class MyMessageBodyReader implements MessageBodyReader<Object> { 
    public MyMessageBodyReader(@Context Providers ps) { 
     // try to do something with ps here 
     // e.g. pass to a superclass constructor, 
     // as required by the solution in the other thread 
    } 

    [...] // implemented interface methods 
} 

Mais tout ce que je fais configuration WRT autour, je reçois toujours une séquence de ces exceptions:

2016-06-07T17:19:28.484+0200|WARN: The following warnings have been detected: WARNING: Unknown HK2 failure detected: 
MultiException stack 1 of 1 
org.jboss.weld.exceptions.CreationException: WELD-001530: Cannot produce an instance of class com.acme.MyMessageBodyReader. 
    at org.jboss.weld.injection.producer.NonProducibleInjectionTarget.produce(NonProducibleInjectionTarget.java:55) 
    at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory$2.getInstance(CdiComponentProvider.java:242) 
    at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory.provide(CdiComponentProvider.java:189) 
    [...] 

suivi par

WARNING: Unknown HK2 failure detected: 
MultiException stack 1 of 2 
org.jboss.weld.exceptions.CreationException: WELD-001530: Cannot produce an instance of class com.acme.MyMessageBodyReader. 
    at org.jboss.weld.injection.producer.NonProducibleInjectionTarget.produce(NonProducibleInjectionTarget.java:55) 
    at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory$2.getInstance(CdiComponentProvider.java:242) 
    at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory.provide(CdiComponentProvider.java:189) 
    [...] 
MultiException stack 2 of 2 
java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.message.internal.MessageBodyFactory 
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:389) 
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461) 
    at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:114) 
    [...] 

J'ai trouvé plusieurs exemples d'injection Providers dans un constructeur, pas le moins dans les sous-classes de XmlRootElementJaxbProvider ce navire avec GlassFish 4.1 - après tout, je veux réutiliser leur hiérarchie de classe de toute façon, comme c'est fait dans le fil lié.

Merci d'avance pour tout conseil.

+0

Est-ce en utilisant toujours le MessageBodyFactory modifié que vous avez décrit dans votre autre thread? Si vous avez piraté des classes de base à Jersey et que vous les avez reconstruites, et que vous obtenez des erreurs qui indiquent que la classe ne peut pas être provisionnée, ces deux choses sont probablement liées. Plus votre code a maintenant la portabilité nulle ... – BadZen

+0

Remarque, je ne suis pas l'auteur dans l'autre thread. Je n'ai pas encore modifié le MessageBodyFactory comme l'OP l'a fait comme je voulais le voir d'abord si je pouvais faire fonctionner un MessageBodyReader/Writer personnalisé. –

Répondre

2

Je ne peux pas expliquer la cause première de l'exception, mais j'ai rencontré le même problème et à l'époque je n'avais pas envie de plonger plus dans la source Jersey que je l'avais déjà.

J'ai fini par charger paresseusement mon MessageBodyReader/Writers personnalisé afin que je puisse injecter Providers dans le wrapper. Ce n'est pas joli mais ça marche.

Quelque chose le long des lignes de:

@Provider 
@Consumes("application/xml") 
public class MyLazyMessageBodyReader implements MessageBodyReader<Object> { 
    @Context 
    private Providers ps; 

    private MessageBodyReader<Object> reader; 

    @Override 
    public final Object readFrom(
      Class<Object> type, 
      Type type1, 
      Annotation[] antns, 
      MediaType mt, 
      MultivaluedMap<String, String> mm, 
      InputStream in) 
      throws IOException, WebApplicationException 
    { 
    return this.getLazyReader().readFrom(type, type1, antns, mt, mm, in); 
    } 

    private MessageBodyReader<Object> getLazyReader() { 
    if (this.reader == null) { 
     this.reader = new MyMessageBodyReader(this.ps); 
    } 
    return this.reader; 
    } 
} 

public class MyMessageBodyReader implements MessageBodyReader<Object> { 
    public MyMessageBodyReader(Providers ps) { 
     // try to do something with ps here 
     // e.g. pass to a superclass constructor, 
     // as required by the solution in the other thread 
    } 

    [...] // implemented interface methods 
}