151 Whiteboard Specification for Jakarta™ RESTful Web Services

151.1 Introduction

REpresentational State Transfer (REST) is a simple pattern for producing Web Services. RESTful services use URI pattern matching to match a particular web resource. Different HTTP verbs, for example GET and DELETE, map to different operations on that resource. Standard HTTP response codes are used to communicate the result of an operation, potentially including a response body if the operation returns a result.

The [1] Jakarta RESTful Web Services 3.0 Specification defines a set of annotation mappings which allow Plain Old Java Objects (POJOs) to be directly exposed as RESTful web resources; these resources can also be grouped together using a Jakarta RESTful Web Services Application. Furthermore the specification defines a plugable model for extending the behavior of the application and the features of the Jakarta RESTful Web Services container itself. For example an extension may define specific error responses that should be sent when particular exceptions occur, or an extension may add support for serializing responses to a different format. The OSGi Whiteboard Specification for Jakarta RESTful Web Services provides a light and convenient way of using these POJOs, applications and extensions in an OSGi environment through the use of the [3] Whiteboard Pattern.

The Whiteboard Specification for Jakarta RESTful Web Services supports:

  • Registering Resources - Registering a Jakarta RESTful Web Services annotated POJO in the Service Registry makes it available to be bound to an endpoint and to start responding to incoming requests.

  • Registering Applications - Registering a Jakarta RESTful Web Services Application in the Service Registry makes it available to be bound to an endpoint and to start responding to incoming requests.

  • Registering Extensions - The Jakarta RESTful Web Services specification defines a variety of plugable extensions. These extensions can be registered in the Service Registry to include them in the handling pipeline.

  • Requiring Extensions - Sometimes Jakarta RESTful Web Services resources, or even Jakarta RESTful Web Services extensions, depend upon the presence of another extension. For example a Jakarta RESTful Web Services resource and exception mapper may both depend on a JSON serializer. Jakarta RESTful Web Services Whiteboard services may define preconditions that must be satisfied before they can be bound.

Jakarta RESTful Web Services Whiteboard implementations must support at least version 3.0 of the Jakarta RESTful Web Services API.

151.1.1 Entities

This specification defines the following entities:

  • Jakarta RESTful Web Services Whiteboard service - An object registered in the Service Registry providing the necessary Whiteboard service properties defined by this specification. Whiteboard services may be resource, application or extension services

  • Jakarta RESTful Web Services Whiteboard implementation - An implementation that provides one or more Jakarta RESTful Web Services Whiteboards.

  • Jakarta RESTful Web Services Whiteboard - A runtime instance that processes Jakarta RESTful Web Services Whiteboard services. Each Jakarta RESTful Web Services Whiteboard service may be processed by multiple Jakarta RESTful Web Services Whiteboards. Different Jakarta RESTful Web Services Whiteboards provided by the same Jakarta RESTful Web Services Whiteboard implementation may configured differently, for example using different ports or root contexts.

  • Jakarta RESTful Web Services Service Runtime service - A service providing runtime introspection into a Jakarta RESTful Web Services Whiteboard instance.

  • Jakarta RESTful Web Services Resource Service - A service that provides one or more RESTful resource methods which map to incoming HTTP requests.

  • Jakarta RESTful Web Services Application Service - A service that provides a jakarta.ws.rs.core.Application to be hosted by a Jakarta RESTful Web Services Whiteboard.

  • Jakarta RESTful Web Services Extension Service - A service that extends the functionality of a Jakarta RESTful Web Services Whiteboard.

  • Static Resources - Jakarta RESTful Web Services resources that are included programmatically in a Jakarta RESTful Web Services Whiteboard application, rather than being added at runtime by the whiteboard.

Figure 151.1 Jakarta RESTful Web Services Whiteboard Overview Diagram

Jakarta RESTful Web Services Whiteboard Overview Diagram

The Figure 151.1 shows an OSGi framework running a Jakarta RESTful Web Services Whiteboard Implementation bundle. This bundle has been configured to provide two Jakarta RESTful Web Services whiteboards, each of which has a corresponding Jakarta RESTful Web Services Service Runtime Service. The various Jakarta RESTful Web Services Whiteboard services available in the framework are discovered and processed by both whiteboards.

151.2 The Jakarta RESTful Web Services Whiteboard

An important principle of the Whiteboard Specification for Jakarta RESTful Web Services is that an OSGi framework may contain many active Jakarta RESTful Web Services Whiteboards at any time, even if there is only a single Jakarta RESTful Web Services Whiteboard implementation present in the framework. In addition to providing a web endpoint with which to register Whiteboard services, a Jakarta RESTful Web Services Whiteboard provides a holder for Jakarta RESTful Web Services Applications.

All Jakarta RESTful Web Services Whiteboards have a default application which is used to register resources that do not target an existing application. In this respect a Jakarta RESTful Web Services whiteboard application shares some similarities with a Servlet Context in the Jakarta Servlet Whiteboard. Resources registered with a Jakarta RESTful Web Services Whiteboard are always registered as part of an application. The generated name of the default application is .default, and it is mapped to the root context of the Jakarta RESTful Web Services Whiteboard.

A Jakarta RESTful Web Services Whiteboard implementation must create a Jakarta RESTful Web Services Whiteboard instance, however it is expected that most implementations will permit multiple Jakarta RESTful Web Services whiteboards to be configured. These instances may differ significantly, or may simply offer the same capabilities on a different port.

For details on the association process between Jakarta RESTful Web Services Whiteboard services and a Jakarta RESTful Web Services Whiteboard see Common Whiteboard Properties.

151.2.1 The Jakarta RESTful Web Services Service Runtime Service

The JakartarsServiceRuntime service represents the runtime state information of a Jakarta RESTful Web Services Whiteboard instance. This information is provided through Data Transfer Objects (DTOs). The architecture of OSGi DTOs is described in OSGi Core Release 8.

Each Jakarta RESTful Web Services Whiteboard implementation registers exactly one JakartarsServiceRuntime service per Jakarta RESTful Web Services Whiteboard. The service properties of the Jakarta RESTful Web Services Service Runtime Service can be used to target Jakarta RESTful Web Services Whiteboard services at specific Jakarta RESTful Web Services whiteboards, as described by the osgi.jakartars.whiteboard.target property in Common Whiteboard Properties.

The JakartarsServiceRuntime provides service registration properties to declare its underlying Jakarta RESTful Web Services Whiteboard. These service properties can include implementation-specific key-value pairs. They also include the following:

Table 151.1 Service properties for the JakartarsServiceRuntime service

Service Property Name Type Description
osgi.jakartars.endpoint String+

Endpoint(s) where this Jakarta RESTful Web Services Whiteboard is listening. Registered Whiteboard services are made available here. Values could be provided as URLs e.g. http://192.168.1.10:8080/ or relative paths, e.g. /myapp/. Relative paths may be used if the scheme and authority parts of the URLs are not known, for example if the Jakarta RESTful Web Services Whiteboard is delegating to a bridged Http Service implementation. If the Jakarta RESTful Web Services Whiteboard Service is serving the root context and scheme and authority are not known, the value of the property is /. Each entry must end with a slash.

See JAKARTA_RS_SERVICE_ENDPOINT.

service.changecount Long

Whenever the DTOs available from the Jakarta RESTful Web Services Service Runtime service change, the value of this property will increase.

This allows interested parties to be notified of changes to the DTOs by observing Service Events of type MODIFIED for the JakartarsServiceRuntime service. See org.osgi.framework.Constants.SERVICE_CHANGECOUNT in OSGi Core Release 8.


151.2.2 Inspecting the Runtime DTOs

The Jakarta RESTful Web Services Service Runtime service provides information about registered Whiteboard services through the RuntimeDTO.

The Runtime DTO provides information about services that have been successfully registered as well as information about the Jakarta RESTful Web Services Whiteboard services that were not successfully registered. Jakarta RESTful Web Services Whiteboard services that have the required properties set but cannot be processed, are reflected in the failure DTOs. Jakarta RESTful Web Services Whiteboard services of interfaces described in this specification that do not have the required properties set are ignored and not reflected in the failure DTOs.

The Runtime DTO can be obtained using the getRuntimeDTO() method. The Runtime DTO returned provides a snapshot of the state of the Jakarta RESTful Web Services Runtime, including the Jakarta RESTful Web Services Whiteboard resources, extensions and applications that are active in each registered application. The Runtime DTO also includes information about Whiteboard services which could not be activated.

151.2.2.1 DTO properties

When whiteboard services are registered with the whiteboard they must be introspected and this information reflected in the DTO(s) for that service. This introspection will include looking for annotations such as @GET and @Path both at a class and method level. The values associated with these annotations must then be appropriately combined, for example when @Path is declared on a type and method level, and recorded in the DTO.

151.2.2.2 Failure DTOs

There are a variety of reasons that whiteboard services may not be able to be used by the whiteboard. For example, if the whiteboard service cannot be retrieved from the service registry, or if the whiteboard service provides an invalid service property value, such as a malformed filter.

In these cases the failed services are represented in the Runtime DTO under one of the failed DTO properties. Depending upon the failure reason one or more of the properties of the failed DTO may be unavailable. For example if the service cannot be retrieved from the service registry then it cannot be introspected for annotations. A failure DTO will always contain the service id for the failed service and the failure reason. The whiteboard implementation must then fill in other DTO properties on a best effort basis.

151.2.3 Relation to the Servlet Container

Implementations of this specification will often be backed by existing servlet containers, such as the OSGi Http Whiteboard, or a Jakarta EE application server. There may also exist implementations which bridge into a servlet container into which the OSGi Framework has been deployed as a Web Application.

In bridged situations the Jakarta RESTful Web Services Whiteboard implementation will have limited facilities for creating new Jakarta RESTful Web Services whiteboards, and may also have limited information about its environment.

Information about the surrounding Servlet Container, including ServletContext information and HttpSession data, is available to Jakarta RESTful Web Services Whiteboard resources using standard Jakarta RESTful Web Services injection behavior.

@GET
@Path("{name}")
public String interrogateSession(@PathParam("name") String name,
         @Context HttpServletRequest req) {
    HttpSession s = req.getSession();
    return String.valueOf(s.getAttribute(name));
}

A Jakarta RESTful Web Services Whiteboard implementation needs to ensure that Http Sessions are not shared amongst different Jakarta RESTful Web Services Whiteboards, or amongst different Jakarta RESTful Web Services Whiteboard applications. That is, HttpServletRequest.getSession() calls must provide different sessions for each whiteboard application with which a Jakarta RESTful Web Services whiteboard service is associated.

151.2.4 Isolation between Jakarta RESTful Web Services Whiteboards

Even when they are created by the same Jakarta RESTful Web Services Whiteboard implementation, each Jakarta RESTful Web Services Whiteboard instance is separate, and isolated from other instances. Importantly, Jakarta RESTful Web Services Whiteboard services targeted to one Jakarta RESTful Web Services Whiteboard application must not be visible in any other Whiteboard or applications to which they are not targeted.

This isolation restriction is critical, as it ensures that different Jakarta RESTful Web Services Whiteboard applications can be configured with different, potentially overlapping, incompatible extension features.

151.3 Common Whiteboard Properties

Jakarta RESTful Web Services Whiteboard services support common service registration properties to associate them with a Jakarta RESTful Web Services Whiteboard. These properties apply to whiteboard resources, extensions and applications except where explicitly stated otherwise. Each service property has an associated Component Property Type annotation that can be used to easily apply the property to a Declarative Services Component.

Table 151.2 Common properties

Service Property Type Description

osgi.jakartars.name

JakartarsName

String

optional

A user defined name that can be used to identify a Jakarta RESTful Web Services whiteboard service. Names must follow OSGi symbolic name rules, and also must not start with the prefixes '.' or 'osgi.'.

If no name is defined for a Jakarta RESTful Web Services whiteboard service then one is generated for it. This generated name will start with a '.'. The prefix osgi. is currently unused, but reserved for future versions of this specification.

If a Jakarta RESTful Web Services service is registered with an illegal name then it is not bound and this is reflected in the failure DTOs. If two Jakarta RESTful Web Services services are registered with the same name (even if they are advertised as different types) then only the first service in ranking order, as specified in ServiceReference.compareTo, is bound and the lower ranked service(s) are reflected in the failure DTOs. See JAKARTA_RS_NAME.

osgi.jakartars.application.select

JakartarsApplicationSelect

String+

optional

One or more LDAP-style filters to select the Jakarta RESTful Web Services Application(s) with which this Whiteboard service should be associated. Any service property of the Application can be filtered on. If these filters are not defined then the default Application is used. If multiple filters are defined then each filter is used to select target applications. Target applications are selected at most once, even if they match more than one filter. The default application can also be specifically targeted using the application name .default.

For example, to select an Application with name myApp provide the following filter:

(osgi.jakartars.name=myApp)

To select all Applications in the whiteboard provide the following value:

(osgi.jakartars.name=*)

If no matching application exists this is reflected in the failure DTOs. See JAKARTA_RS_APPLICATION_SELECT.

† Note that this property is not valid for Jakarta RESTful Web Services Application services.

osgi.jakartars.extension.select

JakartarsExtensionSelect

String+

optional

A set of LDAP-style filters used to express dependencies on one or more extension services. If a filter is provided then the Jakarta RESTful Web Services Whiteboard attempts to match that filter against the service properties of the Whiteboard runtime, the service properties of the whiteboard application, and each of the extension services currently active in the application. This search may occur in any order. If all of the supplied filters are matched then the whiteboard service is registered into the Jakarta RESTful Web Services Whiteboard application.

For example, to require an extension which provides JSON serialization advertising property name serialize.to with value JSON provide the following filter:

(serialize.to=JSON)

A more detailed version of this example is available in A Jakarta RESTful Web Services Whiteboard Extension Example

If any filter(s) fail to match then this is reflected in the failure DTOs. See JAKARTA_RS_EXTENSION_SELECT.

osgi.jakartars.whiteboard.target

JakartarsWhiteboardTarget

String

optional

The value of this service property is an LDAP-style filter expression to select the Jakarta RESTful Web Services Whiteboard(s) to handle this Whiteboard service. The LDAP filter is used to match JakartarsServiceRuntime services. Each Jakarta RESTful Web Services Whiteboard exposes exactly one JakartarsServiceRuntime service. This property is used to associate the Whiteboard service with the Jakarta RESTful Web Services Whiteboard that registered the JakartarsServiceRuntime service. If this property is not specified then the service will target all Jakarta RESTful Web Services Whiteboards. See JAKARTA_RS_WHITEBOARD_TARGET.


151.4 Registering RESTful Resources

Jakarta RESTful Web Services resources can be registered with the Jakarta RESTful Web Services Whiteboard by registering them as Whiteboard services. This means that the resource POJO implementations are registered in the Service Registry. As Jakarta RESTful Web Services resources are POJOs they may be registered using any valid service interface, including Object. The Jakarta RESTful Web Services container will then use reflection to discover methods and annotations on the resource object, just as it would outside of OSGi.

As Jakarta RESTful Web Services resources have no common interface type they are instead registered with the osgi.jakartars.resource service property with a value of "true". This property serves as a marker to the Jakarta RESTful Web Services whiteboard runtime, indicating that this OSGi service should be hosted as a Jakarta RESTful Web Services Whiteboard resource.

151.4.1 Jakarta RESTful Web Services Resource mapping

Jakarta RESTful Web Services resources use the Path annotation to bind themselves to particular URIs within the Jakarta RESTful Web Services container. The path annotation can be applied to the resource class, and to individual resource methods. For example the following Jakarta RESTful Web Services resource:

@Path("foo")
public class Foo {

    private final List<String> entries = 
        Arrays.asList("fizz", "buzz", "fizzbuzz");
        
    @GET
    public List<String> getFoos() {
        return Collections.unmodifiableList(entries);
    }

    @GET
    @Path("{name}")
    public String getFoo(@PathParam("name") String name) {
        if(entries.contains(name)) {
            return "A foo called " + name;
        }
        throw new IllegalArgumentException(“No foo called “ + name);
    }

}

This Jakarta RESTful Web Services resource defines two resource methods. The Path annotation applied to the class sets the base URI for all methods in the resource. The getFoos() method is therefore bound to the URI foo. The Path annotation on the getFoo() method makes this method a sub-resource which captures the next token in the URI. This method is therefore bound to URIs of the form foo/buzz.

When used as an OSGi Jakarta RESTful Web Services Whiteboard service a Jakarta RESTful Web Services resource follows the same mapping rules, but the base context(s) it uses are determined by the Application(s) to which it is mapped. For example, when mapped to the default application of a whiteboard with endpoint http://127.0.0.1/ the getFoos() method would be available at http://127.0.0.1/foo.

151.4.1.1 Clashing resource mappings

Resource services bound to a Jakarta RESTful Web Services whiteboard application share a single URI namespace with other resources in the application (including any existing static resources). When Jakarta RESTful Web Services services are bound it is possible that one or more methods on these services will map to the same URI. This situation is permitted by the Jakarta RESTful Web Services specification which defines a detailed selection algorithm.

When clashes occur in the Jakarta RESTful Web Services whiteboard then resources supplied using the service whiteboard must be preferred to static resources contained in the application. If two or more whiteboard resources exist then they must be ordered using ranking order, as specified in ServiceReference.compareTo. Unlike for other services in the Jakarta RESTful Web Services whiteboard, whiteboard resource services must not be ordered using their natural ordering. Whiteboard resource services with the same ranking must be considered equal, following the normal resource method selection rules defined in the Jakarta RESTful Web Services specification. As per the Core specification, whiteboard services with no service.ranking property must be treated as having a ranking of 0.

151.4.2 Jakarta RESTful Web Services Whiteboard Resource Lifecycle

A key tenet of Jakarta RESTful Web Services is that all resource objects are stateless. In the Jakarta RESTful Web Services specification resources therefore have one of two scopes, they are either singleton, or request-scoped. Singleton resources are created once, potentially outside the Jakarta RESTful Web Services container, and request-scoped resources are created on-demand for each request, then discarded afterwards.

Typically Jakarta RESTful Web Services developers are encouraged to write request-scoped resources, as this makes it difficult to accidentally write stateful components. In OSGi, however, it is more common to write singleton services. On demand instances of OSGi services can be created, but only if the service is registered as a prototype scope.

The Jakarta RESTful Web Services whiteboard implementation is responsible for managing the mismatch between the OSGi service lifecycle model and the Jakarta RESTful Web Services resource lifecycle model. If the Jakarta RESTful Web Services whiteboard resource is registered as prototype scope then the implementation must treat the resources as request-scoped, creating a new service instance for each request and releasing it when the request completes. Otherwise the Jakarta RESTful Web Services whiteboard service must be registered as a singleton scope resource within the application. Singleton scope whiteboard resources must be released by the Jakarta RESTful Web Services whiteboard when the application with which they have been registered is removed from the whiteboard, even if this is only a temporary situation.

If a failure occurs when getting the resource service this will prevent the service from being used, which is reflected using a failure DTO. In such a case the system treats the resource as unusable.

When multiple Jakarta RESTful Web Services Whiteboard implementations are present all of them can potentially process the whiteboard resources. In such situations it can be useful to associate the servlet with a specific whiteboard by specifying the osgi.http.whiteboard.target property on the service.

151.4.2.1 Resource Context Injection

Jakarta RESTful Web Services resources may have objects injected into them by the Jakarta RESTful Web Services container. These objects may be related to an incoming request, for example an HTTP header value, or part of the container runtime. Injected resources are annotated with a Jakarta RESTful Web Services annotation, for example @Context, and may be injected as method parameters, or as fields in the object.

If the Jakarta RESTful Web Services injected objects are passed as method parameters then the resource object may be a singleton. If, however, the objects are injected into fields by the Jakarta RESTful Web Services container then the resource should be declared as a prototype scope. Jakarta RESTful Web Services Whiteboard implementations may support field injection for singleton resources, however this behavior is non portable, and may lead to errors at runtime when using other implementations.

151.4.2.2 Request-Scoped Resources

Request-scoped resources are created on demand for a request and then discarded afterwards. Critically for OSGi services the Jakarta RESTful Web Services whiteboard must not release a prototype scope service until after the response has completed. If the resource makes use of a Jakarta RESTful Web Services AsyncResponse, SseEventSink or a StreamingOutput then this may be some time after the return of resource method, and potentially on a different thread.

Jakarta RESTful Web Services whiteboard implementations must therefore take special care not to release request scoped instances until they are completely finished.

151.4.2.3 Asynchronous Responses

Jakarta RESTful Web Services supports asynchronous responses either for single-valued results, or for streams of data.

Single valued results may be provided by the AsyncResponse type which is injected into resource methods using the @Suspended annotation. If the resource is request scoped then the resource must not be released until after the AsyncResponse has completed.

The following example demonstrates the use of the AsyncResponse:

@Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource     
 public class MyResource {
  
    @Path(“foo”)
    @GET
    public void getFoo(@Suspended AsyncResponse async) {
        Promise<String> p = doLongRunningTaskAsynchronously();
        p.onSuccess(v -> async.resume(v))
            .onFailure(t -> async.resume(t));
    }
}

Single valued asynchronous results can also be provided by returning a suitable type from the resource method. This can be a CompletionStage as described in the Jakarta RESTful Web Services specification, or an OSGi Promise type. In this case the response from the resource method will be sent once the returned type has completed, either successfully or by failing.

The following example demonstrates the use of an asynchronous return value:

@Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource     
 public class MyResource {
  
    @Path(“foo”)
    @GET
    public Promise<String> getFoo() {
        Promise<String> p = doLongRunningTaskAsynchronously();
        return p;
    }
}

Multi-valued results in Jakarta RESTful Web Services are handled using Server Sent Events. To send Server Sent Events a Jakarta RESTful Web Services resource must declare its produced media type appropriately, and inject its resource method with a SseEventSink. The resource must also gain access to a Sse to use as a factory for Outbound Server Sent Events. If the resource is request scoped then the resource must not be released until after the SseEvent has closed.

The following example demonstrates the use of the Server Sent Events:

@Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource     
 public class MyResource {
  
    @Context
    Sse sse;

    @GET
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void getFoo(@Context SseEventSink sink) {
        PushStream<String> p = getStreamOfMessages();
        p.map(sse::newEvent)
            .forEach(e -> sink::send)
            .onResolve(sink::close);
    }
}

151.4.3 Resource Service Properties

The following table describes the properties that can be used by Jakarta RESTful Web Services resources registered as Whiteboard services. Additionally, the common properties listed in Table 151.2 on page are supported.

Table 151.3 Service properties for Jakarta RESTful Web Services Whiteboard resource services.

Service Property Type Description

osgi.jakartars.resource

JakartarsResource

String / Boolean

required

Declares that this service must be processed by the Jakarta RESTful Web Services whiteboard when set to true. See JAKARTA_RS_RESOURCE.


151.4.4 A Jakarta RESTful Web Services Whiteboard Resource Example

The following example code uses Declarative Services annotations to register a Jakarta RESTful Web Services Whiteboard service.

@Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource     
 public class MyResource {
  
     @GET
     @Path("hello")
     @Produces("text/plain")
     public String sayHello(){
          return "Hello World!";
     }
 }

This example registers the resource method at: /hello. Requests for http://www.acme.com/hello map to the resource method, which is called to process the request.

To associate the above example resource with another application add the following service property:

osgi.jakartars.application.select=(osgi.jakartars.name=myApp)

This can also be added using the property annotation:

@JakartarsApplicationSelect("(osgi.jakartars.name=myApp)")

Setting this property requires a Jakarta RESTful Web Services application named myApp to be registered:

@Component(service=Application.class)
@JakartarsName("myApp")
@JakartarsApplicationBase("foo")
public class MyApplication extends Application {}

Now the whiteboard resource will be available at http://www.acme.com/foo/hello as configured by the custom Jakarta RESTful Web Services application.

151.5 Registering Extensions

Jakarta RESTful Web Services extensions can be registered with the Jakarta RESTful Web Services Whiteboard by registering them as Whiteboard services. This means that the extension implementations are registered in the Service Registry. It is relatively common for a single extension type to provide more than one extension interface, for example MessageBodyReader and MessageBodyWriter are often provided by a single object.

Extension services must be registered with the Jakarta RESTful Web Services application that they target using only the interfaces that they advertise in the OSGi service registry. If, for example, an extension service object implements MessageBodyReader and ContainerRequestFilter but only advertises MessageBodyReader in its service registration then it must only be used as a MessageBodyReader

The following Jakarta RESTful Web Services extension interfaces are supported by this specification:

  • ContainerRequestFilter and ContainerResponseFilter - these extensions are used to alter the HTTP request and response parameters.

  • ReaderInterceptor and WriterInterceptor - these extensions are used to alter the incoming or outgoing objects for the call.

  • MessageBodyReader and MessageBodyWriter - these extensions are used to deserialize/serialize objects to the wire for a given media type, for example application/json.

  • ContextResolver extensions are used to provide objects for injection into other Jakarta RESTful Web Services resources and extensions.

  • ExceptionMapper extensions are used to map exceptions thrown by Jakarta RESTful Web Services resources into responses.

  • ParamConverterProvider extensions are used to map rich parameter types to and from String values.

  • Feature and DynamicFeature - these extensions are used as a way to register multiple extension types with the Jakarta RESTful Web Services container. Dynamic Features further allow the extensions to be targeted to specific resources within the Jakarta RESTful Web Services container.

As Jakarta RESTful Web Services extensions have many possible interface types, none of which are defined by this specification, they must be registered with the osgi.jakartars.extension service property with a value of true. This property serves as a marker to the Jakarta RESTful Web Services whiteboard runtime, indicating that this OSGi service should be used as a Jakarta RESTful Web Services Whiteboard extension.

If the osgi.jakartars.extension is added to a service which does not advertise any of the Jakarta RESTful Web Services extension types then this is an error, and must result in a failure DTO being created.

151.5.1 Name Binding and Jakarta RESTful Web Services Extensions

By default Jakarta RESTful Web Services extensions are applied to every request, however sometimes they are only needed for a subset of resource methods. In this case a NameBinding annotation can be used to apply the extension to a subset of resource methods. The following example declares a binding annotation called FizzBuzz and uses it to bind an extension which replaces occurrences of "fizz" with "fizzbuzz".

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@NameBinding
public @interface FizzBuzz{}

@Component
@JakartarsExtension
@FizzBuzz
public class FizzBuzzReplacer implements WriterInterceptor {

    public void aroundWriteTo(WriterInterceptorContext ctx) {
        Object entity = ctx.getEntity();
        
        if(entity != null) {
            ctx.setEntity(entity.toString()
                .replace("fizz", "fizzbuzz"));
        }
        ctx.proceed();
    }
}

@Component(service=FizzResource.class)
@JakartarsResource
@Path("fizzbuzz")
public class FizzResource {

    @GET
    @FizzBuzz
    public String getFoos() {
        return "fizz, buzz, fizzbuzz";
    }
}

The result of an http request to the fizzbuzz URI will be fizzbuzz, buzz, fizzbuzzbuzz

The Jakarta RESTful Web Services whiteboard implementation must support the use of NameBinding to limit the scope of applied whiteboard extensions.

151.5.2 Extension ordering

Jakarta RESTful Web Services filters can be annotated with @PreMatching to indicate that they should be applied before the Jakarta RESTful Web Services container works out which resource should be called by the incoming request. These filters can therefore change the request such that it maps to a different resource than it would have before the filter’s operation. Pre-matching filters cannot use NameBinding as no corresponding named resource is available to the runtime when they operate.

When used in the OSGi Jakarta RESTful Web Services Whiteboard Jakarta RESTful Web Services extensions follow the same ordering rules as defined by the Jakarta RESTful Web Services specification. Where more than one extension of a particular type is available then they are ordered according to their jakarta.annotation.Priority. If two extensions of the same type have the same priority then the whiteboard implementation must break the tie by ordering the extensions according to the natural ordering of their service references, as specified in ServiceReference.compareTo, with static extensions being ranked below all whiteboard services.

The extension processing flow is as follows:

  1. Server receives a request

  2. Pre-matching ContainerRequestFilters are executed. Changes made here can affect which resource method is chosen

  3. The Server matches the request to a resource method

  4. Post-matching ContainerRequestFilters are executed. This includes execution of all filters which match the incoming path and any name-bound filters.

  5. ReaderInterceptors which match the incoming path are applied to the incoming request body. If the request has no body then the ReaderInterceptors are not called.

  6. The list of MessageBodyReaders applicable to the path and incoming content type are tried according to the standard ordering rules. The first MessageBodyReader which states that it can deserialize the entity “wins” and is used to create the entity object. If the incoming request has no body then no MessageBodyReaders are called.

  7. If the resource is request scoped then it is instantiated and injected with relevant types from any defined ContextResolvers. These are queried in order for each of the injectable fields.

  8. The resource method is executed, passing any injected parameters from the request, and from any ContextResolvers. These are queried in turn for each of the injectable parameters.

  9. ContainerResponseFilters are executed passing the method's response when it is complete. This includes execution of all filters, in order, which match the incoming path and any name-bound filters. Note that if an AsyncResponse is used then the response may not complete on the same thread as the incoming request.

  10. WriterInterceptors which match the incoming path are applied to the outgoing response stream. If the response has no body then the WriterInterceptors are not called.

  11. The list of MessageBodyWriters applicable to the path and outgoing content type are tried according to the standard ordering rules. The first writer which states that it can serialize the entity “wins” and is used to write out the entity object. If there is no response body then no writers are called.

  12. The Server response is flushed and committed. If the resource that created the response was request scoped then it must only be released once the response is complete. Note that this may be at some point in the future, and on a different thread if the resource is using an AsyncResponse

151.5.3 Extension dependencies

The osgi.jakartars.extension.select property described in Common Whiteboard Properties applies to extensions as well as Jakarta RESTful Web Services resources. This is because one extension may depend on another.

The most common reason for an extension to have a dependency is for a context injection dependency. Dependencies are often provided by a ContextResolver so that they can be injected into another extension. The following example demonstrates a simple dependency on a Jackson ObjectMapper.

@JakartarsExtension
@JakartarsName("configProvider")
@Component
public class ConfigProvider implements ContextResolver {
    
    private ObjectMapper mapper = new ObjectMapper();
    
    public <T> getContext(Class<T> clazz) {
        if(ObjectMapper.class.equals(clazz)) {
            return mapper;
        }
        return null;
    }
}

@JakartarsExtension
@JakartarsExtensionSelect("(osgi.jakartars.name=configProvider)")
@Component(scope=ServiceScope.PROTOTYPE)
public class ConfiguredExtension implements WriterInterceptor {

    @Context
    private Providers providers;

    public void aroundWriteTo(WriterInterceptorContext ctx) {
        Object entity = ctx.getEntity();
        
        if(entity != null) {
            ObjectMapper mapper = providers
                    .getContextResolver(ObjectMapper.class)
                    .getContext(ObjectMapper.class);
                    
            ctx.setEntity(mapper.writeValueAsString(entity));
        }
        ctx.proceed();
    }
}

151.5.4 Built in extensions

Depending on the capabilities of the Jakarta RESTful Web Services whiteboard implementation, and any statically defined extensions that make up a Jakarta RESTful Web Services Whiteboard application, there may be numerous non standard extensions available. These extensions must be represented using service properties on the Jakarta RESTful Web Services Service Runtime, or the whiteboard application as appropriate. This is why the extension select filters must also be matched against the Jakarta RESTful Web Services Service Runtime service and the whiteboard application being targeted.

151.5.5 Jakarta RESTful Web Services Whiteboard Extension Lifecycle

Jakarta RESTful Web Services extensions have a different lifecycle from Jakarta RESTful Web Services resources, within a single application a Jakarta RESTful Web Services extension always behaves as a singleton. If a Jakarta RESTful Web Services whiteboard extension is registered as prototype scope then the whiteboard implementation must obtain a separate instance for every application to which the extension is applied. Whiteboard extension services must be released by the Jakarta RESTful Web Services whiteboard when the application with which they have been registered is removed from the whiteboard, even if this is only a temporary situation.

Jakarta RESTful Web Services extensions often require configuration, and need to be configured differently for different applications. This configuration is typically provided by a Jakarta RESTful Web Services ContextResolver and injected into fields of the extension by the Jakarta RESTful Web Services container. It is therefore highly recommended that Jakarta RESTful Web Services Whiteboard extensions are always registered as prototype scope, so that separate instances can be created for each whiteboard application.

If an extension is registered as a singleton service then it should not rely on any fields being injected by the Jakarta RESTful Web Services Whiteboard implementation. Jakarta RESTful Web Services Whiteboard implementations may support field injection for singleton extensions, however this behavior is non portable, and may lead to errors at runtime when using other implementations.

151.5.6 Extension Service Properties

The following table describes the properties that can be used by Jakarta RESTful Web Services extensions registered as Whiteboard services. Additionally, the common properties listed in Table 151.2 on page are supported.

Table 151.4 Service properties for Jakarta RESTful Web Services Whiteboard extension services.

Service Property Type Description

osgi.jakartars.extension

JakartarsExtension

String / Boolean

required

Declares that this service must be processed by the Jakarta RESTful Web Services whiteboard when set to true. See JAKARTA_RS_EXTENSION.


151.5.7 A Jakarta RESTful Web Services Whiteboard Extension Example

The following example code uses Declarative Services annotations to register a require Jakarta RESTful Web Services Whiteboard extension which provides JSON support, and requires the extension from a Jakarta RESTful Web Services whiteboard resource.

@Component(property="serialize.to=JSON")
@JakartarsExtension
public class JsonProvider implements MessageBodyReader,
      MessageBodyWriter {
    ...      
}
 
 @Component(service = Object.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource
 @JakartarsExtensionSelect("(serialize.to=JSON)")
 public class MyResource {
  
     @GET
     @Path("hello")
     @Produces(MediaType.APPLICATION_JSON)
     public List<String> getList(){
          return Arrays.asList("Hello", "World!");
     }
 }

151.6 Registering RESTful Web Service Applications

The Jakarta RESTful Web Services specification defines the concept of an Application. An application is an object which collects together one or more Jakarta RESTful Web Services resources and extensions, and provides them to the Jakarta RESTful Web Services container. These resources may be provided as pre-instantiated singletons, or as Class objects to be reflectively instantiated.

The OSGi Jakarta RESTful Web Services whiteboard supports direct registration of Applications for two reasons:

  • To support the use of legacy Jakarta RESTful Web Services applications with the whiteboard

  • To provide simple scoping of Jakarta RESTful Web Services resources and extensions within a whiteboard, in this scenario it can be desirable to register an otherwise empty Application. This application can then be targeted by whiteboard services using the osgi.jakartars.application.select property.

Applications can be registered with the Jakarta RESTful Web Services Whiteboard by registering them as Whiteboard services which advertise themselves using the Jakarta RESTful Web Services Application type. In addition the whiteboard services must provide a osgi.jakartars.application.base property. The value of this property is the URI path relative to the root whiteboard context at which the application will be registered. Note that the value of any ApplicationPath annotation will be applied by the container in addition to the osgi.jakartars.application.base.

Each registered Whiteboard Application service is provided as a separate application within the whiteboard, and is isolated from other applications, including the default application. Whiteboard applications may be empty, may include zero or more static resources, and may include zero or more static extensions.

151.6.1 Application shadowing

The base URI for each application within the whiteboard must be unique. If two or more applications targeting the same whiteboard are registered with the same base URI then only the first in ranking order, as specified in ServiceReference.compareTo, will be made available. All other application services with that URI will have a failure DTO created for them. The same rules also apply to the osgi.jakartars.name property, with the highest ranked service shadowing other applications with the same name.

The default application is implicitly created by the whiteboard and has the name .default. The default application has a lower ranking than all registered services. Therefore an application registered with a base of / will shadow a default application bound at /.

A whiteboard application service may set an osgi.jakartars.name of .default to replace the default application. This technique may be used to rebind the default application to a base uri other than /.

If a whiteboard application fails (for example if the service get fails), or cannot be immediately deployed (for example if it has an unsatisfied osgi.jakartars.extension.select) then any applications that it shadows are still shadowed and relevant failure DTOs are created for all of the applications.

151.6.2 Application Extension Dependencies

It is possible for an application to require additional whiteboard extensions before it is eligible to be hosted by the whiteboard. When making this determination the Whiteboard implementation must perform a dry-run validation of the osgi.jakartars.extension.select filter, applying all of the whiteboard extensions targeted to the application before determining whether the application's requirements are met.

151.6.3 Application Service Properties

The following table describes the properties that can be used by Jakarta RESTful Web Services applications registered as Whiteboard services. Additionally, the common properties listed in Table 151.2 on page are supported, except for the osgi.jakartars.application.select property.

Table 151.5 Service properties for Jakarta RESTful Web Services Whiteboard application services.

Service Property Type Description

osgi.jakartars.application.base

JakartarsApplicationBase

String

required

Declares that this service must be processed by the Jakarta RESTful Web Services whiteboard, and defines the URI, relative to the root context of the whiteboard, at which the Application should be registered. See JAKARTA_RS_APPLICATION_BASE.


151.6.4 Accessing the Application service properties

In Jakarta RESTful Web Services the @Context annotation may be used to inject the Application instance into a resource or extension. Application configuration properties can also be injected using the Configuration type.

When using the Jakarta RESTful Web Services Whiteboard it can also be necessary to access the service properties associated with the application hosting the resource, for example to allow customization of the resource's response. To this end, the Jakarta RESTful Web Services whiteboard implementation must make the Application service properties available as a Map in the configuration. The key used to store this map is osgi.jakartars.application.serviceProperties, and it can be found in any injected Configuration instance.

Furthermore, for Feature and DynamicFeature extensions the application service properties must be visible in the FeatureContext passed to the extension when applying it to the application. The FeatureContext interface provides programmatic access to the Configuration for the application, so this visibility is achieved in the same manner as for an injected Configuration instance.

In the case where the hosting application is not an OSGi service, for example a Whiteboard implementation may choose to provide its default application as an internal detail, then the osgi.jakartars.application.serviceProperties map must exist containing the osgi.jakartars.name of the application and the service properties associated with the JakartarsServiceRuntime service.

151.6.5 A Jakarta RESTful Web Services Whiteboard Application Example

The following example code uses Declarative Services annotations to register a Jakarta RESTful Web Services Whiteboard application, and shows how to target an additional whiteboard resource to that application.

@Component(service=Application.class)
@JakartarsApplicationBase("example")
@JakartarsName("myApp")
public class MyApplication extends Application {
    public Set<Class<?>> getClasses() {
        return new HashSet<>(Arrays.asList(StaticResource.class));
    }      
}
 
 @Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource
 @JakartarsApplicationSelect("(osgi.jakartars.name=myApp)")
 public class MyResource {
  
     @GET
     @Path("hello")
     @Produces("text/plain")
     public List<String> getList(){
          return Arrays.asList("Hello", "World!");
     }
 }

The MyResource service will be available at http://www.acme.com/example/hello

151.7 Whiteboard Error Handling

There are a number of error cases where the Jakarta RESTful Web Services whiteboard may be unable to correctly register a resource. All of these cases must result in a failure DTO being created with the appropriate error code.

  • Failure to obtain a service instance - In the case where a published service is unable to be obtained by the Jakarta RESTful Web Services whiteboard then the service is deny listed by the container. A failure DTO is made available from the JakartarsServiceRuntime representing the deny listed service object.

  • Invalid service objects - Jakarta RESTful Web Services extension and Application objects are required to advertise certain interfaces, or to extend certain types. If a service advertises itself using a Jakarta RESTful Web Services whiteboard service property, but fails to advertise an appropriate Jakarta RESTful Web Services type, or fails to provide any resource methods then this is an error and the service must be deny listed by the container. A failure DTO is available from the JakartarsServiceRuntime representing the deny listed service object.

  • Overlapping Application mappings - As with resources in a single application it is possible that two Jakarta RESTful Web Services resources will register for the same path across applications. In this case the application with the longer base URI is shadowed, and a failure DTO is available from the JakartarsServiceRuntime representing the shadowed Application. Note that determining when two Jakarta RESTful Web Services applications overlap requires an analysis of the resource paths and all of sub-resource paths. If any of these paths clash then the entirety of the shadowed application must be unregistered and marked as a failure. It is an implementation error for some application resource paths to be available while others are shadowed.

  • Class-Space Compatibility - Much of the Jakarta RESTful Web Services mapping definition is handled using annotations with runtime visibility. As Jakarta RESTful Web Services beans are POJOs there is no guarantee of class-space compatibility when the Jakarta RESTful Web Services implementation searches for whiteboard services. The Jakarta RESTful Web Services whiteboard must therefore confirm that the registered service shares the correct view of the Jakarta RESTful Web Services packages. If the class space is not consistent then the Jakarta RESTful Web Services whiteboard container must not register the services, but instead should create a failure DTO indicating that the Jakarta RESTful Web Services object is unable to be registered due to an incompatible class-space.

  • Missing Required Extensions - If a Jakarta RESTful Web Services resource or extension requires one or more extensions using a osgi.jakartars.extension.select filter then at any given time it is possible that the Jakarta RESTful Web Services container will not be able to host the resource. At this time a failure DTO must be created for the relevant resource or extension service.

151.8 The Jakarta RESTful Web Services Client API

The Jakarta RESTful Web Services specification includes a client API for making REST requests. The normal mechanism for obtaining a Client is to use a ClientBuilder, which is instantiated using a static factory method. Static factory methods require the reflective loading of classes and suffer from significant lifecycle issues, as there is no way to force indirectly wired objects to be discarded if the implementation bundle is stopped or uninstalled.

Jakarta RESTful Web Services implementations must therefore register their ClientBuilder implementations as OSGi services for bundles to use in making Client instances. The ClientBuilder must be registered as a prototype scoped service. This allows bundles to configure multiple separate Client instances, and ensures that separate bundles will never accidentally provide conflicting configuration to the same ClientBuilder instance.

151.8.1 Client Filters, Interceptors, Readers and Writers

While Container extensions can be made available using whiteboard services, the same is not true for Clients. There are two main reasons for this:

  1. There is no simple way to scope the filters and interceptors that would be applied to a given client. In a multi-tenant environment this could lead to unexpected behaviors.

  2. Clients are not, in general, expected to be extended by third parties. The Client model is designed to be used by a bundle when making requests from a REST API. If further requests need to be made by a different bundle then it should create and configure a separate client. This is different from the whiteboard server, where one container port may host several distinct sets of resources.

In order to add filters, interceptors, readers and writers to the Jakarta RESTful Web Services client users should use the ClientBuilder#register() method when building their client.

151.8.2 Reactive Clients

The Jakarta RESTful Web Services client API supports both synchronous and asynchronous calls. In Jakarta RESTful Web Services 2.1 the asynchronous behavior of the client was extended using the RxInvoker (reactive invoker) interface. All clients are required to support a reactive invoker which returns CompletionStage instances, however in OSGi the common representation of an asynchronous return is the Promise. This specification therefore provides the PromiseRxInvoker interface which can be used to obtain Promises from the Jakarta RESTful Web Services client.

It is the responsibility of the Jakarta RESTful Web Services whiteboard implementation to create instances of PromiseRxInvoker. The exact mechanism by which instances are created is undefined, however it is possible to register a portable factory to create PromiseRxInvoker instances by implementing the RxInvokerProvider interface and registering this type with the Jakarta RESTful Web Services client. This portable implementation, however, is forced to use a blocking model by the underlying Jakarta RESTful Web Services API, and so implementations may choose to implement a more optimized non-blocking model using internal types.

Clients of this specification may make use of the PromiseRxInvoker using normal Jakarta RESTful Web Services idioms. For example:

Client client = clientBuilder.build();
Promise<String> p = client.target(REST_SERVICE_URL)
    .path("/foo")
    .path("/{name}")
    .resolveTemplate("name", buzz)
    .request()
    .rx(PromiseRxInvoker.class)
    .get(String.class);

151.8.3 Consuming Server Sent Events

In Jakarta RESTful Web Services 2.1 support was added for Server Sent Events. These events are consumed by a REST client using the SseEventSource. The SseEventSource is not created by a Jakarta RESTful Web Services client instance, but is normally created using a static factory method, which does not work in a modular environment. Therefore the Jakarta RESTful Web Services whiteboard implementation must register a SseEventSourceFactory service in the service registry. This object serves as a factory for the Jakarta RESTful Web Services SSE types.

Note that the SseEventSource has no way to register filters or message body processors. All of the filters and necessary processors must be registered with the Jakarta RESTful Web Services client that is used to create the WebTarget used when building the SseEventSource. A client may therefore consume Server Sent Events in the following way:

Client client = clientBuilder.build();

WebTarget target = client.target(REST_SERVICE_URL)
    .path("/foo")
    .path("/{name}")
    .resolveTemplate("name", buzz);

SseEventSource source = sseFactory.newSource(target);
    
source.register(event -> doSomething(event));
    
source.open();

A SseEventSource may easily be converted into a PushEventSource (and consequently a PushStream) as follows. Note that the implementation does not respond to back-pressure requests and should typically be used with a buffer.

SseEventSource source = sseBuilder.newSource(target);
    
PushEventSource<InboundSseEvent> pes = pec ->
        source.register(e -> {
                                try {
                                    if(pec.accept(PushEvent.data(e)) < 0) {
                                        source.close();
                                    }
                                } catch (Exception e) {
                                    try {
                                        pec.accept(PushEvent.error(e));
                                    } finally {
                                        source.close();
                                    } 
                                }
                            },
                        t -> pec.accept(PushEvent.error(t)),
                        () -> pec.accept(PushEvent.close()));
        source.open();
        return source;
    };

151.9 Portability and Interoperability

The extensions defined by the Jakarta RESTful Web Services specification make Jakarta RESTful Web Services runtimes highly plugable, and it is common to extend the behavior of an application using this model. In many cases the custom behaviors are specific to a particular use case, for example mapping a specific exception into a Response, and there is no need for portability. In some common cases, however, there are extensions that can be used across a great many applications.

In order to ensure that a Jakarta RESTful Web Services whiteboard application can make use of a common extension service in a portable way this specification defines standard service property names that should be registered, as appropriate, by whiteboard extension services, whiteboard applications with static extensions, and Jakarta RESTful Web Services whiteboard implementations that provide built-in extension capabilities.

151.9.1 Media Type support

A common use of the Jakarta RESTful Web Services extension mechanism is to provide support for additional media types, both for consuming incoming requests and for producing responses. All Jakarta RESTful Web Services whiteboards must implicitly support text/plain and application/xml (using JAXB), however commonly used media types, such as application/json must be provided as an extension.

To ensure that whiteboard resources can depend on support for a particular media type in a portable way this specification defines the osgi.jakartars.media.type property. This property key should be registered with one or more media types that are supported, and may be provided by:

  • A Whiteboard extension - if the extension provides general purpose support for reading from and writing to a media type then it should register this property.

  • A Whiteboard application - if the application provides general purpose support for reading from and writing to a media type using a static extension then it should register this property.

  • A Jakarta RESTful Web Services Whiteboard implementation - if the implementation provides general purpose built-in support for reading from and writing to a media type then it should register this property. If the built-in extension is always available then it should also be advertised by the osgi.service Capability for the JakartarsServiceRuntime.

The term general purpose is used to indicate that the media type support must not require implementation specific mapping metadata (for example annotations) and should, at a minimum, work with the OSGi scalar types and DTOs. The property key is available as a constant in JAKARTA_RS_MEDIA_TYPE.

151.9.1.1 Media Type names, wildcards and suffixes

Where possible the value(s) of the osgi.jakartars.media.type property should use the IANA registered names of the media type(s) supported, for example application/json. Officially registered media types are available from [4] IANA Media Type Registrations. If there is no officially registered media type then a vendor type should be used. Personal types may also be used, however due to the lack of portability afforded by personal types it is recommended that a non-standard property key is used for personal types.

Wildcard types (containing a *) are often used by extensions to indicate that they can create a variety of different media types. Rarely this is because the extension can serialize into multiple different formats. More typically this is because the extension can serialize into a format which has multiple names, or multiple formats which use the same basic serialization. Suffixes can further modify this behavior, for example VCards may be serialized as XML using application/vcard+xml or as JSON using application/vcard+json.

Wildcard types must not be used as values for the osgi.jakartars.media.type property as these do not provide sufficient information for whiteboard resources to reliably select a media type provider. Where a provider wishes to advertise support for a general suffix, for example +json or +cbor then the provider must advertise the primary media type associated with the suffix; in the supplied example these would be application/json and application/cbor. Clients wishing to use suffixed types should therefore also depend on the primary media type, not the suffixed type, if they wish to be portable. Where greater specificity is required it is recommended that the extension be selected based on additional custom properties. This should also be used for suffixes that have no primary type, for example +der. Official media type registrations are available from [5] IANA Media Type Suffix Registrations

151.9.1.2 Media Type Selection Example

The most commonly required media type for Jakarta RESTful Web Services services is application/json. To this end this specification defines a Component Property annotation JSONRequired which can be applied to a Declarative Services component to express:

  • An extension requirement for runtime application/json media type support

  • A requirement for the Jakarta RESTful Web Services whiteboard

  • An optional active time requirement for application/json media type support, for use in application resolution/assembly.

Custom third-party annotations can easily be created to support additional media types as necessary, and are used as follows:

@Component(service = MyResource.class,
      scope = ServiceScope.PROTOTYPE)
 @JakartarsResource
 @JSONRequired
 @Produces(MediaType.APPLICATION_JSON)  
 public class MyResource {
  
    @Path(“foo”)
    @GET
    public List<String> getFoos() {
        return Arrays.asList("foo", "bar", "baz");
    }
}

A corresponding component property type (JakartarsMediaType) exists for use on a Jakarta RESTful Web Services whiteboard extension or application service which provides media type support. This can be used to declare that one or more media types are supported.

@Component(scope = ServiceScope.PROTOTYPE)
 @JakartarsExtension
 @JakartarsMediaType(MediaType.APPLICATION_JSON)
 public class MyFeature implements Feature {
  
    public boolean configure(FeatureContext context) {
    		context.register(MyJSONCodec.class);
        return true;
    }
}

151.10 Capabilities

151.10.1 osgi.implementation Capability

The Jakarta RESTful Web Services Whiteboard implementation bundle must provide the osgi.implementation capability with name osgi.jakartars. This capability can be used by provisioning tools and during resolution to ensure that a Jakarta RESTful Web Services Whiteboard implementation is present to process the Whiteboard services defined in this specification. The capability must also declare a uses constraint for the jakarta.ws.rs.* specification packages, and for the and OSGi Jakarta RESTful Web Services Whiteboard package. The version of this capability must match the version of this specification:

Provide-Capability: osgi.implementation;
       osgi.implementation="osgi.jakartars";
       uses:="jakarta.ws.rs, jakarta.ws.rs.client, jakarta.ws.rs.container,
              jakarta.ws.rs.core, jakarta.ws.rs.ext, jakarta.ws.rs.sse, 
              org.osgi.service.jakartars.whiteboard";
       version:Version="2.0"

This capability must follow the rules defined for the osgi.implementation Namespace.

151.10.2 osgi.contract Capability

The Jakarta RESTful Web Services Whiteboard implementation must provide a capability in the osgi.contract namespace with the name JakartaRESTfulWebServices if it exports the Jakarta RESTful Web Services specification packages. See [5] Portable Java Contract Definitions.

Providing the osgi.contract capability enables developer to build portable bundles for packages that are not versioned under OSGi Semantic Versioning rules. For more details see osgi.contract Namespace.

If the Jakarta RESTful Web Services API is provided by another bundle, the Jakarta RESTful Web Services Whiteboard implementation must be a consumer of the API and require the contract.

151.10.3 osgi.service Capability

The bundle providing the JakartarsServiceRuntime service must provide a capability in the osgi.service namespace representing this service. This capability must also declare a uses constraint for the org.osgi.service.jakartars.runtime and org.osgi.service.jakartars.runtime.dto packages:

Provide-Capability: osgi.service;
  objectClass:List<String>=
    "org.osgi.service.jakartars.runtime.JakartarsServiceRuntime";
  uses:="org.osgi.service.jakartars.runtime,
         org.osgi.service.jakartars.runtime.dto"

The bundle providing the jakarta.ws.rs.client.ClientBuilder service must also provide a capability in the osgi.service namespace representing this service. This capability must declare that the service is prototype scope, and that there is a uses constraint for the jakarta.ws.rs.client package:

Provide-Capability: osgi.service;
  objectClass:List<String>="jakarta.ws.rs.client.ClientBuilder";
  uses:="jakarta.ws.rs.client,org.osgi.service.jakartars.client";
  service.scope="prototype"

The bundle providing the org.osgi.service.jakartars.client.SseEventSourceFactory service must also provide a capability in the osgi.service namespace representing this service. This capability must declare a uses constraint for the org.osgi.service.jakartars.client package:

Provide-Capability: osgi.service;
  objectClass:List<String>=
    "org.osgi.service.jakartars.client.SseEventSourceFactory";
  uses:="org.osgi.service.jakartars.client"

These capabilities must follow the rules defined for the osgi.service Namespace.

151.11 Security

This section only applies when executing in an OSGi environment which is enforcing Java permissions.

151.11.1 Service Permissions

Bundles that need to register Jakarta RESTful Web Services Whiteboard services must be granted ServicePermission[interfaceName, REGISTER] where interface name is the relevant Jakarta RESTful Web Services Whiteboard service interface name.

The Http Whiteboard implementation must be granted ServicePermission[*, GET] to retrieve the Jakarta RESTful Web Services Whiteboard services from the service registry.

151.11.2 Runtime Introspection

Bundles that need to introspect the state of the Jakarta RESTful Web Services runtime will need ServicePermission[org.osgi.service.jakartars.runtime.JakartarsServiceRuntime, GET] to obtain the Jakarta RESTful Web Services Service Runtime service and access the DTO types.

151.11.3 Calling Jakarta RESTful Web Services Whiteboard Services

This specification does not require that the Jakarta RESTful Web Services Whiteboard implementation is granted All Permission or wraps calls to the Jakarta RESTful Web Services Whiteboard services in a doPrivileged block. Therefore, it is the responsibility of the Jakarta RESTful Web Services Whiteboard services to use a doPrivileged block when performing privileged operations.

151.12 org.osgi.service.jakartars.client

Version 2.0

Jakarta RESTful Web Services Whiteboard Client Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.jakartars.client; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.jakartars.client; version="[1.0,1.1)"

151.12.1 Summary

151.12.2 public interface PromiseRxInvoker
extends RxInvoker<Promise>

A specialization of the RxInvoker which creates Promise instances.

Bundles may obtain an instance of a PromiseRxInvoker using a ClientBuilder obtained from the service registry and calling the jakarta.ws.rs.client.Invocation.Builder.rx(Class) method.

Consumers of this API must not implement this type

151.12.2.1 public Promise<Response> delete()

151.12.2.2 public Promise<R> delete(Class<R> arg0)

<R>

151.12.2.3 public Promise<R> delete(GenericType<R> arg0)

<R>

151.12.2.4 public Promise<Response> get()

151.12.2.5 public Promise<R> get(Class<R> arg0)

<R>

151.12.2.6 public Promise<R> get(GenericType<R> arg0)

<R>

151.12.2.7 public Promise<Response> head()

151.12.2.8 public Promise<R> method(String arg0, Class<R> arg1)

<R>

151.12.2.9 public Promise<R> method(String arg0, Entity<?> arg1, Class<R> arg2)

<R>

151.12.2.10 public Promise<R> method(String arg0, Entity<?> arg1, GenericType<R> arg2)

<R>

151.12.2.11 public Promise<Response> method(String arg0, Entity<?> arg1)

151.12.2.12 public Promise<R> method(String arg0, GenericType<R> arg1)

<R>

151.12.2.13 public Promise<Response> method(String arg0)

151.12.2.14 public Promise<Response> options()

151.12.2.15 public Promise<R> options(Class<R> arg0)

<R>

151.12.2.16 public Promise<R> options(GenericType<R> arg0)

<R>

151.12.2.17 public Promise<R> post(Entity<?> arg0, Class<R> arg1)

<R>

151.12.2.18 public Promise<R> post(Entity<?> arg0, GenericType<R> arg1)

<R>

151.12.2.19 public Promise<Response> post(Entity<?> arg0)

151.12.2.20 public Promise<R> put(Entity<?> arg0, Class<R> arg1)

<R>

151.12.2.21 public Promise<R> put(Entity<?> arg0, GenericType<R> arg1)

<R>

151.12.2.22 public Promise<Response> put(Entity<?> arg0)

151.12.2.23 public Promise<Response> trace()

151.12.2.24 public Promise<R> trace(Class<R> arg0)

<R>

151.12.2.25 public Promise<R> trace(GenericType<R> arg0)

<R>

151.12.3 public interface SseEventSourceFactory

A factory for SseEventSource instances.

Bundles may obtain an instance of a SseEventSourceFactory using the service registry. This service may then be used to construct SseEventSource instances for the supplied WebTarget.

Consumers of this API must not implement this type

151.12.3.1 public SseEventSource.Builder newBuilder(WebTarget target)

The web target to consume events from

Create a new jakarta.ws.rs.sse.SseEventSource.Builder

a builder which can be used to further configure the event source

151.12.3.2 public SseEventSource newSource(WebTarget target)

The web target to consume events from

Create a new SseEventSource

a configured event source

151.13 org.osgi.service.jakartars.runtime

Version 2.0

Jakarta RESTful Web Services Runtime Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.jakartars.runtime; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.jakartars.runtime; version="[1.0,1.1)"

151.13.1 Summary

151.13.2 public interface JakartarsServiceRuntime

The JakartarsServiceRuntime service represents the runtime information of a Jakarta RESTful Web Services Whiteboard implementation.

It provides access to DTOs representing the current state of the service.

The JakartarsServiceRuntime service must be registered with the JakartarsServiceRuntimeConstants.JAKARTA_RS_SERVICE_ENDPOINT service property.

Thread-safe

Consumers of this API must not implement this type

151.13.2.1 public RuntimeDTO getRuntimeDTO()

Return the runtime DTO representing the current state.

The runtime DTO.

151.13.3 public final class JakartarsServiceRuntimeConstants

Defines standard names for Jakarta RESTful Web Services Runtime Service constants.

151.13.3.1 public static final String JAKARTA_RS_SERVICE_ENDPOINT = "osgi.jakartars.endpoint"

Jakarta RESTful Web Services Runtime Service service property specifying the endpoints upon which the Jakarta RESTful Web Services implementation is available.

An endpoint value is a URL or a relative path, to which the Jakarta RESTful Web Services Whiteboard implementation is listening. For example, http://192.168.1.10:8080/ or /myapp/. A relative path may be used if the scheme and authority parts of the URL are not known, e.g. if a bridged Http Whiteboard implementation is used. If the Jakarta RESTful Web Services Whiteboard implementation is serving the root context and neither scheme nor authority is known, the value of the property is "/". Both, a URL and a relative path, must end with a slash.

A Jakarta RESTful Web Services Whiteboard implementation can be listening on multiple endpoints.

The value of this service property must be of type String, String[], or Collection<String>.

151.14 org.osgi.service.jakartars.runtime.dto

Version 2.0

Jakarta RESTful Web Services Runtime DTO Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.jakartars.runtime.dto; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.jakartars.runtime.dto; version="[1.0,1.1)"

151.14.1 Summary

  • ApplicationDTO - Represents a Jakarta RESTful Web Services Application service.

  • BaseApplicationDTO - Represents common information about a Jakarta RESTful Web Services application service.

  • BaseDTO - Represents common information about a Jakarta RESTful Web Services service.

  • BaseExtensionDTO - Represents common information about a Jakarta RESTful Web Services extension service.

  • DTOConstants - Defines standard constants for the DTOs.

  • ExtensionDTO - Represents a Jakarta RESTful Web Services Extension service currently being hosted by the JakartarsServiceRuntime

  • FailedApplicationDTO - Represents a Jakarta RESTful Web Services service which is currently not being used due to a problem.

  • FailedExtensionDTO - Represents a Jakarta RESTful Web Services Extension service which is currently not being used due to a problem.

  • FailedResourceDTO - Represents a Jakarta RESTful Web Services resource service which is currently not being used due to a problem.

  • ResourceDTO - Represents common information about a Jakarta RESTful Web Services resource service.

  • ResourceMethodInfoDTO - Represents information about a Jakarta RESTful Web Services resource method.

  • RuntimeDTO - Represents the state of a Jakarta RESTful Web Services Service Runtime.

151.14.2 public class ApplicationDTO
extends BaseApplicationDTO

Represents a Jakarta RESTful Web Services Application service.

Not Thread-safe

151.14.2.1 public ResourceMethodInfoDTO[] resourceMethods

The RequestPaths handled by statically defined resources in this Application

151.14.2.2 public ApplicationDTO()

151.14.3 public abstract class BaseApplicationDTO
extends BaseDTO

Represents common information about a Jakarta RESTful Web Services application service.

Not Thread-safe

151.14.3.1 public String base

The base URI of the resource defined by JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_BASE.

151.14.3.2 public ExtensionDTO[] extensionDTOs

Returns the representations of the dynamic Jakarta RESTful Web Services extension services associated with this Application. The returned array may be empty if this application is currently not associated with any Jakarta RESTful Web Services extension services.

151.14.3.3 public ResourceDTO[] resourceDTOs

Returns the representations of the dynamic Jakarta RESTful Web Services resource services associated with this Application. The returned array may be empty if this application is currently not associated with any Jakarta RESTful Web Services Resource services.

151.14.3.4 public BaseApplicationDTO()

151.14.4 public abstract class BaseDTO
extends DTO

Represents common information about a Jakarta RESTful Web Services service.

Not Thread-safe

151.14.4.1 public String name

The name of the service if it set one using JakartarsWhiteboardConstants.JAKARTA_RS_NAME, otherwise this value will contain the generated name for this service

151.14.4.2 public long serviceId

Service property identifying the Jakarta RESTful Web Services service

151.14.4.3 public BaseDTO()

151.14.5 public abstract class BaseExtensionDTO
extends BaseDTO

Represents common information about a Jakarta RESTful Web Services extension service.

Not Thread-safe

151.14.5.1 public String[] extensionTypes

The extension types recognized for this service.

151.14.5.2 public BaseExtensionDTO()

151.14.6 public final class DTOConstants

Defines standard constants for the DTOs. The error codes are defined to take the same values as used by the Http Service Whiteboard

151.14.6.1 public static final int FAILURE_REASON_DUPLICATE_NAME = 6

The service is registered in the service registry with the JakartarsWhiteboardConstants.JAKARTA_RS_NAME property and a service with that name already exists in the runtime

151.14.6.2 public static final int FAILURE_REASON_NOT_AN_EXTENSION_TYPE = 4

The extension service is registered in the service registry but the service is not registered using a recognized extension type

151.14.6.3 public static final int FAILURE_REASON_REQUIRED_APPLICATION_UNAVAILABLE = 7

The service is registered in the service registry with the JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_SELECT property and the filters is not matched by any running application.

151.14.6.4 public static final int FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE = 5

The service is registered in the service registry with the JakartarsWhiteboardConstants.JAKARTA_RS_EXTENSION_SELECT property and one or more of the filters is not matched.

151.14.6.5 public static final int FAILURE_REASON_SERVICE_NOT_GETTABLE = 2

The service is registered in the service registry but getting the service fails as it returns null.

151.14.6.6 public static final int FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE = 1

Service is shadowed by another service.

For example, another service with the same service properties but having a higher service ranking. See org.osgi.framework.ServiceReference.compareTo(Object).

151.14.6.7 public static final int FAILURE_REASON_UNKNOWN = 0

Failure reason is unknown.

151.14.6.8 public static final int FAILURE_REASON_VALIDATION_FAILED = 3

The service is registered in the service registry but the service properties are invalid.

151.14.7 public class ExtensionDTO
extends BaseExtensionDTO

Represents a Jakarta RESTful Web Services Extension service currently being hosted by the JakartarsServiceRuntime

Not Thread-safe

151.14.7.1 public String[] consumes

The media types consumed by this service, if provided in an Consumes annotation

151.14.7.2 public ResourceDTO[] filteredByName

The resourceDTOs that are mapped to this extension using a NameBinding annotation

151.14.7.3 public String[] nameBindings

The full names of the NameBinding annotations applied to this extension, if any

151.14.7.4 public String[] produces

The media types produced by this service, if provided in an Produces annotation

151.14.7.5 public ExtensionDTO()

151.14.8 public class FailedApplicationDTO
extends BaseApplicationDTO

Represents a Jakarta RESTful Web Services service which is currently not being used due to a problem.

The service represented by this DTO is not used due to a failure, but the BaseApplicationDTO.extensionDTOs and BaseApplicationDTO.resourceDTOs may be non-empty if whiteboard services have been associated with this failed application.

Not Thread-safe

151.14.8.2 public FailedApplicationDTO()

151.14.9 public class FailedExtensionDTO
extends BaseExtensionDTO

Represents a Jakarta RESTful Web Services Extension service which is currently not being used due to a problem.

Not Thread-safe

151.14.9.2 public FailedExtensionDTO()

151.14.10 public class FailedResourceDTO
extends BaseDTO

Represents a Jakarta RESTful Web Services resource service which is currently not being used due to a problem.

Not Thread-safe

151.14.10.2 public FailedResourceDTO()

151.14.11 public class ResourceDTO
extends BaseDTO

Represents common information about a Jakarta RESTful Web Services resource service.

Not Thread-safe

151.14.11.1 public ResourceMethodInfoDTO[] resourceMethods

The RequestPaths handled by this resource

151.14.11.2 public ResourceDTO()

151.14.12 public class ResourceMethodInfoDTO
extends DTO

Represents information about a Jakarta RESTful Web Services resource method. All information is determined by reading the relevant annotations, from the Jakarta RESTful Web Services type and not interpreted further. Dynamic information, or information provided in other ways may not be represented in this DTO.

Not Thread-safe

151.14.12.1 public String[] consumingMimeType

The mime-type(s) consumed by this resource method, null if Consumes is not defined

151.14.12.2 public String method

The HTTP verb being handled, for example GET, DELETE, PUT, POST, HEAD, OPTIONS, null if no HttpMethod is defined

151.14.12.3 public String[] nameBindings

The NameBinding annotations that apply to this resource method, if any

151.14.12.4 public String path

The path of this resource method. Placeholder information present in the URI pattern will not be interpreted and simply returned as defined.

151.14.12.5 public String[] producingMimeType

The mime-type(s) produced by this resource method, null if Produces is not defined

151.14.12.6 public ResourceMethodInfoDTO()

151.14.13 public class RuntimeDTO
extends DTO

Represents the state of a Jakarta RESTful Web Services Service Runtime.

Not Thread-safe

151.14.13.1 public ApplicationDTO[] applicationDTOs

Returns the representations of the Jakarta RESTful Web Services Application services associated with this Runtime. The returned array may be empty if this whiteboard is currently not associated with any Jakarta RESTful Web Services application services.

151.14.13.2 public ApplicationDTO defaultApplication

Returns the current state of the default application for this Runtime.

151.14.13.3 public FailedApplicationDTO[] failedApplicationDTOs

Returns the representations of the Jakarta RESTful Web Services extension services targeted to this runtime but currently not used due to some problem. The returned array may be empty.

151.14.13.4 public FailedExtensionDTO[] failedExtensionDTOs

Returns the representations of the Jakarta RESTful Web Services extension services targeted to this runtime but currently not used due to some problem. The returned array may be empty.

151.14.13.5 public FailedResourceDTO[] failedResourceDTOs

Returns the representations of the Jakarta RESTful Web Services resource services targeted to this runtime but currently not used due to some problem. The returned array may be empty.

151.14.13.6 public ServiceReferenceDTO serviceDTO

The DTO for the corresponding JakartarsServiceRuntime. This value is never null.

151.14.13.7 public RuntimeDTO()

151.15 org.osgi.service.jakartars.whiteboard

Version 2.0

Jakarta RESTful Web Services Whiteboard Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.jakartars.whiteboard; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.jakartars.whiteboard; version="[1.0,1.1)"

151.15.1 Summary

151.15.2 public final class JakartarsWhiteboardConstants

Defines standard constants for the Jakarta RESTful Web Services Whiteboard services.

151.15.2.1 public static final String JAKARTA_RS_APPLICATION_BASE = "osgi.jakartars.application.base"

Service property specifying the base URI mapping for a Jakarta RESTful Web Services application service.

The specified uri is used to determine whether a request should be mapped to the resource. Services without this service property are ignored.

The value of this service property must be of type String, and will have a "/" prepended if no "/" exists.

If two applications are registered with the same base uri then the lower ranked service is failed with a cause of DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE

151.15.2.2 public static final String JAKARTA_RS_APPLICATION_SELECT = "osgi.jakartars.application.select"

Service property specifying the target application for a Jakarta RESTful Web Services resource or extension service.

The specified filter(s) is/are used to determine whether a resource should be included in a particular application. Services without this service property are bound to the default Application.

If a filter property is registered and no application running in the whiteboard matches the filter then the service will be failed with a cause of DTOConstants.FAILURE_REASON_REQUIRED_APPLICATION_UNAVAILABLE

The value of this service property must be of type String+, and each entry must be a valid OSGi filter.

151.15.2.3 public static final String JAKARTA_RS_APPLICATION_SERVICE_PROPERTIES = "osgi.jakartars.application.serviceProperties"

The property key which can be used to find the application service properties inside an injected Configuration

151.15.2.4 public static final String JAKARTA_RS_DEFAULT_APPLICATION = ".default"

The name of the default Jakarta RESTful Web Services application in every Whiteboard instance.

151.15.2.5 public static final String JAKARTA_RS_EXTENSION = "osgi.jakartars.extension"

Service property specifying that a Jakarta RESTful Web Services resource service should be processed by the whiteboard.

The value of this service property must be of type String or Boolean and set to "true" or true.

A service providing this property must be registered as one or more of the following types:

  • MessageBodyReader

  • MessageBodyWriter

  • ContainerRequestFilter

  • ContainerResponseFilter

  • ReaderInterceptor

  • WriterInterceptor

  • ContextResolver

  • ExceptionMapper

  • ParamConverterProvider

  • Feature

  • DynamicFeature

If a service with this property does not match any of the defined types then it is registered as a failure DTO with the error code DTOConstants.FAILURE_REASON_NOT_AN_EXTENSION_TYPE,

151.15.2.6 public static final String JAKARTA_RS_EXTENSION_SELECT = "osgi.jakartars.extension.select"

A Service property specifying one or more target filters used to select the set of Jakarta RESTful Web Services extension services required to support this whiteboard service.

A Jakarta RESTful Web Services Whiteboard service may require one or more extensions to be available so that it can function. For example a resource which declares that it @Produces("text/json") requires a MessageBodyWriter which supports JSON to be available.

This service property provides a String+ set of LDAP filters which will be applied to the service properties of all extensions available in the Jakarta RESTful Web Services container. If all of the filters are satisfied then this service is eligible to be hosted by the Jakarta RESTful Web Services container.

This service property may be declared by any Jakarta RESTful Web Services whiteboard service, whether it is a resource, or an extension.

If this service property is not specified, then no extensions are required.

If one or more filter properties are registered and no suitable extension(s) are available then the service will be failed with a cause of DTOConstants.FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE

The value of this service property must be of type String and be a valid filter string.

151.15.2.7 public static final String JAKARTA_RS_MEDIA_TYPE = "osgi.jakartars.media.type"

A service property specifying that a Jakarta RESTful Web Services extension service, application service, or whiteboard implementation provides support for reading from and writing to a specific media type.

The value of this property will be one or more media type identifiers, and where possible IANA registered names, such as application/json should be used. The value must not be a wildcard type. Support for multiple media types that use the same suffix should be supported by registering the media type associated with the suffix.

151.15.2.8 public static final String JAKARTA_RS_NAME = "osgi.jakartars.name"

Service property specifying the name of a Jakarta RESTful Web Services whiteboard service.

This name is provided as a property on the registered Endpoint service so that the URI for a particular Jakarta RESTful Web Services service can be identified. If this service property is not specified, then no Endpoint information will be registered for this resource.

Resource names must be unique among all services associated with a single Whiteboard implementation. If a clashing name is registered then the lower ranked service will be failed with a cause of DTOConstants.FAILURE_REASON_DUPLICATE_NAME

The value of this service property must be of type String.

151.15.2.9 public static final String JAKARTA_RS_RESOURCE = "osgi.jakartars.resource"

Service property specifying that a Jakarta RESTful Web Services resource should be processed by the whiteboard.

The value of this service property must be of type String or Boolean and set to "true" or true.

151.15.2.10 public static final String JAKARTA_RS_WHITEBOARD_IMPLEMENTATION = "osgi.jakartars"

The name of the implementation capability for the Whiteboard Specification for Jakarta RESTful Web Services.

151.15.2.11 public static final String JAKARTA_RS_WHITEBOARD_SPECIFICATION_VERSION = "2.0"

The version of the implementation capability for the Whiteboard Specification for Jakarta RESTful Web Services.

151.15.2.12 public static final String JAKARTA_RS_WHITEBOARD_TARGET = "osgi.jakartars.whiteboard.target"

Service property specifying the target filter to select the Jakarta RESTful Web Services Whiteboard implementation to process the service.

A Jakarta RESTful Web Services Whiteboard implementation can define any number of service properties which can be referenced by the target filter. The service properties should always include the osgi.jakartars.endpoint service property if the endpoint information is known.

If this service property is not specified, then all Jakarta RESTful Web Services Whiteboard implementations can process the service.

The value of this service property must be of type String and be a valid filter string.

151.16 org.osgi.service.jakartars.whiteboard.annotations

Version 2.0

Jakarta RESTful Web Services Whiteboard Annotations Package Version 1.0.

This package contains annotations that can be used to require the Jakarta RESTful Web Services Whiteboard implementation.

Bundles should not normally need to import this package as the annotations are only used at build-time.

151.16.1 Summary

151.16.2 @RequireJakartarsWhiteboard

This annotation can be used to require the Jakarta RESTful Web Services Whiteboard implementation. It can be used directly, or as a meta-annotation.

This annotation is applied to several of the Jakarta RESTful Web Services Whiteboard component property annotations meaning that it does not normally need to be applied to Declarative Services components which use the Jakarta RESTful Web Services Whiteboard.

CLASS

TYPE, PACKAGE

151.17 org.osgi.service.jakartars.whiteboard.propertytypes

Version 2.0

Jakarta RESTful Web Services Whiteboard Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.jakartars.whiteboard; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.jakartars.whiteboard; version="[1.0,1.1)"

151.17.1 Summary

151.17.2 @JakartarsApplicationBase

Component Property Type for the osgi.jakartars.application.base service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard application service to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_BASE service property.

Component Property Types

CLASS

TYPE

151.17.2.1 String value

Service property providing a base context URI for a Jakarta RESTful Web Services whiteboard application.

The base URI for this application.

JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_BASE

151.17.2.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.3 @JakartarsApplicationSelect

Component Property Type for the osgi.jakartars.application.select service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard resource or extension service to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_SELECT service property.

Component Property Types

CLASS

TYPE

151.17.3.1 String[] value

Service property providing a OSGi filter(s) identifying the application(s) to which this service should be bound.

The filter(s) for selecting the application(s) to bind to.

JakartarsWhiteboardConstants.JAKARTA_RS_APPLICATION_SELECT

151.17.3.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.4 @JakartarsExtension

Component Property Type for the osgi.jakartars.extension service property.

This annotation can be used on a Jakarta RESTful Web Services extension service to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_EXTENSION service property.

Component Property Types

CLASS

TYPE

151.17.4.1 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.5 @JakartarsExtensionSelect

Component Property Type for the osgi.jakartars.extension.select service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard resource or extension to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_EXTENSION_SELECT service property.

Component Property Types

CLASS

TYPE

151.17.5.1 String[] value

Service property providing one or more OSGi filters identifying the extension(s) or application features which this service requires to work.

The filters for selecting the extensions to require.

JakartarsWhiteboardConstants.JAKARTA_RS_EXTENSION_SELECT

151.17.5.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.6 @JakartarsMediaType

Component Property Type for the osgi.jakartars.media.type service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard extension or application to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_MEDIA_TYPE service property.

Component Property Types

CLASS

TYPE

151.17.6.1 String[] value

Service property identifying the name(s) of media types supported by this service.

The Jakarta RESTful Web Services media types supported.

JakartarsWhiteboardConstants.JAKARTA_RS_MEDIA_TYPE

151.17.6.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.7 @JakartarsName

Component Property Type for the osgi.jakartars.name service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard service to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_NAME service property.

Component Property Types

CLASS

TYPE

151.17.7.1 String value

Service property identifying the name of a Jakarta RESTful Web Services service for processing by the whiteboard.

The Jakarta RESTful Web Services whiteboard service name.

JakartarsWhiteboardConstants.JAKARTA_RS_NAME

151.17.7.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.8 @JakartarsResource

Component Property Type for the osgi.jakartars.resource service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard resource to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_RESOURCE service property.

Component Property Types

CLASS

TYPE

151.17.8.1 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.9 @JakartarsWhiteboardTarget

Component Property Type for the osgi.jakartars.whiteboard.target service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard resource or extension service to declare the value of the JakartarsWhiteboardConstants.JAKARTA_RS_WHITEBOARD_TARGET service property.

Component Property Types

CLASS

TYPE

151.17.9.1 String value

Service property providing an OSGi filter identifying the whiteboard(s) to which this service should be bound.

The filter for selecting the whiteboards to bind to.

JakartarsWhiteboardConstants.JAKARTA_RS_WHITEBOARD_TARGET

151.17.9.2 String PREFIX_ = "osgi."

Prefix for the property name. This value is prepended to each property name.

151.17.10 @JSONRequired

Component Property Type for requiring JSON media type support using the JakartarsWhiteboardConstants.JAKARTA_RS_MEDIA_TYPE service property.

This annotation can be used on a Jakarta RESTful Web Services whiteboard resource to declare require that JSON support is available before the resource becomes active. It also adds an optional Requirement for a service providing this media type to aid with provisioning.

Component Property Types

CLASS

TYPE

151.17.10.1 String osgi_jakartars_extension_select default "(osgi.jakartars.media.type=application/json)"

Provides an extension selection filter for an extension supporting the JSON media type

A filter requiring an osgi.jakartars.media.type of application/json

151.17.10.2 String FILTER = "(osgi.jakartars.media.type=application/json)"

A filter requiring an osgi.jakartars.media.type of application/json

151.19 Changes

  • This specification is providing the same functionality as its predecessor, [6] JAX-RS Service Whiteboard Specification, with the switch from the JAX-RS API to the Jakarta RESTful Web Services API.

    Due to the naming change numerous constants have been renamed, including the service properties used in the specification. This allows the old and new specifications to coexist in the same framework.

  • The Application Selection Filter property has changed from a single String to a String+, allowing multiple filters to be supplied.