RESTEasy Guice has some simple integration with Guice 7.0.
RESTEasy Guice will scan the binding types for a Guice Module for @Path and @Provider annotations.
It will register these bindings with RESTEasy.
@Path("hello")
public class HelloResource {
@GET
@Path("{name}")
public String hello(@PathParam("name") final String name) {
return "Hello " + name;
}
}First you start off by specifying a Jakarta REST resource class.
The HelloResource is just that.
Next you create a Guice Module class that defines all your bindings:
import com.google.inject.Module;
import com.google.inject.Binder;
public class HelloModule implements Module {
public void configure(final Binder binder) {
binder.bind(HelloResource.class);
}
}You put all these classes somewhere within your WAR WEB-INF/classes or in a JAR within WEB-INF/lib.
Then you need to create your web.xml file.
You need to use the GuiceResteasyBootstrapServletContextListener as follows
<web-app>
<display-name>Guice Hello</display-name>
<context-param>
<param-name>resteasy.guice.modules</param-name>
<param-value>dev.resteasy.examples.guice.hello.HelloModule</param-value>
</context-param>
<listener>
<listener-class>
dev.resteasy.guice.GuiceResteasyBootstrapServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>GuiceResteasyBootstrapServletContextListener is a subclass of ResteasyBootstrap, so you can use any other RESTEasy configuration option within your web.xml file.
Also notice that there is a resteasy.guice.modules context-param.
This can take a comma delimited list of class names that are Guice Modules.
Guice does not scan the classpath, so RESTEasy Guice can only see what your modules explicitly bind.
Every @Path root resource and every @Provider must be bound in one of your modules; an unbound resource is simply not registered and its endpoints return 404.
public class MyModule implements Module {
@Override
public void configure(final Binder binder) {
binder.bind(HelloResource.class); // a @Path resource
binder.bind(MyExceptionMapper.class); // an @Provider
binder.bind(GreetingService.class).to(GreetingServiceImpl.class);
}
}Resources are instantiated by Guice, so constructor injection uses Guice bindings.
This means the Jakarta REST @Context annotation cannot be used on a constructor parameter — RESTEasy performs @Context injection on fields and setters only, after Guice has created the instance.
To inject the request-scoped context objects (UriInfo, HttpHeaders, etc.) through a constructor, install the RequestScopeModule (see below) and use a plain @Inject constructor.
Add the RequestScopeModule to your modules to make the Jakarta REST context objects injectable with a plain Guice @Inject, bound to the current HTTP request.
The following types are bound: UriInfo, HttpHeaders, Request, SecurityContext, HttpServletRequest, and HttpServletResponse (ServletConfig and ServletContext are not bound).
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.UriInfo;
@Path("example")
public class ExampleResource {
private final UriInfo uriInfo;
@Inject
public ExampleResource(final UriInfo uriInfo) {
this.uriInfo = uriInfo;
}
@GET
public String get() {
return uriInfo.getRequestUri().toString();
}
}The scope is also available directly as the dev.resteasy.guice.RequestScoped annotation for binding your own request-scoped objects.
Add the JaxrsModule to bind the Jakarta REST utility factories so they can be injected: jakarta.ws.rs.ext.RuntimeDelegate, jakarta.ws.rs.core.Response.ResponseBuilder, jakarta.ws.rs.core.UriBuilder, and jakarta.ws.rs.core.Variant.VariantListBuilder.
You can configure the stage Guice uses to deploy your modules by specific a context param, resteasy.guice.stage.
If this value is not specified, RESTEasy uses whatever Guice’s default is.
<web-app>
<display-name>Guice Hello</display-name>
<context-param>
<param-name>resteasy.guice.modules</param-name>
<param-value>dev.resteasy.examples.guice.hello.HelloModule</param-value>
</context-param>
<context-param>
<param-name>resteasy.guice.stage</param-name>
<param-value>PRODUCTION</param-value>
</context-param>
<listener>
<listener-class>
dev.resteasy.guice.GuiceResteasyBootstrapServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>GuiceResteasyBootstrapServletContextListener can be extended to allow more flexibility in the way the Injector and Modules are created.
Three methods can be overridden: getModules(), withInjector() and getStage(). Register your subclass as the listener in the web.xml.
Override getModules() when you need to pass arguments to your modules' constructor or perform more complex operations.
Override withInjector(Injector) when you need to interact with the Injector after it has been created.
Override getStage(ServletContext) to set the Stage yourself.
<web-app>
<!-- other tags omitted -->
<listener>
<listener-class>
dev.resteasy.guice.GuiceResteasyBootstrapServletContextListener
</listener-class>
</listener>
</web-app>public class MyServletContextListener extends GuiceResteasyBootstrapServletContextListener {
@Override
protected List<? extends Module> getModules(ServletContext context) {
return List.of(new JpaPersistModule("consulting_hours"), new MyModule());
}
@Override
public void withInjector(Injector injector) {
injector.getInstance(PersistService.class).start();
}
}The group name and package name have both changed. If you are migrating from prior editions of RESTEasy Guice, you will need to update your dependencies and imports.
The new group name is 'dev.resteasy.guice' and the new package name is 'dev.resteasy.guice'.
For example code for the dependencies see: https://central.sonatype.com/artifact/dev.resteasy.guice/resteasy-guice
-
Previous package name: org.jboss.resteasy.plugins.guice.
-
Current package name: dev.resteasy.guice
This update may be as simple as searching for org.jboss.resteasy.plugins.guice and replacing it with dev.resteasy.guice.
For most projects, that will be either changing the entry in web.xml to:
<listener>
<listener-class>
dev.resteasy.guice.GuiceResteasyBootstrapServletContextListener
</listener-class>
</listener>Or changing the import statement in a custom listener to:
import dev.resteasy.guice.GuiceResteasyBootstrapServletContextListener;Releasing the project requires permission to deploy to Maven Central see Maven Central Release Requirements.
Once everything is setup, you simply need to run the ./release.sh script. There are two required parameters:
-
-ror--releasewhich is the version you want to release -
-dor--developmentwhich is the next development version.
By default the release version cannot contain SNAPSHOT and the development version, must container SNAPSHOT.
./release -r 1.0.0.Final -d 1.0.1.Final-SNAPSHOT| Argument | Requires Value | Description |
|---|---|---|
|
Yes |
The next version for the development cycle. |
|
No |
Forces to allow a SNAPSHOT suffix in release version and not require one for the development version. |
|
N/A |
Displays this help |
|
Unused |
Passes the |
|
Unused |
Passes the |
|
Yes |
The version to be released. Also used for the tag. |
|
No |
Executes the release in as a dry-run. Nothing will be updated or pushed. |
|
No |
Executes the release in, but doesn’t actually push the changes to GitHub or publish the release on Maven Central. |
|
No |
Prints verbose output. |
Any additional arguments are considered arguments for the Maven command.