The solution I found (if not the best), is to define a CustomServletContext and use the guice-bridge artifact, following references issue HK2-121 in jersey issue tracker. The solution:
public class KratosServletContainer extends ServletContainer {
private Injector injector;
@Inject
KratosServletContainer(Injector injector, ResourceConfig configuration) {
super(configuration);
this.injector = injector;
}
@Override
protected void init(WebConfig webConfig) throws ServletException {
super.init(webConfig);
ServiceLocator locator;
try {
Field webComponentField = getClass().getSuperclass()
.getDeclaredField("webComponent");
webComponentField.setAccessible(true);
WebComponent webComponent = (WebComponent) webComponentField.get(this);
Field appHandlerField = webComponent.getClass().getDeclaredField("appHandler");
appHandlerField.setAccessible(true);
ApplicationHandler appHandler = (ApplicationHandler) appHandlerField.get(webComponent);
locator = appHandler.getServiceLocator();
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | llegalAccessException e) {
throw new RuntimeException(e);
}
GuiceBridge.getGuiceBridge().initializeGuiceBridge(
locator);
GuiceIntoHK2Bridge guiceBridge = locator
.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
}
}
By example: My resources look like this:
@Path("resource")
public class ResourceFinder {
private static final Logger logger = Logger.getLogger(ResourceFinder.class.getName());
private Date date;
private final PersistenceManagerService pm;
@Inject
public ResourceFinder(Date date, PersistenceManagerService pm) {
this.date = date;
this.pm = pm;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/suma/{value1}/{value2}")
@PermitAll
public String getSuma(@PathParam("value1") int value1,
@PathParam("value2") int value2) {
User user = new User();
user.setName("cacho" + value1);
pm.get().makePersistent(user);
pm.get().flush();
//date was injected by guice
//pm was injected by guice
return String.valueOf(value1 + value2 + " "+pm.get()+" "+date);
}
}
The method:
@Override
public ResourceModel processResourceModel(ResourceModel resourceModel, Configuration configuration) {
logger.info(actualKrundle.getName());
ResourceModel.Builder newResourceModelBuilder = new ResourceModel.Builder(false);
for (final Provider<?> r : actualKrundle.getResources()) {
String name = r.get().getClass().getCanonicalName();
List<Resource> resources = resourceModel.getResources();
for (final Resource resource : resources) {
if (resource.getName().endsWith(name)){
final Resource.Builder resourceBuilder = Resource.builder(resource);
resourceBuilder.path(actualKrundle.getName()+"/"+resource.getPath());
Resource r1 = resourceBuilder.build();
newResourceModelBuilder.addResource(r1);
break;
}
}
}
return newResourceModelBuilder.build();
}
Make changes in the path of the resource, recreates the instance and everything stays injected...