GithubHelp home page GithubHelp logo

jersey2-guice's Introduction

Jersey 2.0 w/ Guice

Continuous Integration

Introduction

This library provides support for Jersey 2.0 w/ Guice similar to the way it used to work in Jersey 1.x with the jersey-guice library. It uses Guice's own GuiceFilter (like jersey-guice) and it's somewhat different from the Guice/HK2 Bridge.

Installation

Go to search.maven.org and search for g:"com.squarespace.jersey2-guice" AND a:"jersey2-guice-impl" to find the current release version.

Gradle

compile "com.squarespace.jersey2-guice:jersey2-guice-impl:${current.version}"

Maven

<dependency>
  <groupId>com.squarespace.jersey2-guice</groupId>
  <artifactId>jersey2-guice-impl</artifactId>
  <version>${current.version}</version>
</dependency>

Usage

Getting Started

Jersey/HK2 uses unfortunately SPIs and the Singleton pattern internally. Your code is effectively racing against the Servlet container's code and the first one to initialize HK2's ServiceLocatorGenerator inside its ServiceLocatorFactory wins.

This library uses two approaches to override HK2's own ServiceLocatorGenerator. It first tries to use a SPI and if it can't it'll fall back to reflection to replace a private static field. Regardless of the approach it's still a race against the Servlet container.

public static void main(String[] args) {

  List<Module> modules = new ArrayList<>();
  
  modules.add(new JerseyGuiceModule("__HK2_Generated_0"));
  modules.add(new ServletModule());
  modules.add(new AbstractModule() {
    @Override
    protected void configure() {
      // ...
    }
  });
  
  Injector injector = Guice.createInjector(modules);
  JerseyGuiceUtils.install(injector);
  
  // ... continue ...
}

Documentation

The User's Guide can be found in the Wiki.

Apache 2.0 License

Copyright 2014-2016 Squarespace, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

jersey2-guice's People

Contributors

abrandimarti avatar fkirill avatar jontejj avatar mrserverless avatar oillio avatar rkapsi avatar squinn avatar twz123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jersey2-guice's Issues

Guice type conversions for constant bindings don't work for primitive types

According to the Binder documentation:

When a constant binding's value is a string, it is eligile for conversion to all primitive types, to all enums, and to class literals. Conversions for other types can be configured using convertToTypes().

However, this seems to not work in jersey2-guice. Below is code to reproduce this:

package com.foo.service;

import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.name.Names;

public class FooModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(Key.get(String.class, Names.named("named.bar"))).toInstance("3");
  }
}

Given that the bound instance is a string, it should be possible to automatically have it converted to an int:

package com.foo.service.resources;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class FooResource {

  private final int bar;

  @Inject
  public FooResource(@Named("named.bar") int bar) {
    this.bar = bar;
  }

  @GET
  public int getBar() {
    return bar;
  }
}

Unfortunately this results in the following exception being thrown:

Jan 13, 2016 9:25:28 PM org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=int,parent=FooResource,qualifiers={},position=0,optional=false,self=false,unqualified=null,447210731)
    at com.squarespace.jersey2.guice.GuiceThreeThirtyResolver.resolve(GuiceThreeThirtyResolver.java:61)
    at com.squarespace.jersey2.guice.GuiceInjectionResolver.resolve(GuiceInjectionResolver.java:51)
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:214)
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:231)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:297)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:288)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1110)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:401)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
    at java.lang.Thread.run(Thread.java:745)
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.foo.service.resources.FooResource errors were found
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:249)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:297)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:288)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1110)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:401)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
    at java.lang.Thread.run(Thread.java:745)
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.foo.service.resources.FooResource
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:389)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
    at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
    at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
    at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:297)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:288)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1110)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:401)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
    at java.lang.Thread.run(Thread.java:745)

Does not work with embedded jetty

I works fine when I deploy to a jetty server, but when I try embedded jetty the jetty server does not start:

    Server server = new Server(9000);

    ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/");
    servletContextHandler.addServlet(DefaultServlet.class, "/");

    server.start();
    server.join();

Here is the output:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Usually when you start embedded jetty it shows the following:

2016-09-20 10:40:53.794:INFO::main: Logging initialized @113ms
2016-09-20 10:40:53.849:INFO:oejs.Server:main: jetty-9.3.11.v20160721
2016-09-20 10:40:53.941:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@7bfcd12c{/,null,AVAILABLE}
2016-09-20 10:40:53.952:INFO:oejs.AbstractConnector:main: Started ServerConnector@2be94b0f{HTTP/1.1,[http/1.1]}{0.0.0.0:9000}
2016-09-20 10:40:53.953:INFO:oejs.Server:main: Started @274ms

I don't have to reference anything. As soon as I add the dependency to my project it happens.

OSGi manifest

Hi there,

please correct me if I am wrong, but the current JAR comes with a non-OSGi manifest; hence one cannot add this third-party dependency from Maven to the Eclipse-based target platform.

If I add support for the OSGi manifest, would you take care of redeploying a new version to Maven? That would be awesome.

I look forward to your feedback!

Guice binding annotations not working

Copied from a Guice issue I previously filed (and closed): google/guice#966 (comment)

I have two modules that bind a set of strings like:

In FooModule:

Multibinder<String> fooThingsBinder = Multibinder.newSetBinder(binder(), String.class, Foo.class);
...
for(String foo: fooThings) {
  fooThingsBinder.addBinding().toInstance(foo);
}

And something similar in BarModule. Then elsewhere in the code I get these sets injected like:

public class FooResource(@Foo Set<String> fooThings, ...) { ... }

and something similar in BarResource.

What I'm seeing is that one of these sets non-deterministically gets injected to both resource classes. E.g., the foo things end up in FooResource and BarResource, or vice-versa.

I have tried using the @Named binding annotation as well, with the same results. I have another multi-binding that uses different types instead binding annotations, and it is working fine.

I'll try to come up with a test case later today/this week as time allows. I've worked around this for now by creating separate sub-types for the foo/bar things.

How to get custom @Context injections?

Migrating a Jersey 1.x app, we have some classes that are injected via @Context. Previously, this was done like:

@javax.ws.rs.ext.Provider
public class MyCustomThingProvider extends AbstractHttpContextInjectable<MyCustomThing>
    implements InjectableProvider<Context, Type> {
  ...
}

Based on the Jersey 2.x manual, the way to do this is with an HK2 Factory, like:

public class MyCustomThingFactory implements Factory<MyCustomThing> {

  private final UriInfo uriInfo;

  @Inject
  protected MyCustomThingFactory(UriInfo uriInfo) {
    this.uriInfo = uriInfo;
  }

  ...
}

Before, I could pull out the things I needed from the request when implementing AbstractHttpContextInjectable#getValue(HttpContext). Now, it looks like the preferred method is to inject things to the factory itself (things like HttpServletRequest, UriInfo, etc).

This is all fine, and I actually have it working, but my question is: how can I avoid having to do some HK2 binding in my application setup? The only way I could get this working is to add an HK2 binder:

jerseyConfig.register(new AbstractBinder() {
      @Override
      protected void configure() {
        bindFactory(MyCustomThingFactory.class).to(MyCustomThing.class);
      }
    });

Any ideas?

Jersey 2.26 compatibility

Are there plans to update this project to be compatible with the breaking changes in Jersey 2.26's HK2 usage? They now have a sort-of abstraction layer on top of HK2, so jersey2-guice doesn't compile (or run) when 2.26 is on the classpath.

Allow creating your own injector

I want to be able to create my own injector, not hand creating the injector off to jersey2-guice. I got it working by marking a few things public (https://github.com/marshallpierce/jersey2-guice/compare/external-injector) and duplicating a couple of lines of logic from BootstrapUtils#newInjector.

I'm guessing that you don't really want to just mark stuff public and that you'd like to expose a better way of doing this, so I didn't file my changes as PR. If you have any suggestions for how you'd like to structure things to allow making your own injector instead of having jersey2-guice do it, I'd be happy to do the work to make it happen. (Or just submit my code as a PR if you're cool with making things public.) Thanks!

Error injecting constructor, java.lang.IllegalStateException

While deploying an application that includes wars and ejb, glassfish server show following messages:

GRAVE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: com.google.inject.CreationException: Unable to create injector, see the following errors:

  1. Error injecting constructor, java.lang.IllegalStateException: name=com.pa.APIShiroWebModule
    at com.pa.HK2Linker.(HK2Linker.java:23)
    at com.pa.APIJerseyModule.configureServlets(APIJerseyModule.java:49)
    while locating com.pa.HK2Linker

Source code:

...
final ServiceLocator locator = BootstrapUtils.newServiceLocator();
install(new BootstrapModule(locator));
bind(HK2Linker.class).asEagerSingleton();
...

public class HK2Linker {
@Inject
public HK2Linker(Injector injector, ServiceLocator locator) {
BootstrapUtils.link(locator, injector);
BootstrapUtils.install(locator);
}
}
APIShiroWebModule is a simple module herited from ShiroWebModule.
What's goiing wrong?

It appears jersey2-guice-spi is either not present or in conflict with some other Jar

I'm trying to use this package with Dropwizard and Guice, using the "complex example" code in the wiki of this repo. I'm currently getting this error when I start my application

.... It appears jersey2-guice-spi is either not present or in conflict with some other Jar: ServiceLocatorGeneratorImpl(hk2-locator, 1911168986)

It looks like this is related to this (#37)... I did some monkeypatching with JerseyGuiceUtils.java and printed out the names of the providers within lookupSPI:

for (ServiceLocatorGenerator generator : providers) {
  System.out.println(generator.getClass().getName());
}

And I get:

org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl
com.squarespace.jersey2.guice.GuiceServiceLocatorGeneratorStub
org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl

Currently the code just takes the first one... however it looks like the second one is the right class. Would it be better to just loop over the providers and check all of them?

GuiceJustInTimeResolver#findBinding causes & logs exception on every request

Code: https://bitbucket.org/marshallpierce/guice-jaxrs-examples @ 00e29b2. See the jersey2 module.

./gradlew :jersey2:run and hit http://localhost:8080/resource. With each request, the stuff below [1] is logged. This isn't great because (1) it pollutes the logs and (2) I don't really want to be throwing an exception each request as there are performance consequences to that (http://shipilev.net/blog/2014/exceptional-performance/). Am I not setting something up correctly?

On a related note, at startup, the stuff at [2] is logged. If I don't require explicit bindings, it still complains that it's not bound, just with a different message that doesn't mention explicit bindings. Is this perhaps related to me not wiring things correctly? If this is an unrelated problem I'm happy to file a separate issue.

[1]

org.glassfish.jersey.server.internal.inject.ConfiguredValidator, annotation=[none]]
com.google.inject.ConfigurationException: Guice configuration errors:

1) Explicit bindings are required and org.glassfish.jersey.server.internal.inject.ConfiguredValidator is not explicitly bound.
  while locating org.glassfish.jersey.server.internal.inject.ConfiguredValidator

1 error
        at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:158) ~[guice-4.0-beta4.jar:na]
        at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:66) ~[guice-4.0-beta4.jar:na]
        at com.squarespace.jersey2.guice.GuiceJustInTimeResolver.findBinding(GuiceJustInTimeResolver.java:94) [jersey2-guice-0.1.jar:na]
        at com.squarespace.jersey2.guice.GuiceJustInTimeResolver.justInTimeResolution(GuiceJustInTimeResolver.java:66) [jersey2-guice-0.1.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.secondChanceResolve(ServiceLocatorImpl.java:466) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetInjecteeDescriptor(ServiceLocatorImpl.java:534) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getInjecteeDescriptor(ServiceLocatorImpl.java:546) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.IterableProviderImpl.justInTime(IterableProviderImpl.java:94) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.IterableProviderImpl.get(IterableProviderImpl.java:103) [hk2-locator-2.3.0-b10.jar:na]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:135) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispvaResourceMethodDispatcherProvider.java:195) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:271) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373) [jersey-container-servlet-core-2.12.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381) [jersey-container-servlet-core-2.12.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344) [jersey-container-servlet-core-2.12.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221) [jersey-container-servlet-core-2.12.jar:na]
        aoogle.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:278) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:268) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:180) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:93) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:120) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:134) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:131) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.GuiceFilter$Context.call(GuiceFilter.java:208) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:131) [guice-servlet-4.0-beta4.jar:na]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1615) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1112) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:479) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1046) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollecti:109) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.Server.handle(Server.java:462) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:281) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505) [jetty-io-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_11]

[2]

2014-08-30 14:46:40,966 [main] ERROR MDC[] c.s.j.guice.GuiceJustInTimeResolver - Exception: injectee=SystemInjecteeImpl(requiredType=RuntimeThreadProvider,parent=RuntimeExecutorsBinder$BackgroundSchedulerFactory,qualifiers={},position=0,optional=true,self=false,unqualified=null,663466110), key=Key[type=org.glassfish.jersey.spi.RuntimeThreadProvider, annotation=[none]]
com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for org.glassfish.jersey.spi.RuntimeThreadProvider was bound.
  while locating org.glassfish.jersey.spi.RuntimeThreadProvider

1 error
        at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:158) ~[guice-4.0-beta4.jar:na]
        at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:66) ~[guice-4.0-beta4.jar:na]
        at com.squarespace.jersey2.guice.GuiceJustInTimeResolver.findBinding(GuiceJustInTimeResolver.java:94) [jersey2-guice-0.1.jar:na]
        at com.squarespace.jersey2.guice.GuiceJustInTimeResolver.justInTimeResolution(GuiceJustInTimeResolver.java:66) [jersey2-guice-0.1.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.secondChanceResolve(ServiceLocatorImpl.java:466) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetInjecteeDescriptor(ServiceLocatorImpl.java:534) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getInjecteeDescriptor(ServiceLocatorImpl.java:546) [hk2-locator-2.3.0-b10.jar:na]
        at com.squarespace.jersey2.guice.GuiceThreeThirtyResolver.resolve(GuiceThreeThirtyResolver.java:52) [jersey2-guice-0.1.jar:na]
        at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:214) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:231) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.inPerLookupContext.findOrCreate(PerLookupContext.java:69) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2268) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:105) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:87) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:94) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:114) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:102) [hk2-locator-2.3.0-b10.jar:na]
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97) [hk2-utils-2.3.0-b10.jar:na]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_11]
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154) [hk2-utils-2.3.0-b10.jar:na]
        at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199) [hk2-utils-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:153) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2268) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:638) [hk2-locator-2.3.0-b10.jar:na]
        at com.squarespace.jersey2.guice.GuiceThreeThirtyResolver.resolve(GuiceThreeThirtyResolver.java:64) [jersey2-guice-0.1.jar:na]
        at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:947) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:902) [hk2-locator-2.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:977) [hk2-lo.3.0-b10.jar:na]
        at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:968) [hk2-locator-2.3.0-b10.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:514) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286) [jersey-common-2.12.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:320) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:285) [jersey-server-2.12.jar:na]
        at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311) [jersey-container-servlet-core-2.12.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170) [jersey-container-servlet-core-2.12.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:358) [jersey-container-servlet-core-2.12.jar:na]
        at javax.servlet.GenericServlet.init(GenericServlet.java:244) [javax.servlet-api-3.1.0.jar:3.1.0]
        at com.google.inject.servlet.ServletDefinition.init(ServletDefinition.java:119) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ManagedServletPipeline.init(ManagedServletPipeline.java:84) [guice-servlet-4.0-beta4.jar:na]
        at com.google.inject.servlet.ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:104) [guice-servlet-4.0-beta4.jar:na]
    com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:226) [guice-servlet-4.0-beta4.jar:na]
        at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:137) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:810) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:300) [jetty-servlet-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:745) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.Server.start(Server.java:358) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.server.Server.doStart(Server.java:325) [jetty-server-9.1.3.v20140225.jar:9.1.3.v20140225]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbsfeCycle.java:68) [jetty-util-9.1.3.v20140225.jar:9.1.3.v20140225]
        at com.palominolabs.http.server.HttpServerWrapper.start(HttpServerWrapper.java:122) [jetty-http-server-wrapper-1.0.5.jar:na]
        at org.mpierce.guice.jaxrs.jersey2.Jersey2Main.main(Jersey2Main.java:42) [main/:na]

Calling modules() in JerseyGuiceServletContextListener constructor is too early

I just noticed that the constructor for JerseyGuiceServletContextListener itself calls modules(). This presents a problem because it is impossible to pass information through to the module constructors. For example, I have a Guice module that keeps track of the command line program arguments. The arguments themselves need to be passed into the module (this is simplified):

@RequiredArgsConstructor
public class ArgsModule extends AbstractModule {
    private final String[] args;

    @Override
    protected void configure() {
        bind(Args.class).toInstance(new Args(args));
    }
}

The idea is that I would pass in the args to MyJerseyGuiceServletContextListener, and MyJerseyGuiceServletContextListener would create the ArgsModule. However, because JerseyGuiceServletContextListener calls modules() right away, the args field in MyJerseyGuiceServletContextListener hasn't been initialized yet.

Is it possible to create the Injector slightly later, perhaps in contextInitialized()?

AOP requires registration in two places

This may be "working as advertised", but it seems a bit weird.

Resource classes need to be registered with Jersey (through the ResourceConfig, either individually or via packages()). If they are registered with Guice only, they don't show up as endpoints (ie, they are 404). However, they don't need to be registered/bound separately with Guice to receive Guice injection.

However, in order to receive AOP, resource classes must also be registered/bound with Guice.

Is there a way to make registration necessary only in one place, either with Guice or with Jersey? It's almost there, it just doesn't seem to work with AOP. FWIW I don't care if it's Guice-side or Jersey-side that requires registration/binding.

jersey2-guice, Jersey 2.16 and uber-jar

Hi. I've stumbled upon some interesting behaviour. I'm not sure whether it's a bug or not, but I've decided to share it anyway.

The situation is, if you build any application with jersey2-guice + Jersey >= 2.16 and pack it into uber-jar, then most probably it'll crash on start with a huge stack trace like:

WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for javax.xml.parsers.DocumentBuilderFactory was bound.
  while locating javax.xml.parsers.DocumentBuilderFactory

1 error
    at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:159)
    at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:67)
    at com.squarespace.jersey2.guice.GuiceJustInTimeResolver.findBinding(GuiceJustInTimeResolver.java:90)
...

The key here is an uber-jar and the fact that starting from version 2.16 Jersey has moved JAX-B providers into separate module (release notes). At some points Jersey relyes on information in META-INF/services and after JAX-B providers separations they've created a conflict there (because two jars have implementations for the same interface). So the solution is to add

<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>

into maven-shade-plugin configuration. But first of all, this is very-very unobvious (at least it was for me, and it took me hell of a time to figure all this out). Second of all, if I remove jersey2-guice initialization, then HK2 is able to go around this and somehow finds the right implementation. That's why I've decided to bring that up.

While I was digging all this stuff, I've made some very simple example to reproduce this situation: https://github.com/smaant/jersey-guice-issue

Getting a ServletContext

I have some modules that needs a ServletContext. The problem is that JerseyGuiceServletContextListener#modules() is being called before JerseyGuiceServletContextListener#contextInitialized(). Is there any way to pass a ServletContext to a module.

I'm using apache shiro security framework with guice support. The ShiroWebModule needs a ServletContext
http://shiro.apache.org/static/1.2.1/apidocs/org/apache/shiro/guice/web/ShiroWebModule.html#ShiroWebModule(javax.servlet.ServletContext)

java.lang.IllegalStateException: java.lang.NoSuchFieldException: defaultGenerator

Looks like InjectionsUtils is expecting a field defaultGenerator which is no more supported

I get following exception when my container startup and tries to instantiate my listener which extends JerseyGuiceServletContextListener

Could not instantiate listener com.XXXX.jersey2.bootstrap.JerseyContextListener
java.lang.IllegalStateException: java.lang.NoSuchFieldException: defaultGenerator
    at com.squarespace.jersey2.guice.InjectionsUtils.install(InjectionsUtils.java:77)
    at com.squarespace.jersey2.guice.BootstrapUtils.install(BootstrapUtils.java:128)
    at com.squarespace.jersey2.guice.BootstrapUtils.install(BootstrapUtils.java:117)
    at com.squarespace.jersey2.guice.JerseyGuiceServletContextListener.<init>(JerseyGuiceServletContextListener.java:54)
    at com.XXXX.jersey2.bootstrap.JerseyContextListener.<init>(JerseyContextListener.java:26)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at java.lang.Class.newInstance(Class.java:438)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.newListenerInstance(WebXmlConfiguration.java:650)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initListener(WebXmlConfiguration.java:631)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initWebXmlElement(WebXmlConfiguration.java:368)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initWebXmlElement(AbstractConfiguration.java:190)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initialize(WebXmlConfiguration.java:289)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initialize(AbstractConfiguration.java:133)

I am using following build.gradle

  compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.+'
  compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.+'
  compile group: 'com.squarespace.jersey2-guice', name: 'jersey2-guice', version: '0.+'
  provided group: 'javax.servlet', name: 'servlet-api', version: '2.5'
  provided group: 'javax.servlet', name: 'jsp-api', version: '2.0'

Custom scopes are not mapped to hk2 scopes

Custom scope mappings, annotated with @scope and @com.google.inject.ScopeAnnotation, and added to guice with:
binder().bindScope(com.example.RequestScoped.class, ServletScopes.REQUEST);

leads to:
"Could not find an active context for com.example.RequestScoped"

Could Injector#getScopeBindings() be used to retrieve all the scopes from guice and add them to hk2?

Async support?

I have not tested it but does this work with Async Servlets?

Resource injection problem

Injecting multiple implementation of the same interface into a resource class might not work as expected.

I am sending a pull request with a simple failing test.

base path

I have my listener

public class GuiceListener extends JerseyGuiceServletContextListener {
    @Override
    protected List<? extends Module> modules() {
        return newArrayList(new DashboardModule());
    }
}

my module

public class DashboardModule extends ServletModule {
    @Override
    protected void configureServlets() {
        bind(HelloResource.class);
    }
}

my resuorce

@Path("/hello")
public class HelloResource {
    @GET
    @Produces("text/plain")
    public String getMessage() {
        return "hello world";
    }
}

and my web.xml

<filter>
        <filter-name>GuiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>GuiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>pt.ipb.sa.dashboard.guice.GuiceListener</listener-class>
    </listener>

what do I tell jersey that should use /rest/* as my base path

with the old jersey-guice and would have done the following

serve("/rest/*").with(GuiceContainer.class, params);

what should I do with jersey2-guice?

Guice scope annotations are ignored

I have a Resource class annotated with com.google.inject.Singleton, with its constructor annotated with com.google.inject.Inject. This ends up having RequestScope in Jersey and is instantiated on every request.

I don't understand the innards of the bridging mechanism, but given that it requires Guice's Inject annotation to work, shouldn't it also respect Guice's scope annotations?

@Qualifier / @BindingAnnotation annotated dependencies are not being injected into hk2 created services

Usually you can use @nAmed to qualify dependencies:

  @Inject
  ColorfulResource(@Named("red") String color)
  {
    this.color = color;
  }

But JSR-330 also has support for @qualifier (http://atinject.googlecode.com/svn/trunk/javadoc/javax/inject/Qualifier.html) , guice also uses @BindingAnnotation (https://github.com/google/guice/wiki/BindingAnnotations)

  @Inject
  MyQualifierResource(@Saab Car car)
  {
    this.car = car;
  }

Lazily construct the Injector in JerseyGuiceServletContextListener so that modules can be added at runtime

Currently we still use JAX-WS (next to JAX-RS) and let the endpoint instances be resolved by guice. This is done by subclassing com.sun.xml.ws.server.AbstractMultiInstanceResolver and implement the resolve and start methods. In the start method we register the webServiceContext instance binding as a guice module.

Unfortunately the guice injector in JerseyGuiceServletContextListener is created in the constructor. Would it be an option to create it lazily?

AOP doesn't work

The docs suggest that Guice AOP should work. However, when I use a jax-rs method via jetty/jersey, my guice interceptor is nowhere to be found. When running the same jax-rs method in a test case (instantiating it via guice directly), the interceptor is present.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.