>>>>> Steinar Bang <[email protected]>: >> The service definition is >> https://github.com/steinarb/ukelonn/blob/5ca75f438407c594ed476bed790d984b0007cfdf/ukelonn.api/src/main/java/no/priv/bang/ukelonn/UkelonnService.java#L36
>> The service implementation, is this DS component >> https://github.com/steinarb/ukelonn/blob/5ca75f438407c594ed476bed790d984b0007cfdf/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/impl/UkelonnServiceProvider.java#L42 >> However, with Jersey getting injection of the above service into the >> resource classes isn't so easy. > Based in the following two stackoverflow threads I have a tentative plan > for getting the service injected into Jersey resources using my current > stack (ie. karaf 4.1.5 and OSGi 6.0.0): > > https://stackoverflow.com/questions/38373867/inject-dao-instance-into-jersey-resource?noredirect=1&lq=1 > > https://stackoverflow.com/questions/16216759/dependency-injection-with-jersey-2-0 [snip!] > Outline of my plan: > 1. Make the service implementation extend ResourcesConfig Turns out this wasn't necessary. What's @Inject'ed into Jersey resources by HK2 JSR330 injections, can be any class. > 2. Create a class extending AbstractBinder, that in its configure() > method will bind an instance of the service implmentation to the > UkelonnService interface I ended up just creating an anonymous inner and registering it immediately. > 3. In the @Activate method of the service implementation, register the > activated instance with Jersey, using the AbstractBinder above This was wrong. The instances that needs to be injected, must bek registered with the ResourceConfig used by the ServletContainer. They cannot be registered with any old ResourceConfig. > 4. In the resource classes use JSR330 @Inject of the UkelonnService This was as predicted. Needed to > 5. Create a whiteboard DS service from the JerseyServletContainer, with: > a. param configuration configuring a package to scan for resources > b. add a @Reference for an UkelonnService and an @Activate method, to > ensure that the servlet isn't activated, and plugged into the > whiteboard until a service is available that can be injected into > the created resources (and it should also ensure the servlet is > taken down if the UkelonnService implementation is taken down) Actually, the ServletContainer DS component needs to have the UkelonnService (and an OSGi LogService) injected as OSGi services, because it needs to register them as instances in its ResourceConfig. The trick to get everything working, was to first have the ServletContainer create a ResourceConfig object containing all of the servlet setup, then copy that ResourceConfig and register OSGi services for Jersey injection and reload the ServletContainer with the copy. The procedure to get Jersey working with OSGi services UkelonnService and LogService injected into the Jersey resource objects, is then as follows: 1. Create a whiteboard DS component exposing a Servlet service from Jersey ServletContainer, configuring the package to scan for API resources: https://github.com/steinarb/ukelonn/blob/59c6c693027e6d400ccd9e6b1777ce7f5adb4096/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/api/UkelonnRestApiServlet.java#L37 2. Make the DS component of ServletContainer depend on OSGi services UkelonnService and LogService https://github.com/steinarb/ukelonn/blob/59c6c693027e6d400ccd9e6b1777ce7f5adb4096/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/api/UkelonnRestApiServlet.java#L74 3. Override the ServletContainer.init(WebConfig) method, and: a. Call super.init(WebConfig) to make sure that a ServletConfig containing the information set up by the http whiteboard is created (contains the servletcontext, the servlet name and the package to scan for Jersey resources) https://github.com/steinarb/ukelonn/blob/59c6c693027e6d400ccd9e6b1777ce7f5adb4096/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/api/UkelonnRestApiServlet.java#L57 b. Copy the ResourceConfig of the ServletContainer (because that ServletConfig is immutable after the setup, and calling ServletConfig.register() will cause an IllegalOperationException) c. On the ServletConfig copy, register an anonymous inner inheriting AbstractBinder that in its configure() method registers the OSGi services injected into the ServletContainer as JSR330 injections in the Jersey resources d. Call ServletContainer.reload(ResourceConfig) with the ResourceConfig copy as the argument 4. In the resources use JSR330 injections of UkelonnService and/or LogService, e.g. https://github.com/steinarb/ukelonn/blob/59c6c693027e6d400ccd9e6b1777ce7f5adb4096/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/api/resources/RegisterJob.java#L32
