UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl
<p>There are errors when using DI in Jersey Rest application:</p>

<pre><code>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)
</code></pre>

<p>I am quite new to the concept and it appears quite complicated since there are some examples seems to be deprecated. As I understand there are a few ways to make DI work: native HK2, Spring/HK2 Bridge. What is easier and more straightforward to configure? How to set up programmatically (not a fan of XML) for Jersey 2.x?</p>

<p><strong>ResourceConfig</strong> </p>

<pre><code>import org.glassfish.jersey.server.ResourceConfig;

public class ApplicationConfig  extends ResourceConfig {
    public ApplicationConfig() {
        register(new ApplicationBinder());
        packages(true, "api");
    }
}
</code></pre>

<p><strong>AbstractBinder</strong></p>

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

<p><strong>PricingResource</strong> </p>

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

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

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Collection&lt;Price&gt; findPrices() {
        return pricingService.findPrices();
    }
}
</code></pre>

<p><strong>PricingService</strong> </p>

<pre><code>@Singleton
public class PricingService {
   // no constructors...
// findPrices() ...

}
</code></pre>

<hr>

<p><strong>UPDATE</strong></p>

<pre><code>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();
    }

}
</code></pre>

<p><strong>UPDATE3:</strong></p>

<pre><code>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&lt;Price&gt; prices = response.readEntity(new GenericType&lt;List&lt;Price&gt;&gt;(){});
//        assertEquals("Should return status 200", 200, response.getStatus());
        assertTrue(prices.get(0).getId() == getMockedPrices().get(0).getId());
    }

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

<p><strong>JUnit output:</strong></p>

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


java.lang.AssertionError
</code></pre>

<p><strong>While debugging:</strong></p>

<p><code>prices.get(0)</code> is <code>Price</code> object that has <code>null</code> assigned to all fields.</p>

<hr>

<p><strong>UPDATE4:</strong></p>

<p>Added to <code>configure()</code>:</p>

<pre><code> config.register(JacksonFeature.class);
 config.register(JacksonJsonProvider.class);
</code></pre>

<p>Now Junit output a bit better:</p>

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

<p>Indeed list <code>prices</code> has correct number of <code>prices</code> but all prices' fields is <strong>null</strong>. That leads to assumption that problem might be reading entity:</p>

<pre><code>List&lt;Price&gt; prices = response.readEntity(new GenericType&lt;List&lt;Price&gt;&gt;(){});
</code></pre>

<h2>Here is how to fix it</h2>

<p>Change Moxy dependency to:</p>

<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.media&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-media-json-jackson&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre>

<p>and add annotations on 'Price' object.</p>

<pre><code>@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
</code></pre>