UnsatisfiedDependencyException: Il n'y a pas d'objet disponible pour l'injection au SystemInjecteeImpl

Il y a des erreurs lors de l'utilisation de DI en Maillot Reste d'application:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=PricingService,parent=PricingResource,qualifiers={},position=0,optional=false,self=false,unqualified=null,1633188703)

Je suis assez nouveau dans le concept, et il semble assez compliqué, car il y a quelques exemples qui semble être obsolète. Comme je comprends qu'il ya quelques façons de le faire (DI): natif HK2, Printemps/HK2 Pont. Ce qui est plus facile et plus simple à configurer? Comment configurer par programmation (pas un fan de XML) pour le Jersey 2.x?

ResourceConfig

import org.glassfish.jersey.server.ResourceConfig;

public class ApplicationConfig  extends ResourceConfig {
    public ApplicationConfig() {
        register(new ApplicationBinder());
        packages(true, "api");
    }
}

AbstractBinder

public class ApplicationBinder extends AbstractBinder {
    @Override
    protected void configure() {
        bind(PricingService.class).to(PricingService.class).in(Singleton.class);
    }
}

PricingResource

@Path("/prices")
public class PricingResource {
    private final PricingService pricingService;

    @Inject
    public PricingResource(PricingService pricingService) {
        this.pricingService = pricingService;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<Price> findPrices() {
        return pricingService.findPrices();
    }
}

PricingService

@Singleton
public class PricingService {
   //no constructors...
//findPrices() ...

}

Mise à JOUR

public class Main {
    public static final String BASE_URI = "http://localhost:8080/api/";

    public static HttpServer startServer() {
        return createHttpServerWith(new ResourceConfig().packages("api").register(JacksonFeature.class));
    }

    private static HttpServer createHttpServerWith(ResourceConfig rc) {
        HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
        StaticHttpHandler staticHttpHandler = new StaticHttpHandler("src/main/webapp");
        staticHttpHandler.setFileCacheEnabled(false);
        staticHttpHandler.start();
        httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler);
        return httpServer;
    }

    public static void main(String[] args) throws IOException {
        System.setProperty("java.util.logging.config.file", "src/main/resources/logging.properties");
        final HttpServer server = startServer();

        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        server.start();
        System.in.read();
        server.stop();
    }

}

UPDATE3:

public class PricingResourceTest extends JerseyTest {
    @Mock
    private PricingService pricingServiceMock;

    @Override
    protected Application configure() {
        MockitoAnnotations.initMocks(this);
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);

        ResourceConfig config = new ResourceConfig(PricingResource.class);
        config.register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(pricingServiceMock).to(PricingService.class);
            }
        });
        return config;
    }

    @Test
    public void testFindPrices(){
        when(pricingServiceMock.findPrices()).thenReturn(getMockedPrices());
        Response response  = target("/prices")
                .request()
                .get();
        verify(pricingServiceMock).findPrices();
        List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});
//       assertEquals("Should return status 200", 200, response.getStatus());
        assertTrue(prices.get(0).getId() == getMockedPrices().get(0).getId());
    }

    private List<Price> getMockedPrices(){
        List<Price> mockedPrices = Arrays.asList(new Price(1L, 12.0, 50.12, 12L));
        return mockedPrices;
    }
}

JUnit sortie:

INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 4
1 < Content-Type: application/json
[{}]


java.lang.AssertionError

En cours de débogage:

prices.get(0) est Price objet qui a null attribué à tous les domaines.


UPDATE4:

Ajouté à configure():

 config.register(JacksonFeature.class);
 config.register(JacksonJsonProvider.class);

Maintenant Junit sortie un peu mieux:

INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 149
1 < Content-Type: application/json
[{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2},{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2}]

En effet liste prices a bon nombre de prices mais tous les prix des " champs est null. Qui conduit à l'hypothèse que le problème est peut-être la lecture de l'entité:

List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});

Ici est de savoir comment fixer

Changement Moxy dépendance:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
</dependency>

et d'ajouter des annotations sur les "Prix" de l'objet.

@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
Juste en regardant cela, si j'ai mis le tout dans un seul JerseyTest pour tester, je peux vous dire qu'avec ce que vous avez fournis, il devrait fonctionner correctement. Essayez de le faire vous-même, puis essayer de cerner le problème. Je ne suis pas sûr de ce que d'autre à vous dire. La seule façon que je pouvais voir pas de travail (dans un vrai serveur env), si vous utilisez web.xml et le ResourceConfig classe n'est pas encore utilisé. Si que est dans le cas, reportez-vous à ici
Vous n'êtes pas vous même à l'aide de la ResourceConfig dans votre post. Vous créez un nom complètement différent createHttpServerWith(new ResourceConfig()..
ResourceConfig est défini dans Main et ApplicationConfig mais il semble que ces deux ne sont pas likned ensemble.....peut-être
Pourquoi seraient-ils liés? Utilisez simplement createHttpServerWith(new ApplicationConfig())
La principale chose que vous êtes absent de la maquette de l'initialisation des données. Vous ne devez le faire à l'intérieur de votre méthode d'essai. Comme vous l'avez fait dans votre question précédente, qui est aujourd'hui disparu, dans cette question,

OriginalL'auteur J.Olufsen | 2016-04-27