An Introduction to the RESTEasy SeBootstrap Usage

By Wei Nan Li | November 1, 2022

Since RESTEasy implements the Jakarta RESTful Web Services 3.1 API, it includes an implementation for the jakarta.ws.rs.SeBootstrap API. The API allows the jakarta.ws.rs.core.Application to be run in a Java SE environment. In this article, I’ll focus on its usage of the feature.

Firstly, the simplest way to use the the feature is to write a code block like this:

SeBootstrap.start(MyApp.class)
        .thenApply(instance -> {
            instance.stopOnShutdown((stopResult -> System.out.println("Container has stopped.")));
            try (Client client = ClientBuilder.newClient()) {
                final Response response = client.target(instance.configuration()
                        .baseUriBuilder()
                        .path("rest")).request().get();
                System.out.println(response.readEntity(String.class));
            }
            return instance;
        }).toCompletableFuture().get();

In the above code we use the SeBootstrap.start() method to start a service. This registers the MyApp.class resource. The MyApp.class is just an ordinary Application class and contains a basic resource class:

@ApplicationPath("/rest")
public class MyApp extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        return Set.of(MyResource.class);
    }
}

Here is the content of the MyResource class:

@Path("/")
public class MyResource {
    @GET
    public String get() {
        return "Hello";
    }
}

And the SeBootstrap interface will take care of the service setup and starting process. If you don’t deal with this code block, the service will exit after the code block is executed and exited. So if you want to hold the service and keep it long running, you can put this line under the above code block:

Thread.currentThread().join();

So the code execution will stay running at above point, and the service will be kept open for accessing. In this way the service is used like a normal service. If you just want to start a service inline, and do a client side request, and then let the service go away, you can write code like this:

SeBootstrap.start(ExampleApplication.class, SeBootstrap.Configuration.builder()
                .build())
        .thenApply((instance) -> {
            try (Client client = ClientBuilder.newClient()) {
                final WebTarget target = client.target(instance.configuration().baseUriBuilder());
                final Response response = client.target(instance.configuration()
                                .baseUriBuilder()
                                .path("/foo"))
                        .request()
                        .get();
                System.out.printf("Response: %d - %s%n", response.getStatus(), response.readEntity(String.class));
            }
            return instance;
        })
        .whenComplete((instance, t) -> instance.stop())
        .toCompletableFuture().get(60, TimeUnit.MINUTES);

In the above code block, it uses the thenApply() method to write a closure, and inside the closure it creates a client and does the request to the service, and processes the response inline. Finally, it uses the whenComplete() method to stop the service. To avoid the service quit before the client request is finished, there is .toCompletableFuture().get(60, TimeUnit.MINUTES) added at end to wait for the call to be finished, and it sets the timeout period to 60 minutes.

As we can see, the SeBootstrap API requires an embedded server. RESTEasy currently has 6 embedded servers implemented. Only org.jboss.resteasy:resteasy-undertow and org.jboss.resteasy:resteasy-undertow-cdi implement all the features and are the preferred implementations. However, the others will work in most cases. You can even implement your own by implementing the org.jboss.resteasy.plugins.server.embedded.EmbeddedServer interface and adding a service file for your implementation.

Here is the list of the currently supported embedded servers:

  • CdiNettyJaxrsServer
  • NettyJaxrsServer
  • ReactorNettyJaxrsServer
  • UndertowCdiEmbeddedServer
  • UndertowJaxrsServer
  • VertxJaxrsServer

There is another server already deprecated and shouldn’t be used:

  • SunHttpJaxrsServer

In addition, these implementations also honor the @Priority annotation giving higher priority to lower values from the annotation. To use one of the embedded servers, RESTEasy will automatically search the classpath to find one of the above servers during runtime, and load it automatically. For example, if you want to use the UndertowCdiEmbeddedServer as the underlying server, you can add these dependencies to your project:

<dependencies>
    <dependency>
        <groupId>jakarta.ws.rs</groupId>
        <artifactId>jakarta.ws.rs-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-undertow-cdi</artifactId>
    </dependency>
</dependencies>

As the pom.xml section shown above, it adds resteasy-undertow-cdi into the dependencies. So the SeBootstrap will load the UndertowCdiEmbeddedServer provided by resteasy-undertow-cdi during the runtime.

Note: You don’t have to add resteasy-core into dependency explicitly, because the reteasy-undertow-cdi will bring it in.

To see more of the SeBootstrap usage, RESTEasy provides a usage example in the resteasy-quickstart project:

The above code shows the usage of SeBootstrap with resteasy-undertow-cdi as the underlying implementation.

Note: Currently we are cleanning up the resteasy-example project, once we finished working on it we may move the above example back to the resteasy-example repository.

In addition, the RESTEasy document contains a section writing about its usage:

To see more examples, the test code is also a good place to check:

To understand the design of the SeBootstrap and its implementation inside RESTEasy, you can read this article:

Enjoy!

         

YourKit
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications. YourKit is the creator of YourKit Java Profiler, YourKit .NET Profiler, and YourKit YouMonitor