intershop

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


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

Solution

  • 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)