Dependency injection doesn't work in REST resource class - ICM 7.10.38.11-LTS

70 views Asked by At

I'm trying to create a REST cartridge to expose API for getting my custom business component (WarehouseBO in this case). I have based my code on this guide - Guide - Create a New Storefront REST Resource and have created cartridge app_sf_rest_warehouse and in it WarehouseResource which has several dependencies but whenever I try to make a REST call it throws and error and in the logs it says there was no object available for injection (I have tried injecting CurrentApplicationBOProvider and LocaleMgr):

Lookup and initialization failed for a resource class: class com.luminoslabs.warehouse.rest.capi.WarehouseResource. org.glassfish.hk2.api.MultiException: 
A MultiException has 1 exceptions.  They are:
 1. org.glassfish.hk2.api.UnsatisfiedDependencyException: 
 There was no object available for injection at
    SystemInjecteeImpl(requiredType=LocaleMgr,parent=WarehouseResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,424987312)

The URL I'm trying is: http://localhost:8080/INTERSHOP/rest/WFS/inSPIRED-inTRONICS_Business-Site/-/warehouses All of the following code artifacts are from app_sf_rest_warehouse:

apps.component

<components xmlns="http://www.intershop.de/component/2010">
    <fulfill requirement="selectedCartridge" of="intershop.SMBResponsive.Cartridges" value="app_sf_rest_warehouse"/>
</components>

instances.component

<components xmlns="http://www.intershop.de/component/2010"> 
    <!-- Way where you attach your new resource to existing REST API root -->
    <fulfill requirement="subResource" of="intershop.B2BWebShop.RESTAPI.root">
        <instance name="intershop.B2BWebShop.RESTAPI.WarehouseResource" with="WarehouseResource">
            <fulfill requirement="name" value="warehouses" />
        </instance>
    </fulfill>
    <fulfill requirement="resourceACLCartridge" value="app_sf_rest_warehouse" of="intershop.B2BWebShop.RESTAPI.AuthorizationService"/>
</components>

implementations.component

<components xmlns="http://www.intershop.de/component/2010">
    <implementation name="WarehouseResource" implements="AbstractRestResource" class="com.luminoslabs.warehouse.rest.capi.WarehouseResource">
        <requires name="subResource" contract="RestResource" cardinality="0..n" />
        <requires name="name" contract="String" cardinality="1..1" />
    </implementation>
</components>

WarehouseReource.java

@Tag(name = "Warehouse")
@OpenAPIDefinition( info = @Info(version = "1.0.0"))
public class WarehouseResource extends AbstractRestResource implements RestResource
{
    /*@Inject
    private CurrentApplicationBOProvider currentApplicationBOProvider;*/
    
    @Inject
    private LocaleMgr localeMgr;
    
    public WarehouseResource()
    {
        super();
        //NamingMgr.inject(this);
        //NamingMgr.injectMembers(this);
    }
    
    @Operation(
                    summary = "Returns the list of warehouses."
                 )
                 @ApiResponses({@ApiResponse(
                 responseCode = "200",
                 description = "The list of warehouses.",
                 content = {@Content(
                 schema = @Schema(
                 implementation = Collection.class
              )
              )}
              ), @ApiResponse(
                 responseCode = "401",
                 ref = "401"
              )})
    @GET
    @Produces({"application/json"})
    public Response getWarehouses()
    {
        //final WarehouseBORepository warehouseBORepository = currentApplicationBOProvider.get().getRepository(WarehouseBORepository.EXTENSION_ID);
        final Collection<WarehouseBO> warehouseBOs = null; //warehouseBORepository.getAllWarehouseBOs();
        final Collection<WarehouseRO> warehouseROs = Optional.ofNullable(warehouseBOs).map( warehouses -> warehouses.stream().map( warehouse -> new WarehouseRO(warehouse) ).collect(Collectors.toList()) ).orElse(new ArrayList<>(0));
        
        return Response.ok(warehouseROs).build();
    }
}
2

There are 2 answers

0
mihallievich On BEST ANSWER

It works if you use @com.google.inject.Inject instead of @javax.inject.Inject.

This answer is based on one given by @Johannes Metzner and his video (the important part is around 13:54)

EDIT: The whole cookbook for this video is Cookbook - REST Framework (Guice Based)

0
Johannes Metzner On

Thank you for pointing to the guide that you've been using. Wiring REST resources via component framework is tedious and therefore discouraged. Please have a look at this youtube video from a Intershop Dev Community session. In there a Injection-only approach is described. That you should use.

Following the guide that you mentioned it is not possible to use field or any other injection patterns. Normally, you could use that (even with instances produced by the component framework) but instances of AbstractRestResource are handled differently. Sorry :)