Skip to content

Commit

Permalink
Support Jersey 3 and Jakarta EE 9/10 (#2919)
Browse files Browse the repository at this point in the history
Motivation:

Jersey, in its latest releases has adopted both Jakarta EE 9 and 10 which makes a break from the legacy JEE API.  This unfortunately makes any Jersey 3 application incompatible with any Jersey 2 application.  Widely-used frameworks like Spring have also adopted Jakarta EE 10.
In order for ServiceTalk to support those applications, it needs to offer Jersey 3-compatible modules that ServiceTalk applications can consume.

Modifications:

- Add module `servicetalk-data-jackson-jersey3-jakarta9` and `-jakarta10`;
- Add module `servicetalk-data-protobuf-jersey3-jakarta9` and `-jakarta10`;
- Add module `servicetalk-http-router-jersey3-jakarta9` and `-jakarta10`;
- Add module `servicetalk-http-router-jersey3-internal-jakarta9` and `-jakarta10`;
- Add module `servicetalk-http-security-jersey3-jakarta9` and `-jakarta10`;
- Update `build.gradle` in new modules to pull source from the original `-jersey` modules and replace the imports;
- Add Jersey and Jakarta EE dependency versions for both 9 and 10;
- Update related docs to describe how to use Jersey 3.0.x and 3.1.x

Result:

Applications can use the relevant new Jersey 3 modules to be compatible with Jakarta EE 9 and 10.
  • Loading branch information
blake-bauman authored May 14, 2024
1 parent e207cd2 commit a65238c
Show file tree
Hide file tree
Showing 35 changed files with 1,365 additions and 1 deletion.
18 changes: 17 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,30 @@ jsr305Version=3.0.2
log4jVersion=2.22.1
slf4jVersion=1.7.36

# Jersey 2
javaxActivationVersion=1.2.2
javaxJaxbApiVersion=2.3.3
javaxJaxbCoreVersion=2.3.0.1
javaxJaxbImplVersion=2.3.3

jaxRsVersion=2.1.6
jerseyVersion=2.37

#Jersey 3.0 - Jakarta EE 9
javaxActivationVersionEE9=2.0.1
javaxJaxbApiVersionEE9=3.0.1
javaxJaxbCoreVersionEE9=3.0.2
javaxJaxbImplVersionEE9=3.0.2
jaxRsVersionEE9=3.0.0
jersey3VersionEE9=3.0.13

#Jersey 3.1 - Jakarta EE 10
javaxActivationVersionEE10=2.1.3
javaxJaxbApiVersionEE10=4.0.2
javaxJaxbCoreVersionEE10=4.0.5
javaxJaxbImplVersionEE10=4.0.5
jaxRsVersionEE10=3.1.0
jersey3VersionEE10=3.1.6

reactiveStreamsVersion=1.0.4
jcToolsVersion=4.0.3
# backward compatible with jackson 2.9+, we do not depend on any new features from later versions.
Expand Down
1 change: 1 addition & 0 deletions servicetalk-data-jackson-jersey/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

apply plugin: "io.servicetalk.servicetalk-gradle-plugin-internal-library"

// Dependencies must remain consistent between servicetalk-data-jackson-jerseyX modules
dependencies {
api platform(project(":servicetalk-dependencies"))
testImplementation enforcedPlatform("org.glassfish.jersey:jersey-bom:$jerseyVersion")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ It is a replacement for `jersey-media-json-jackson` and allows avoiding the inpu
with out-of-the-box body readers and also allows accepting/returning `Single<Pojo>` and `Publisher<Pojo>`
from resource methods.

**Note:** If using Jersey 3.X, replace all imports containing `javax.ws` with `jakarta.ws`, and replace the dependency with:
* `servicetalk-data-jackson-jersey3-jakarta9` for Jersey 3.0.X
* `servicetalk-data-jackson-jersey3-jakarta10` for Jersey 3.1.X

CAUTION: This serializer can not currently be used with Server-Sent Events (SSE).

== Using a custom ObjectMapper
Expand Down
1 change: 1 addition & 0 deletions servicetalk-data-jackson-jersey3-jakarta10/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src
130 changes: 130 additions & 0 deletions servicetalk-data-jackson-jersey3-jakarta10/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright © 2018-2019, 2021-2022, 2024 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

apply plugin: "io.servicetalk.servicetalk-gradle-plugin-internal-library"

// Required version for module
def javaLanguageVersion = JavaVersion.VERSION_11

if (!JavaVersion.current().isCompatibleWith(javaLanguageVersion)) {
project.tasks.all { task -> task.enabled = false }
}

java {
sourceCompatibility = javaLanguageVersion
targetCompatibility = javaLanguageVersion
}

compileJava {
options.release = Integer.parseInt(javaLanguageVersion.getMajorVersion())
}

compileTestJava {
options.release = compileJava.options.release
}

checkstyleMain {
enabled false
}

checkstyleTest {
enabled false
}

spotbugsMain {
enabled false
}

spotbugsTest {
enabled false
}

task cleanSources(type: Delete) {
delete 'src'
}

task copySourcesForJersey3(type: Copy) {
dependsOn tasks.cleanSources
from '../servicetalk-data-jackson-jersey/src'
into 'src'
filter { line -> line.replaceAll('javax.ws.rs', 'jakarta.ws.rs') }
filter { line -> line.replaceAll('javax.inject', 'jakarta.inject') }

// Only modify specific javax.annotations. Some like javax.annotation.Nullable need to stay the same
filter { line -> line.replaceAll('javax.annotation.Priority', 'jakarta.annotation.Priority') }
}

tasks.processResources.dependsOn(copySourcesForJersey3)
tasks.sourcesJar.dependsOn(copySourcesForJersey3)
tasks.compileJava.dependsOn(copySourcesForJersey3)
tasks.processTestResources.dependsOn(copySourcesForJersey3)
tasks.compileTestJava.dependsOn(copySourcesForJersey3)

def actualJerseyVersion = "${jersey3VersionEE10}"
def actualJavaxActivationVersion = "${javaxActivationVersionEE10}"
def actualJavaxJaxbApiVersion = "${javaxJaxbApiVersionEE10}"
def actualJavaxJaxbCoreVersion = "${javaxJaxbCoreVersionEE10}"
def actualJavaxJaxbImplVersion = "${javaxJaxbImplVersionEE10}"
def actualJaxRsVersion = "${jaxRsVersionEE10}"

// Dependencies must remain consistent between servicetalk-data-jackson-jerseyX modules
dependencies {
api platform(project(":servicetalk-dependencies"))
api platform("org.glassfish.jersey:jersey-bom:${actualJerseyVersion}")
api "jakarta.activation:jakarta.activation-api:$actualJavaxActivationVersion"
api "org.glassfish.jaxb:jaxb-core:$actualJavaxJaxbCoreVersion"
api "jakarta.ws.rs:jakarta.ws.rs-api:$actualJaxRsVersion"
api "jakarta.xml.bind:jakarta.xml.bind-api:$actualJavaxJaxbApiVersion"
api "org.glassfish.jaxb:jaxb-runtime:$actualJavaxJaxbImplVersion"
testImplementation enforcedPlatform("org.glassfish.jersey:jersey-bom:$actualJerseyVersion")

testImplementation enforcedPlatform("org.junit:junit-bom:$junit5Version")

api project(":servicetalk-data-jackson")
api "jakarta.ws.rs:jakarta.ws.rs-api" // MediaType, Feature
api "org.glassfish.jersey.core:jersey-common" // AutoDiscoverable

implementation project(":servicetalk-annotations")
implementation project(":servicetalk-buffer-netty")
implementation project(":servicetalk-concurrent-api-internal")
implementation project(":servicetalk-concurrent-internal")
implementation project(":servicetalk-http-api")
implementation project(":servicetalk-http-router-jersey3-jakarta10")
implementation project(":servicetalk-http-router-jersey3-jakarta10-internal")
implementation project(":servicetalk-http-utils")
implementation project(":servicetalk-transport-netty")
implementation "com.google.code.findbugs:jsr305"
implementation "org.glassfish.jersey.core:jersey-server"
implementation "org.slf4j:slf4j-api"

testImplementation testFixtures(project(":servicetalk-concurrent-api"))
testImplementation testFixtures(project(":servicetalk-concurrent-internal"))
testImplementation testFixtures(project(":servicetalk-transport-netty-internal"))
testImplementation testFixtures(project(":servicetalk-http-router-jersey3-jakarta10"))
testImplementation project(":servicetalk-http-netty")
testImplementation project(":servicetalk-http-router-predicate")
testImplementation project(":servicetalk-test-resources")
testImplementation project(":servicetalk-transport-netty-internal")

testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testImplementation "org.junit.platform:junit-platform-suite-api:$junitPlatformVersion"
testImplementation "net.javacrumbs.json-unit:json-unit:$jsonUnitVersion"
testImplementation "org.glassfish.jersey.inject:jersey-hk2"
testImplementation "org.glassfish.jersey.media:jersey-media-sse"
testImplementation "org.hamcrest:hamcrest:$hamcrestVersion"
testImplementation "org.mockito:mockito-core:$mockitoCoreVersion"
}
1 change: 1 addition & 0 deletions servicetalk-data-jackson-jersey3-jakarta9/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src
130 changes: 130 additions & 0 deletions servicetalk-data-jackson-jersey3-jakarta9/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright © 2018-2019, 2021-2022, 2024 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

apply plugin: "io.servicetalk.servicetalk-gradle-plugin-internal-library"

// Required version for module
def javaLanguageVersion = JavaVersion.VERSION_11

if (!JavaVersion.current().isCompatibleWith(javaLanguageVersion)) {
project.tasks.all { task -> task.enabled = false }
}

java {
sourceCompatibility = javaLanguageVersion
targetCompatibility = javaLanguageVersion
}

compileJava {
options.release = Integer.parseInt(javaLanguageVersion.getMajorVersion())
}

compileTestJava {
options.release = compileJava.options.release
}

checkstyleMain {
enabled false
}

checkstyleTest {
enabled false
}

spotbugsMain {
enabled false
}

spotbugsTest {
enabled false
}

task cleanSources(type: Delete) {
delete 'src'
}

task copySourcesForJersey3(type: Copy) {
dependsOn tasks.cleanSources
from '../servicetalk-data-jackson-jersey/src'
into 'src'
filter { line -> line.replaceAll('javax.ws.rs', 'jakarta.ws.rs') }
filter { line -> line.replaceAll('javax.inject', 'jakarta.inject') }

// Only modify specific javax.annotations. Some like javax.annotation.Nullable need to stay the same
filter { line -> line.replaceAll('javax.annotation.Priority', 'jakarta.annotation.Priority') }
}

tasks.processResources.dependsOn(copySourcesForJersey3)
tasks.sourcesJar.dependsOn(copySourcesForJersey3)
tasks.compileJava.dependsOn(copySourcesForJersey3)
tasks.processTestResources.dependsOn(copySourcesForJersey3)
tasks.compileTestJava.dependsOn(copySourcesForJersey3)

def actualJerseyVersion = "${jersey3VersionEE9}"
def actualJavaxActivationVersion = "${javaxActivationVersionEE9}"
def actualJavaxJaxbApiVersion = "${javaxJaxbApiVersionEE9}"
def actualJavaxJaxbCoreVersion = "${javaxJaxbCoreVersionEE9}"
def actualJavaxJaxbImplVersion = "${javaxJaxbImplVersionEE9}"
def actualJaxRsVersion = "${jaxRsVersionEE9}"

// Dependencies must remain consistent between servicetalk-data-jackson-jerseyX modules
dependencies {
api platform(project(":servicetalk-dependencies"))
api platform("org.glassfish.jersey:jersey-bom:${actualJerseyVersion}")
api "jakarta.activation:jakarta.activation-api:$actualJavaxActivationVersion"
api "org.glassfish.jaxb:jaxb-core:$actualJavaxJaxbCoreVersion"
api "jakarta.ws.rs:jakarta.ws.rs-api:$actualJaxRsVersion"
api "jakarta.xml.bind:jakarta.xml.bind-api:$actualJavaxJaxbApiVersion"
api "org.glassfish.jaxb:jaxb-runtime:$actualJavaxJaxbImplVersion"
testImplementation enforcedPlatform("org.glassfish.jersey:jersey-bom:$actualJerseyVersion")

testImplementation enforcedPlatform("org.junit:junit-bom:$junit5Version")

api project(":servicetalk-data-jackson")
api "jakarta.ws.rs:jakarta.ws.rs-api" // MediaType, Feature
api "org.glassfish.jersey.core:jersey-common" // AutoDiscoverable

implementation project(":servicetalk-annotations")
implementation project(":servicetalk-buffer-netty")
implementation project(":servicetalk-concurrent-api-internal")
implementation project(":servicetalk-concurrent-internal")
implementation project(":servicetalk-http-api")
implementation project(":servicetalk-http-router-jersey3-jakarta9")
implementation project(":servicetalk-http-router-jersey3-jakarta9-internal")
implementation project(":servicetalk-http-utils")
implementation project(":servicetalk-transport-netty")
implementation "com.google.code.findbugs:jsr305"
implementation "org.glassfish.jersey.core:jersey-server"
implementation "org.slf4j:slf4j-api"

testImplementation testFixtures(project(":servicetalk-concurrent-api"))
testImplementation testFixtures(project(":servicetalk-concurrent-internal"))
testImplementation testFixtures(project(":servicetalk-transport-netty-internal"))
testImplementation testFixtures(project(":servicetalk-http-router-jersey3-jakarta9"))
testImplementation project(":servicetalk-http-netty")
testImplementation project(":servicetalk-http-router-predicate")
testImplementation project(":servicetalk-test-resources")
testImplementation project(":servicetalk-transport-netty-internal")

testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testImplementation "org.junit.platform:junit-platform-suite-api:$junitPlatformVersion"
testImplementation "net.javacrumbs.json-unit:json-unit:$jsonUnitVersion"
testImplementation "org.glassfish.jersey.inject:jersey-hk2"
testImplementation "org.glassfish.jersey.media:jersey-media-sse"
testImplementation "org.hamcrest:hamcrest:$hamcrestVersion"
testImplementation "org.mockito:mockito-core:$mockitoCoreVersion"
}
1 change: 1 addition & 0 deletions servicetalk-data-protobuf-jersey/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ buildscript {
apply plugin: "io.servicetalk.servicetalk-gradle-plugin-internal-library"
apply plugin: "com.google.protobuf"

// Dependencies must remain consistent between servicetalk-data-protobuf-jerseyX modules
dependencies {
api platform(project(":servicetalk-dependencies"))
testImplementation enforcedPlatform("org.glassfish.jersey:jersey-bom:$jerseyVersion")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ This module provides Protobuf serialization and deserialization for ServiceTalk
thee `InputStream` adaptation that kicks in with out-of-the-box body readers and also allows accepting/returning
`Single<MessageLite>` and `Publisher<MessageLite>` from resource methods.

**Note:** If using Jersey 3.X, replace all imports containing `javax.ws` with `jakarta.ws`, and replace the dependency with:
* `servicetalk-data-protobuf-jersey3-jakarta9` for Jersey 3.0.X
* `servicetalk-data-protobuf-jersey3-jakarta10` for Jersey 3.1.X

CAUTION: This serializer can not currently be used with Server-Sent Events (SSE).

== Single Item Encoding
Expand Down
1 change: 1 addition & 0 deletions servicetalk-data-protobuf-jersey3-jakarta10/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src
Loading

0 comments on commit a65238c

Please sign in to comment.