Guice - Jersey - Servlets

I recently switched to two-phase injection, and this created an error in servlet binding. I am currently switching between two error modes and am not sure which direction is best taken.

The first error I encountered was:

com.sun.jersey.api.container.ContainerException: ResourceConfig instance does not contain root resource classes.

My servlet module looked like this:

public class MyServletModule extends JerseyServletModule { @Override protected void configureServlets() { bind(MyServlet.class).asEagerSingleton(); serve("/*").with(GuiceContainer.class); } } 

I managed to remove this error by explicitly setting the com.sun.jersey.config.property.packages parameter.

 public class MyServletModule extends JerseyServletModule { @Override protected void configureServlets() { bind(MyServlet.class).asEagerSingleton(); Map<String,String> parameters = new HashMap<String, String>(); parameters.put(PackagesResourceConfig.PROPERTY_PACKAGES, MyServlet.class.getPackage().getName()); serve("/*").with(GuiceContainer.class, parameters); } } 

But when I do this, Guice tries to bind Just In Time, which does not respect @Inject in my servlet constructor.

com.google.inject.ConfigurationException: Guice configuration errors:

1) Unable to create a binding for MyServlet. It is already configured on one or more injectable injectors or private modules associated with MyServletModule.configureServlets (MyServletModule.java:44) If this was in PrivateModule, did you forget to open the link? while searching for MyServlet

1 error when com.google.inject.internal.InjectorImpl.getBinding (InjectorImpl.java:150)

My servlet has a @Inject constructor whose arguments cannot be bound just in time. After debugging in InjectorImpl, I believe that this is the reason why something fails when I use PROPERTY_PACKAGES.

I'm just not sure if PROPERTY_PACKAGES is being used correctly, and I need to fix some bindings? Or if this is the wrong direction, and I need to fix the original ResourceConfig error in another way.

Help or push in the right direction is welcome.

+4
source share
3 answers

I was able to link Jack's resources to Guice without using the binding parameters (without explicitly specifying the com.sun.jersey.config.property.packages parameter), linking the resources separately

 public class BindJerseyResources extends ServletModule { @Override protected void configureServlets() { // excplictly bind GuiceContainer before binding Jersey resources // otherwise resource won't be available for GuiceContainer // when using two-phased injection bind(GuiceContainer.class); // bind Jersey resources PackagesResourceConfig resourceConfig = new PackagesResourceConfig("jersey.resources.package"); for (Class<?> resource : resourceConfig.getClasses()) { bind(resource); } // Serve resources with Jerseys GuiceContainer serve("/*").with(GuiceContainer.class); } } 

Resources are similar to the following

 @Path("/") @RequestScoped public class Resource { private Storage storage; @Inject public Resource(Storage storage) { this.storage = storage; } @GET @Path("get/{name}") @Produces(MediaType.TEXT_PLAIN) public String getGuid(@PathParam("name") String name) { return storage.get(name); } } 

Perhaps this will help you avoid the last problematic snap.


Updated response to biphasic injection.

+8
source

Java part

 import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Singleton; import com.google.inject.persist.jpa.JpaPersistModule; import com.google.inject.servlet.GuiceServletContextListener; import com.sun.jersey.guice.JerseyServletModule; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import com.sun.jersey.spi.container.servlet.ServletContainer; import com.thjug.apipublic.Echo; public class ServletContextListener extends GuiceServletContextListener { @Override protected Injector getInjector() { final Injector injector = Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { bind(Echo.class); bind(ServletContainer.class).in(Singleton.class); serve("/*").with(GuiceContainer.class); } }, new JpaPersistModule("dbUnit"), new LoggingModule()); injector.getInstance(JPAInitializer.class); return injector; } } 

web.xml

  <distributable /> <display-name>API</display-name> <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> <description>Guice Initiate</description> <listener-class>com.thjug.base.ServletContextListener</listener-class> </listener> 

The following is my basic information on how to do REST using Guice http://www.slideshare.net/nuboat/lightweight-javaee

0
source

Here is an article on how to make a binding (including the full source code): implementing-distributed-counter

0
source

All Articles