Merge remote-tracking branch 'origin/master' into origin/3.x
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/bom/pom.xml b/bom/pom.xml
index 1083d28..92404fc 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.eclipse.ee4j</groupId>
<artifactId>project</artifactId>
- <version>1.0.7</version>
+ <version>1.0.8</version>
<relativePath/>
</parent>
diff --git a/connectors/helidon-connector/pom.xml b/connectors/helidon-connector/pom.xml
index 0e06810..31b40cd 100644
--- a/connectors/helidon-connector/pom.xml
+++ b/connectors/helidon-connector/pom.xml
@@ -42,7 +42,7 @@
<dependency>
<groupId>io.helidon.jersey</groupId>
<artifactId>helidon-jersey-connector</artifactId>
- <version>3.0.0-M1</version>
+ <version>${helidon.jersey.connector.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/TransferEncodingParser.java b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/TransferEncodingParser.java
index d3b1d9f..0a3ede0 100644
--- a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/TransferEncodingParser.java
+++ b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/TransferEncodingParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -218,8 +218,9 @@
while (offset < limit) {
final byte b = input.get(offset);
- if (isSpaceOrTab(b) /*trailing spaces are not allowed by the spec, but some server put it there*/
- || b == HttpParserUtils.CR || b == HttpParserUtils.SEMI_COLON) {
+ if (isSpaceOrTab(b)
+ || /*trailing spaces are not allowed by the spec, but some server put it there*/
+ b == HttpParserUtils.CR || b == HttpParserUtils.SEMI_COLON) {
headerParsingState.checkpoint = offset;
} else if (b == HttpParserUtils.LF) {
contentParsingState.chunkContentStart = offset + 1;
diff --git a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS11Test.java b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS11Test.java
index 3d1ef6c..fc87b73 100644
--- a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS11Test.java
+++ b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS11Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS1Test.java b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS1Test.java
index a3a9237..a7293b5 100644
--- a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS1Test.java
+++ b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTLS1Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTest.java b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTest.java
index 7cef70b..5d205ce 100644
--- a/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTest.java
+++ b/connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/SslFilterTest.java
@@ -24,22 +24,29 @@
import java.net.ServerSocket;
import java.net.SocketException;
import java.nio.ByteBuffer;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-
import javax.net.ServerSocketFactory;
import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
-
import org.glassfish.jersey.SslConfigurator;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ConditionEvaluationResult;
+import org.junit.jupiter.api.extension.ExecutionCondition;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -48,6 +55,7 @@
/**
* @author Petr Janouch
*/
+@ExtendWith(SslFilterTest.DeprecatedTLSCondition.class)
public abstract class SslFilterTest {
private static final int PORT = 8321;
@@ -531,4 +539,32 @@
socket.startHandshake();
}
}
+
+ public static class DeprecatedTLSCondition implements ExecutionCondition {
+
+ @Override
+ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
+ Class<?> test = context.getTestClass().get();
+ String required = null;
+ if (test == SslFilterTLS1Test.class) {
+ required = "TLSv1";
+ } else if (test == SslFilterTLS11Test.class) {
+ required = "TLSv1.1";
+ }
+ if (required != null) {
+ try {
+ SSLContext context1 = SSLContext.getInstance("TLS");
+ context1.init(null, null, null);
+ List<String> supportedProtocols = Arrays.asList(context1.getDefaultSSLParameters().getProtocols());
+ if (!supportedProtocols.contains(required)) {
+ return ConditionEvaluationResult.disabled("JDK does not support " + required);
+ }
+ } catch (KeyManagementException | NoSuchAlgorithmException e) {
+ return ConditionEvaluationResult.disabled("JDK does not support TLS: " + e.getMessage());
+ }
+ }
+ return ConditionEvaluationResult.enabled("JDK is valid to run " + test.getCanonicalName());
+ }
+
+ }
}
diff --git a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
index 3aaf758..59b1da9 100644
--- a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
+++ b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -603,7 +603,11 @@
final String name = (String) parameterNames.nextElement();
final List<String> values = Arrays.asList(servletRequest.getParameterValues(name));
- formMap.put(name, keepQueryParams ? values : filterQueryParams(name, values, queryParams));
+ final List<String> filteredValues = keepQueryParams ? values : filterQueryParams(name, values, queryParams);
+
+ if (!filteredValues.isEmpty()) {
+ formMap.put(name, filteredValues);
+ }
}
if (!formMap.isEmpty()) {
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
index 183fd0f..df67cb5 100644
--- a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -238,13 +238,9 @@
}
- private URI getBaseUri(final Request request) {
- try {
- return new URI(request.getScheme(), null, request.getServerName(),
- request.getServerPort(), getBasePath(request), null, null);
- } catch (final URISyntaxException ex) {
- throw new IllegalArgumentException(ex);
- }
+ private URI getBaseUri(final Request request) throws URISyntaxException {
+ return new URI(request.getScheme(), null, request.getServerName(),
+ request.getServerPort(), getBasePath(request), null, null);
}
private String getBasePath(final Request request) {
diff --git a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
index 4d7c43e..7c4c760 100644
--- a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
+++ b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
@@ -66,6 +66,19 @@
}
@Test
+ public void test400StatusCodeForIllegalHeaderValue() throws IOException {
+ startServer(ExceptionResource.class);
+ URI testUri = getUri().build();
+ BasicHttpRequest request = new BasicHttpRequest("GET", testUri.toString() + "/400");
+ request.addHeader("X-Forwarded-Host", "_foo.com");
+ CloseableHttpClient client = HttpClientBuilder.create().build();
+
+ CloseableHttpResponse response = client.execute(new HttpHost(testUri.getHost(), testUri.getPort()), request);
+
+ assertEquals(400, response.getStatusLine().getStatusCode());
+ }
+
+ @Test
public void test400StatusCode() throws IOException {
startServer(ExceptionResource.class);
Client client = ClientBuilder.newClient();
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/JerseyCompletionStageRxInvokerTest.java b/core-client/src/test/java/org/glassfish/jersey/client/JerseyCompletionStageRxInvokerTest.java
index b55f9e8..d7643aa 100644
--- a/core-client/src/test/java/org/glassfish/jersey/client/JerseyCompletionStageRxInvokerTest.java
+++ b/core-client/src/test/java/org/glassfish/jersey/client/JerseyCompletionStageRxInvokerTest.java
@@ -111,7 +111,7 @@
@Test
public void testNotFoundReadEntityViaGenericType() throws Throwable {
- Assertions.assertThrows(NotFoundException.class, () ->{
+ Assertions.assertThrows(NotFoundException.class, () -> {
try {
client.target("http://jersey.java.net")
.request()
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
index 6a234e5..1548ef8 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Payara Foundation and/or its affiliates.
*
* This program and the accompanying materials are made available under the
@@ -280,11 +280,15 @@
} else {
final List<ClassTypePair> ctps = ReflectionHelper.getTypeArgumentAndClass(genericType);
final ClassTypePair ctp = (ctps.size() == 1) ? ctps.get(0) : null;
-
+ final boolean empty = value.isEmpty();
for (ParamConverterProvider provider : Providers.getProviders(manager, ParamConverterProvider.class)) {
final ParamConverter<?> converter = provider.getConverter(ctp.rawClass(), ctp.type(), annotations);
if (converter != null) {
- return (T) Optional.of(value).map(s -> converter.fromString(value));
+ if (empty) {
+ return (T) Optional.empty();
+ } else {
+ return (T) Optional.of(value).map(s -> converter.fromString(value));
+ }
}
}
/*
@@ -323,7 +327,7 @@
@Override
public T fromString(String value) {
- if (value == null) {
+ if (value == null || value.isEmpty()) {
return (T) optionals.empty();
} else {
return (T) optionals.of(value);
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/GuardianStringKeyMultivaluedMap.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/GuardianStringKeyMultivaluedMap.java
new file mode 100644
index 0000000..d92ac56
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/GuardianStringKeyMultivaluedMap.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.util.collection;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The {@link MultivaluedMap} wrapper that is able to set guards observing changes of values represented by a key.
+ * @param <V> The value type of the wrapped {@code MultivaluedMap}.
+ *
+ * @since 2.38
+ */
+public class GuardianStringKeyMultivaluedMap<V> implements MultivaluedMap<String, V> {
+
+ private final MultivaluedMap<String, V> inner;
+ private final Map<String, Boolean> guards = new HashMap<>();
+
+ public GuardianStringKeyMultivaluedMap(MultivaluedMap<String, V> inner) {
+ this.inner = inner;
+ }
+
+ @Override
+ public void putSingle(String key, V value) {
+ observe(key);
+ inner.putSingle(key, value);
+ }
+
+ @Override
+ public void add(String key, V value) {
+ observe(key);
+ inner.add(key, value);
+ }
+
+ @Override
+ public V getFirst(String key) {
+ return inner.getFirst(key);
+ }
+
+ @Override
+ public void addAll(String key, V... newValues) {
+ observe(key);
+ inner.addAll(key, newValues);
+ }
+
+ @Override
+ public void addAll(String key, List<V> valueList) {
+ observe(key);
+ inner.addAll(key, valueList);
+ }
+
+ @Override
+ public void addFirst(String key, V value) {
+ observe(key);
+ inner.addFirst(key, value);
+ }
+
+ @Override
+ public boolean equalsIgnoreValueOrder(MultivaluedMap<String, V> otherMap) {
+ return inner.equalsIgnoreValueOrder(otherMap);
+ }
+
+ @Override
+ public int size() {
+ return inner.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return inner.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return inner.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return inner.containsValue(value);
+ }
+
+ @Override
+ public List<V> get(Object key) {
+ return inner.get(key);
+ }
+
+ @Override
+ public List<V> put(String key, List<V> value) {
+ observe(key);
+ return inner.put(key, value);
+ }
+
+ @Override
+ public List<V> remove(Object key) {
+ if (key != null) {
+ observe(key.toString());
+ }
+ return inner.remove(key);
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends List<V>> m) {
+ for (String key : m.keySet()) {
+ observe(key);
+ }
+ inner.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ observeAll();
+ inner.clear();
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return inner.keySet();
+ }
+
+ @Override
+ public Collection<List<V>> values() {
+ return inner.values();
+ }
+
+ @Override
+ public Set<Entry<String, List<V>>> entrySet() {
+ return inner.entrySet();
+ }
+
+ /**
+ * Observe changes of a value represented by the key.
+ * @param key the key values to observe
+ */
+ public void setGuard(String key) {
+ guards.put(key, false);
+ }
+
+ /**
+ * Get all the guarded keys
+ * @return a {@link Set} of keys guarded.
+ */
+ public Set<String> getGuards() {
+ return guards.keySet();
+ }
+
+ /**
+ * Return true when the value represented by the key has changed. Resets any observation - the operation is not idempotent.
+ * @param key the Key observed.
+ * @return whether the value represented by the key has changed.
+ */
+ public boolean isObservedAndReset(String key) {
+ Boolean observed = guards.get(key);
+ guards.put(key, false);
+ return observed != null && observed;
+ }
+
+ private void observe(String key) {
+ for (Map.Entry<String, Boolean> guard : guards.entrySet()) {
+ if (guard.getKey().equals(key)) {
+ guard.setValue(true);
+ }
+ }
+ }
+
+ private void observeAll() {
+ for (Map.Entry<String, Boolean> guard : guards.entrySet()) {
+ guard.setValue(true);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return inner.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ GuardianStringKeyMultivaluedMap<?> that = (GuardianStringKeyMultivaluedMap<?>) o;
+ return inner.equals(that.inner) && guards.equals(that.guards);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(inner, guards);
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/LRU.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/LRU.java
new file mode 100644
index 0000000..3338b00
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/LRU.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.util.collection;
+
+import org.glassfish.jersey.internal.guava.Cache;
+import org.glassfish.jersey.internal.guava.CacheBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An abstract LRU interface wrapping an actual LRU implementation.
+ * @param <K> Key type
+ * @param <V> Value type
+ * @Since 2.38
+ */
+public abstract class LRU<K, V> {
+
+ /**
+ * Returns the value associated with {@code key} in this cache, or {@code null} if there is no
+ * cached value for {@code key}.
+ */
+ public abstract V getIfPresent(Object key);
+
+ /**
+ * Associates {@code value} with {@code key} in this cache. If the cache previously contained a
+ * value associated with {@code key}, the old value is replaced by {@code value}.
+ */
+ public abstract void put(K key, V value);
+
+ /**
+ * Create new LRU
+ * @return new LRU
+ */
+ public static <K, V> LRU<K, V> create() {
+ return LRUFactory.createLRU();
+ }
+
+ private static class LRUFactory {
+ // TODO configure via the Configuration
+ public static final int LRU_CACHE_SIZE = 128;
+ public static final long TIMEOUT = 5000L;
+ private static <K, V> LRU<K, V> createLRU() {
+ final Cache<K, V> CACHE = CacheBuilder.newBuilder()
+ .maximumSize(LRU_CACHE_SIZE)
+ .expireAfterAccess(TIMEOUT, TimeUnit.MILLISECONDS)
+ .build();
+ return new LRU<K, V>() {
+ @Override
+ public V getIfPresent(Object key) {
+ return CACHE.getIfPresent(key);
+ }
+
+ @Override
+ public void put(K key, V value) {
+ CACHE.put(key, value);
+ }
+ };
+ }
+ }
+
+
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/HeaderUtils.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/HeaderUtils.java
index 8064f66..aeea686 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/HeaderUtils.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/HeaderUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -102,7 +102,7 @@
* if the supplied header value is {@code null}.
*/
@SuppressWarnings("unchecked")
- private static String asString(final Object headerValue, RuntimeDelegate rd) {
+ public static String asString(final Object headerValue, RuntimeDelegate rd) {
if (headerValue == null) {
return null;
}
@@ -149,7 +149,7 @@
* will be called for before element conversion.
* @return String view of header values.
*/
- private static List<String> asStringList(final List<Object> headerValues, final RuntimeDelegate rd) {
+ public static List<String> asStringList(final List<Object> headerValues, final RuntimeDelegate rd) {
if (headerValues == null || headerValues.isEmpty()) {
return Collections.emptyList();
}
@@ -191,7 +191,24 @@
return null;
}
- final RuntimeDelegate rd = RuntimeDelegateDecorator.configured(configuration);
+ return asStringHeaders(headers, RuntimeDelegateDecorator.configured(configuration));
+ }
+
+ /**
+ * Returns string view of passed headers. Any modifications to the headers are visible to the view, the view also
+ * supports removal of elements. Does not support other modifications.
+ *
+ * @param headers headers.
+ * @param rd {@link RuntimeDelegate} instance or {@code null} (in that case {@link RuntimeDelegate#getInstance()}
+ * will be called for before conversion of elements).
+ * @return String view of headers or {@code null} if {code headers} input parameter is {@code null}.
+ */
+ public static MultivaluedMap<String, String> asStringHeaders(
+ final MultivaluedMap<String, Object> headers, RuntimeDelegate rd) {
+ if (headers == null) {
+ return null;
+ }
+
return new AbstractMultivaluedMap<String, String>(
Views.mapView(headers, input -> HeaderUtils.asStringList(input, rd))
) {
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/HttpHeaderReader.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/HttpHeaderReader.java
index c39a016..fe5a249 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/HttpHeaderReader.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/HttpHeaderReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,6 +23,7 @@
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -31,6 +32,7 @@
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.NewCookie;
+import org.glassfish.jersey.internal.util.collection.LRU;
/**
* An abstract pull-based reader of HTTP headers.
@@ -371,61 +373,25 @@
return l;
}
- private static final ListElementCreator<MediaType> MEDIA_TYPE_CREATOR =
- new ListElementCreator<MediaType>() {
-
- @Override
- public MediaType create(HttpHeaderReader reader) throws ParseException {
- return MediaTypeProvider.valueOf(reader);
- }
- };
-
/**
* TODO javadoc.
*/
public static List<MediaType> readMediaTypes(List<MediaType> l, String header) throws ParseException {
- return HttpHeaderReader.readList(
- l,
- MEDIA_TYPE_CREATOR,
- header);
+ return MEDIA_TYPE_LIST_READER.readList(l, header);
}
- private static final ListElementCreator<AcceptableMediaType> ACCEPTABLE_MEDIA_TYPE_CREATOR =
- new ListElementCreator<AcceptableMediaType>() {
-
- @Override
- public AcceptableMediaType create(HttpHeaderReader reader) throws ParseException {
- return AcceptableMediaType.valueOf(reader);
- }
- };
-
/**
* TODO javadoc.
*/
public static List<AcceptableMediaType> readAcceptMediaType(String header) throws ParseException {
- return HttpHeaderReader.readQualifiedList(
- AcceptableMediaType.COMPARATOR,
- ACCEPTABLE_MEDIA_TYPE_CREATOR,
- header);
+ return ACCEPTABLE_MEDIA_TYPE_LIST_READER.readList(header);
}
- private static final ListElementCreator<QualitySourceMediaType> QUALITY_SOURCE_MEDIA_TYPE_CREATOR =
- new ListElementCreator<QualitySourceMediaType>() {
-
- @Override
- public QualitySourceMediaType create(HttpHeaderReader reader) throws ParseException {
- return QualitySourceMediaType.valueOf(reader);
- }
- };
-
/**
* FIXME use somewhere in production code or remove.
*/
public static List<QualitySourceMediaType> readQualitySourceMediaType(String header) throws ParseException {
- return HttpHeaderReader.readQualifiedList(
- QualitySourceMediaType.COMPARATOR,
- QUALITY_SOURCE_MEDIA_TYPE_CREATOR,
- header);
+ return QUALITY_SOURCE_MEDIA_TYPE_LIST_READER.readList(header);
}
/**
@@ -454,121 +420,246 @@
public static List<AcceptableMediaType> readAcceptMediaType(
final String header, final List<QualitySourceMediaType> priorityMediaTypes) throws ParseException {
- return HttpHeaderReader.readQualifiedList(
- new Comparator<AcceptableMediaType>() {
-
- @Override
- public int compare(AcceptableMediaType o1, AcceptableMediaType o2) {
- // FIXME what is going on here?
- boolean q_o1_set = false;
- int q_o1 = 0;
- boolean q_o2_set = false;
- int q_o2 = 0;
- for (QualitySourceMediaType priorityType : priorityMediaTypes) {
- if (!q_o1_set && MediaTypes.typeEqual(o1, priorityType)) {
- q_o1 = o1.getQuality() * priorityType.getQuality();
- q_o1_set = true;
- } else if (!q_o2_set && MediaTypes.typeEqual(o2, priorityType)) {
- q_o2 = o2.getQuality() * priorityType.getQuality();
- q_o2_set = true;
- }
- }
- int i = q_o2 - q_o1;
- if (i != 0) {
- return i;
- }
-
- i = o2.getQuality() - o1.getQuality();
- if (i != 0) {
- return i;
- }
-
- return MediaTypes.PARTIAL_ORDER_COMPARATOR.compare(o1, o2);
- }
- },
- ACCEPTABLE_MEDIA_TYPE_CREATOR,
- header);
+ return new AcceptMediaTypeListReader(priorityMediaTypes).readList(header);
}
- private static final ListElementCreator<AcceptableToken> ACCEPTABLE_TOKEN_CREATOR =
- new ListElementCreator<AcceptableToken>() {
-
- @Override
- public AcceptableToken create(HttpHeaderReader reader) throws ParseException {
- return new AcceptableToken(reader);
- }
- };
/**
* TODO javadoc.
*/
public static List<AcceptableToken> readAcceptToken(String header) throws ParseException {
- return HttpHeaderReader.readQualifiedList(ACCEPTABLE_TOKEN_CREATOR, header);
+ return ACCEPTABLE_TOKEN_LIST_READER.readList(header);
}
- private static final ListElementCreator<AcceptableLanguageTag> LANGUAGE_CREATOR =
- new ListElementCreator<AcceptableLanguageTag>() {
-
- @Override
- public AcceptableLanguageTag create(HttpHeaderReader reader) throws ParseException {
- return new AcceptableLanguageTag(reader);
- }
- };
-
/**
* TODO javadoc.
*/
public static List<AcceptableLanguageTag> readAcceptLanguage(String header) throws ParseException {
- return HttpHeaderReader.readQualifiedList(LANGUAGE_CREATOR, header);
- }
-
- private static <T extends Qualified> List<T> readQualifiedList(ListElementCreator<T> c, String header)
- throws ParseException {
-
- List<T> l = readList(c, header);
- Collections.sort(l, Quality.QUALIFIED_COMPARATOR);
- return l;
- }
-
- private static <T> List<T> readQualifiedList(final Comparator<T> comparator, ListElementCreator<T> c, String header)
- throws ParseException {
-
- List<T> l = readList(c, header);
- Collections.sort(l, comparator);
- return l;
+ return ACCEPTABLE_LANGUAGE_TAG_LIST_READER.readList(header);
}
/**
* TODO javadoc.
*/
public static List<String> readStringList(String header) throws ParseException {
- return readList(new ListElementCreator<String>() {
+ return STRING_LIST_READER.readList(header);
+ }
+ private static final MediaTypeListReader MEDIA_TYPE_LIST_READER = new MediaTypeListReader();
+ private static final AcceptableMediaTypeListReader ACCEPTABLE_MEDIA_TYPE_LIST_READER = new AcceptableMediaTypeListReader();
+ private static final QualitySourceMediaTypeListReader QUALITY_SOURCE_MEDIA_TYPE_LIST_READER =
+ new QualitySourceMediaTypeListReader();
+ private static final AcceptableTokenListReader ACCEPTABLE_TOKEN_LIST_READER = new AcceptableTokenListReader();
+ private static final AcceptableLanguageTagListReader ACCEPTABLE_LANGUAGE_TAG_LIST_READER =
+ new AcceptableLanguageTagListReader();
+ private static final StringListReader STRING_LIST_READER = new StringListReader();
+
+ private static class MediaTypeListReader extends ListReader<MediaType> {
+ private static final ListElementCreator<MediaType> MEDIA_TYPE_CREATOR =
+ new ListElementCreator<MediaType>() {
+
+ @Override
+ public MediaType create(HttpHeaderReader reader) throws ParseException {
+ return MediaTypeProvider.valueOf(reader);
+ }
+ };
+
+ List<MediaType> readList(List<MediaType> l, final String header) throws ParseException {
+ return super.readList(l, header);
+ }
+
+ private MediaTypeListReader() {
+ super(MEDIA_TYPE_CREATOR);
+ }
+ }
+
+ private static class AcceptableMediaTypeListReader extends QualifiedListReader<AcceptableMediaType> {
+ private static final ListElementCreator<AcceptableMediaType> ACCEPTABLE_MEDIA_TYPE_CREATOR =
+ new ListElementCreator<AcceptableMediaType>() {
+
+ @Override
+ public AcceptableMediaType create(HttpHeaderReader reader) throws ParseException {
+ return AcceptableMediaType.valueOf(reader);
+ }
+ };
+ private AcceptableMediaTypeListReader() {
+ super(ACCEPTABLE_MEDIA_TYPE_CREATOR, AcceptableMediaType.COMPARATOR);
+ }
+ }
+ /*
+ * TODO not used in production?
+ */
+ private static class QualitySourceMediaTypeListReader extends QualifiedListReader<QualitySourceMediaType> {
+ private static final ListElementCreator<QualitySourceMediaType> QUALITY_SOURCE_MEDIA_TYPE_CREATOR =
+ new ListElementCreator<QualitySourceMediaType>() {
+
+ @Override
+ public QualitySourceMediaType create(HttpHeaderReader reader) throws ParseException {
+ return QualitySourceMediaType.valueOf(reader);
+ }
+ };
+ private QualitySourceMediaTypeListReader() {
+ super(QUALITY_SOURCE_MEDIA_TYPE_CREATOR, QualitySourceMediaType.COMPARATOR);
+ }
+ }
+
+ /*
+ * TODO this is used in tests only
+ */
+ private static class AcceptMediaTypeListReader extends QualifiedListReader<AcceptableMediaType> {
+ AcceptMediaTypeListReader(List<QualitySourceMediaType> priorityMediaTypes) {
+ super(ACCEPTABLE_MEDIA_TYPE_CREATOR, new AcceptableMediaTypeComparator(priorityMediaTypes));
+ }
+
+ private static final ListElementCreator<AcceptableMediaType> ACCEPTABLE_MEDIA_TYPE_CREATOR =
+ new ListElementCreator<AcceptableMediaType>() {
+
+ @Override
+ public AcceptableMediaType create(HttpHeaderReader reader) throws ParseException {
+ return AcceptableMediaType.valueOf(reader);
+ }
+ };
+
+ private static class AcceptableMediaTypeComparator implements Comparator<AcceptableMediaType> {
+ private final List<QualitySourceMediaType> priorityMediaTypes;
+
+ private AcceptableMediaTypeComparator(List<QualitySourceMediaType> priorityMediaTypes) {
+ this.priorityMediaTypes = priorityMediaTypes;
+ }
+
+ @Override
+ public int compare(AcceptableMediaType o1, AcceptableMediaType o2) {
+ // FIXME what is going on here?
+ boolean q_o1_set = false;
+ int q_o1 = 0;
+ boolean q_o2_set = false;
+ int q_o2 = 0;
+ for (QualitySourceMediaType priorityType : priorityMediaTypes) {
+ if (!q_o1_set && MediaTypes.typeEqual(o1, priorityType)) {
+ q_o1 = o1.getQuality() * priorityType.getQuality();
+ q_o1_set = true;
+ } else if (!q_o2_set && MediaTypes.typeEqual(o2, priorityType)) {
+ q_o2 = o2.getQuality() * priorityType.getQuality();
+ q_o2_set = true;
+ }
+ }
+ int i = q_o2 - q_o1;
+ if (i != 0) {
+ return i;
+ }
+
+ i = o2.getQuality() - o1.getQuality();
+ if (i != 0) {
+ return i;
+ }
+
+ return MediaTypes.PARTIAL_ORDER_COMPARATOR.compare(o1, o2);
+ }
+ };
+
+
+ }
+
+ private static class AcceptableTokenListReader extends QualifiedListReader<AcceptableToken> {
+ private static final ListElementCreator<AcceptableToken> ACCEPTABLE_TOKEN_CREATOR =
+ new ListElementCreator<AcceptableToken>() {
+
+ @Override
+ public AcceptableToken create(HttpHeaderReader reader) throws ParseException {
+ return new AcceptableToken(reader);
+ }
+ };
+ private AcceptableTokenListReader() {
+ super(ACCEPTABLE_TOKEN_CREATOR);
+ }
+ }
+
+ private static class AcceptableLanguageTagListReader extends QualifiedListReader<AcceptableLanguageTag> {
+ private static final ListElementCreator<AcceptableLanguageTag> LANGUAGE_CREATOR =
+ new ListElementCreator<AcceptableLanguageTag>() {
+
+ @Override
+ public AcceptableLanguageTag create(HttpHeaderReader reader) throws ParseException {
+ return new AcceptableLanguageTag(reader);
+ }
+ };
+ private AcceptableLanguageTagListReader() {
+ super(LANGUAGE_CREATOR);
+ }
+ }
+
+ private abstract static class QualifiedListReader<T extends Qualified> extends ListReader<T> {
+ @Override
+ public List<T> readList(String header) throws ParseException {
+ List<T> l = super.readList(header);
+ Collections.sort(l, comparator);
+ return l;
+ }
+
+ private final Comparator<T> comparator;
+ private QualifiedListReader(ListElementCreator<T> creator) {
+ this(creator, (Comparator<T>) Quality.QUALIFIED_COMPARATOR);
+ }
+
+ protected QualifiedListReader(ListElementCreator<T> creator, Comparator<T> comparator) {
+ super(creator);
+ this.comparator = comparator;
+ }
+ }
+
+ private static class StringListReader extends ListReader<String> {
+ private static final ListElementCreator<String> listElementCreator = new ListElementCreator<String>() {
@Override
public String create(HttpHeaderReader reader) throws ParseException {
reader.hasNext();
return reader.nextToken().toString();
}
- }, header);
+ };
+
+ private StringListReader() {
+ super(listElementCreator);
+ }
}
- private static <T> List<T> readList(final ListElementCreator<T> c, final String header) throws ParseException {
- return readList(new ArrayList<T>(), c, header);
- }
+ private abstract static class ListReader<T> {
+ private final LRU<String, List<T>> LIST_CACHE = LRU.create();
+ protected final ListElementCreator<T> creator;
- private static <T> List<T> readList(final List<T> l, final ListElementCreator<T> c, final String header)
- throws ParseException {
-
- HttpHeaderReader reader = new HttpHeaderReaderImpl(header);
- HttpHeaderListAdapter adapter = new HttpHeaderListAdapter(reader);
-
- while (reader.hasNext()) {
- l.add(c.create(adapter));
- adapter.reset();
- if (reader.hasNext()) {
- reader.next();
- }
+ protected ListReader(ListElementCreator<T> creator) {
+ this.creator = creator;
}
- return l;
+ protected List<T> readList(final String header) throws ParseException {
+ return readList(new ArrayList<T>(), header);
+ }
+
+ private List<T> readList(final List<T> l, final String header)
+ throws ParseException {
+
+// List<T> list = null;
+ List<T> list = LIST_CACHE.getIfPresent(header);
+
+ if (list == null) {
+ synchronized (LIST_CACHE) {
+ list = LIST_CACHE.getIfPresent(header);
+ if (list == null) {
+ HttpHeaderReader reader = new HttpHeaderReaderImpl(header);
+ HttpHeaderListAdapter adapter = new HttpHeaderListAdapter(reader);
+ list = new LinkedList<>();
+
+ while (reader.hasNext()) {
+ list.add(creator.create(adapter));
+ adapter.reset();
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+ LIST_CACHE.put(header, list);
+ }
+ }
+ }
+
+ l.addAll(list);
+ return l;
+ }
}
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
index 7e70d3b..9eb4a40 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
@@ -50,11 +50,16 @@
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.ext.ReaderInterceptor;
+import jakarta.ws.rs.ext.RuntimeDelegate;
import javax.xml.transform.Source;
import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.internal.RuntimeDelegateDecorator;
+import org.glassfish.jersey.internal.util.collection.GuardianStringKeyMultivaluedMap;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.message.MessageBodyWorkers;
/**
@@ -90,11 +95,14 @@
private static final List<AcceptableMediaType> WILDCARD_ACCEPTABLE_TYPE_SINGLETON_LIST =
Collections.singletonList(MediaTypes.WILDCARD_ACCEPTABLE_TYPE);
- private final MultivaluedMap<String, String> headers;
+ private final GuardianStringKeyMultivaluedMap<String> headers;
private final EntityContent entityContent;
private final boolean translateNce;
private MessageBodyWorkers workers;
private final Configuration configuration;
+ private final RuntimeDelegate runtimeDelegateDecorator;
+ private LazyValue<MediaType> contentTypeCache;
+ private LazyValue<List<AcceptableMediaType>> acceptTypeCache;
/**
* Input stream and its state. State is represented by the {@link Type Type enum} and
@@ -158,10 +166,16 @@
* as required by JAX-RS specification on the server side.
*/
public InboundMessageContext(Configuration configuration, boolean translateNce) {
- this.headers = HeaderUtils.createInbound();
+ this.headers = new GuardianStringKeyMultivaluedMap<>(HeaderUtils.createInbound());
this.entityContent = new EntityContent();
this.translateNce = translateNce;
this.configuration = configuration;
+ runtimeDelegateDecorator = RuntimeDelegateDecorator.configured(configuration);
+
+ contentTypeCache = contentTypeCache();
+ acceptTypeCache = acceptTypeCache();
+ headers.setGuard(HttpHeaders.CONTENT_TYPE);
+ headers.setGuard(HttpHeaders.ACCEPT);
}
/**
@@ -196,7 +210,7 @@
* @return updated context.
*/
public InboundMessageContext header(String name, Object value) {
- getHeaders().add(name, HeaderUtils.asString(value, configuration));
+ getHeaders().add(name, HeaderUtils.asString(value, runtimeDelegateDecorator));
return this;
}
@@ -208,7 +222,7 @@
* @return updated context.
*/
public InboundMessageContext headers(String name, Object... values) {
- this.getHeaders().addAll(name, HeaderUtils.asStringList(Arrays.asList(values), configuration));
+ this.getHeaders().addAll(name, HeaderUtils.asStringList(Arrays.asList(values), runtimeDelegateDecorator));
return this;
}
@@ -265,7 +279,7 @@
final LinkedList<String> linkedList = new LinkedList<String>();
for (Object element : values) {
- linkedList.add(HeaderUtils.asString(element, configuration));
+ linkedList.add(HeaderUtils.asString(element, runtimeDelegateDecorator));
}
return linkedList;
@@ -332,7 +346,7 @@
}
try {
- return converter.apply(HeaderUtils.asString(value, configuration));
+ return converter.apply(HeaderUtils.asString(value, runtimeDelegateDecorator));
} catch (ProcessingException ex) {
throw exception(name, value, ex);
}
@@ -447,18 +461,26 @@
* message entity).
*/
public MediaType getMediaType() {
- return singleHeader(HttpHeaders.CONTENT_TYPE, new Function<String, MediaType>() {
- @Override
- public MediaType apply(String input) {
- try {
- return RuntimeDelegateDecorator.configured(configuration)
- .createHeaderDelegate(MediaType.class)
- .fromString(input);
- } catch (IllegalArgumentException iae) {
- throw new ProcessingException(iae);
- }
- }
- }, false);
+ if (headers.isObservedAndReset(HttpHeaders.CONTENT_TYPE) && contentTypeCache.isInitialized()) {
+ contentTypeCache = contentTypeCache(); // headers changed -> drop cache
+ }
+ return contentTypeCache.get();
+ }
+
+ private LazyValue<MediaType> contentTypeCache() {
+ return Values.lazy((Value<MediaType>) () -> singleHeader(
+ HttpHeaders.CONTENT_TYPE, new Function<String, MediaType>() {
+ @Override
+ public MediaType apply(String input) {
+ try {
+ return runtimeDelegateDecorator
+ .createHeaderDelegate(MediaType.class)
+ .fromString(input);
+ } catch (IllegalArgumentException iae) {
+ throw new ProcessingException(iae);
+ }
+ }
+ }, false));
}
/**
@@ -468,17 +490,26 @@
* to their q-value, with highest preference first.
*/
public List<AcceptableMediaType> getQualifiedAcceptableMediaTypes() {
- final String value = getHeaderString(HttpHeaders.ACCEPT);
-
- if (value == null || value.isEmpty()) {
- return WILDCARD_ACCEPTABLE_TYPE_SINGLETON_LIST;
+ if (headers.isObservedAndReset(HttpHeaders.ACCEPT) && acceptTypeCache.isInitialized()) {
+ acceptTypeCache = acceptTypeCache();
}
+ return acceptTypeCache.get();
+ }
- try {
- return Collections.unmodifiableList(HttpHeaderReader.readAcceptMediaType(value));
- } catch (ParseException e) {
- throw exception(HttpHeaders.ACCEPT, value, e);
- }
+ private LazyValue<List<AcceptableMediaType>> acceptTypeCache() {
+ return Values.lazy((Value<List<AcceptableMediaType>>) () -> {
+ final String value = getHeaderString(HttpHeaders.ACCEPT);
+
+ if (value == null || value.isEmpty()) {
+ return WILDCARD_ACCEPTABLE_TYPE_SINGLETON_LIST;
+ }
+
+ try {
+ return Collections.unmodifiableList(HttpHeaderReader.readAcceptMediaType(value));
+ } catch (ParseException e) {
+ throw exception(HttpHeaders.ACCEPT, value, e);
+ }
+ });
}
/**
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java
index 3a7748c..b9ab253 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -47,11 +47,16 @@
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.ext.RuntimeDelegate;
import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.internal.RuntimeDelegateDecorator;
import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.internal.util.collection.GuardianStringKeyMultivaluedMap;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
/**
* Base outbound message context implementation.
@@ -63,9 +68,11 @@
private static final List<MediaType> WILDCARD_ACCEPTABLE_TYPE_SINGLETON_LIST =
Collections.<MediaType>singletonList(MediaTypes.WILDCARD_ACCEPTABLE_TYPE);
- private final MultivaluedMap<String, Object> headers;
+ private final GuardianStringKeyMultivaluedMap<Object> headers;
private final CommittingOutputStream committingOutputStream;
private Configuration configuration;
+ private RuntimeDelegate runtimeDelegateDecorator;
+ private LazyValue<MediaType> mediaTypeCache;
private Object entity;
private GenericType<?> entityType;
@@ -101,9 +108,13 @@
*/
public OutboundMessageContext(Configuration configuration) {
this.configuration = configuration;
- this.headers = HeaderUtils.createOutbound();
+ this.headers = new GuardianStringKeyMultivaluedMap<>(HeaderUtils.createOutbound());
this.committingOutputStream = new CommittingOutputStream();
this.entityStream = committingOutputStream;
+ this.runtimeDelegateDecorator = RuntimeDelegateDecorator.configured(configuration);
+ this.mediaTypeCache = mediaTypeCache();
+
+ headers.setGuard(HttpHeaders.CONTENT_LENGTH);
}
/**
@@ -113,7 +124,8 @@
* @param original the original outbound message context.
*/
public OutboundMessageContext(OutboundMessageContext original) {
- this.headers = HeaderUtils.createOutbound();
+ this.headers = new GuardianStringKeyMultivaluedMap<>(HeaderUtils.createOutbound());
+ this.headers.setGuard(HttpHeaders.CONTENT_LENGTH);
this.headers.putAll(original.headers);
this.committingOutputStream = new CommittingOutputStream();
this.entityStream = committingOutputStream;
@@ -122,6 +134,8 @@
this.entityType = original.entityType;
this.entityAnnotations = original.entityAnnotations;
this.configuration = original.configuration;
+ this.runtimeDelegateDecorator = original.runtimeDelegateDecorator;
+ this.mediaTypeCache = original.mediaTypeCache();
}
/**
@@ -153,7 +167,7 @@
* @return multi-valued map of outbound message header names to their string-converted values.
*/
public MultivaluedMap<String, String> getStringHeaders() {
- return HeaderUtils.asStringHeaders(headers, configuration);
+ return HeaderUtils.asStringHeaders(headers, runtimeDelegateDecorator);
}
/**
@@ -173,7 +187,7 @@
* character.
*/
public String getHeaderString(String name) {
- return HeaderUtils.asHeaderString(headers.get(name), RuntimeDelegateDecorator.configured(configuration));
+ return HeaderUtils.asHeaderString(headers.get(name), runtimeDelegateDecorator);
}
/**
@@ -209,7 +223,7 @@
return valueType.cast(value);
} else {
try {
- return converter.apply(HeaderUtils.asString(value, null));
+ return converter.apply(HeaderUtils.asString(value, runtimeDelegateDecorator));
} catch (ProcessingException ex) {
throw exception(name, value, ex);
}
@@ -267,8 +281,17 @@
* message entity).
*/
public MediaType getMediaType() {
- return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, RuntimeDelegateDecorator.configured(configuration)
- .createHeaderDelegate(MediaType.class)::fromString, false);
+ if (headers.isObservedAndReset(HttpHeaders.CONTENT_TYPE) && mediaTypeCache.isInitialized()) {
+ mediaTypeCache = mediaTypeCache(); // headers changed -> drop cache
+ }
+ return mediaTypeCache.get();
+ }
+
+ private LazyValue<MediaType> mediaTypeCache() {
+ return Values.lazy((Value<MediaType>) () ->
+ singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, RuntimeDelegateDecorator.configured(configuration)
+ .createHeaderDelegate(MediaType.class)::fromString, false)
+ );
}
/**
@@ -294,7 +317,7 @@
result.add(_value);
} else {
conversionApplied = true;
- result.addAll(HttpHeaderReader.readAcceptMediaType(HeaderUtils.asString(value, configuration)));
+ result.addAll(HttpHeaderReader.readAcceptMediaType(HeaderUtils.asString(value, runtimeDelegateDecorator)));
}
} catch (java.text.ParseException e) {
throw exception(HttpHeaders.ACCEPT, value, e);
@@ -333,7 +356,7 @@
} else {
conversionApplied = true;
try {
- result.addAll(HttpHeaderReader.readAcceptLanguage(HeaderUtils.asString(value, configuration))
+ result.addAll(HttpHeaderReader.readAcceptLanguage(HeaderUtils.asString(value, runtimeDelegateDecorator))
.stream()
.map(LanguageTag::getAsLocale)
.collect(Collectors.toList()));
@@ -366,7 +389,7 @@
}
Map<String, Cookie> result = new HashMap<String, Cookie>();
- for (String cookie : HeaderUtils.asStringList(cookies, configuration)) {
+ for (String cookie : HeaderUtils.asStringList(cookies, runtimeDelegateDecorator)) {
if (cookie != null) {
result.putAll(HttpHeaderReader.readCookies(cookie));
}
@@ -454,7 +477,7 @@
}
Map<String, NewCookie> result = new HashMap<String, NewCookie>();
- for (String cookie : HeaderUtils.asStringList(cookies, configuration)) {
+ for (String cookie : HeaderUtils.asStringList(cookies, runtimeDelegateDecorator)) {
if (cookie != null) {
NewCookie newCookie = HttpHeaderReader.readNewCookie(cookie);
String cookieName = newCookie.getName();
@@ -542,7 +565,7 @@
} else {
conversionApplied = true;
try {
- result.add(Link.valueOf(HeaderUtils.asString(value, configuration)));
+ result.add(Link.valueOf(HeaderUtils.asString(value, runtimeDelegateDecorator)));
} catch (IllegalArgumentException e) {
throw exception(HttpHeaders.LINK, value, e);
}
@@ -863,6 +886,7 @@
void setConfiguration(Configuration configuration) {
this.configuration = configuration;
+ this.runtimeDelegateDecorator = RuntimeDelegateDecorator.configured(configuration);
}
/**
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
index d4b4a05..f9ee35a 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,13 +19,15 @@
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -134,7 +136,7 @@
* @throws IOException if there is an error reading from the input stream.
*/
public static String readFromAsString(InputStream in, MediaType type) throws IOException {
- return readFromAsString(new InputStreamReader(in, getCharset(type)));
+ return new String(readAllBytes(in), getCharset(type));
}
/**
@@ -154,6 +156,73 @@
}
return sb.toString();
}
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Java 9+ InputStream::readAllBytes
+ * TODO Replace when Java 8 not any longer supported (3.1+)
+ */
+ private static byte[] readAllBytes(InputStream inputStream) throws IOException {
+ List<byte[]> bufs = null;
+ byte[] result = null;
+ int total = 0;
+ int remaining = Integer.MAX_VALUE;
+ int n;
+ do {
+ byte[] buf = new byte[Math.min(remaining, BUFFER_SIZE)];
+ int nread = 0;
+
+ // read to EOF which may read more or less than buffer size
+ while ((n = inputStream.read(buf, nread,
+ Math.min(buf.length - nread, remaining))) > 0) {
+ nread += n;
+ remaining -= n;
+ }
+
+ if (nread > 0) {
+ if (MAX_BUFFER_SIZE - total < nread) {
+ throw new OutOfMemoryError("Required array size too large");
+ }
+ total += nread;
+ if (result == null) {
+ result = buf;
+ } else {
+ if (bufs == null) {
+ bufs = new ArrayList<>();
+ bufs.add(result);
+ }
+ bufs.add(buf);
+ }
+ }
+ // if the last call to read returned -1 or the number of bytes
+ // requested have been read then break
+ } while (n >= 0 && remaining > 0);
+
+ if (bufs == null) {
+ if (result == null) {
+ return new byte[0];
+ }
+ return result.length == total ? result : Arrays.copyOf(result, total);
+ }
+
+ result = new byte[total];
+ int offset = 0;
+ remaining = total;
+ for (byte[] b : bufs) {
+ int count = Math.min(b.length, remaining);
+ System.arraycopy(b, 0, result, offset, count);
+ offset += count;
+ remaining -= count;
+ }
+
+ return result;
+ }
/**
* Convert a string to bytes and write those bytes to an output stream.
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java b/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
index bdf4ef5..99e5022 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
@@ -28,6 +28,7 @@
import java.util.logging.Logger;
import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.GenericEntity;
import jakarta.ws.rs.core.GenericType;
@@ -36,7 +37,6 @@
import jakarta.ws.rs.core.MultivaluedHashMap;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.SecurityContext;
-import jakarta.ws.rs.ext.RuntimeDelegate;
import jakarta.ws.rs.ext.WriterInterceptor;
import org.glassfish.jersey.internal.MapPropertiesDelegate;
@@ -162,7 +162,7 @@
}
public RequestContextBuilder type(final MediaType contentType) {
- request.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, HeaderUtils.asString(contentType, null));
+ request.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, HeaderUtils.asString(contentType, (Configuration) null));
return this;
}
@@ -186,7 +186,7 @@
request.getHeaders().remove(name);
return;
}
- request.header(name, HeaderUtils.asString(value, null));
+ request.header(name, HeaderUtils.asString(value, (Configuration) null));
}
private void putHeaders(final String name, final Object... values) {
@@ -194,7 +194,7 @@
request.getHeaders().remove(name);
return;
}
- request.getHeaders().addAll(name, HeaderUtils.asStringList(Arrays.asList(values), null));
+ request.getHeaders().addAll(name, HeaderUtils.asStringList(Arrays.asList(values), (Configuration) null));
}
private void putHeaders(final String name, final String... values) {
diff --git a/docs/src/main/docbook/getting-started.xml b/docs/src/main/docbook/getting-started.xml
index 47adf87..5553d50 100644
--- a/docs/src/main/docbook/getting-started.xml
+++ b/docs/src/main/docbook/getting-started.xml
@@ -51,10 +51,10 @@
configuration needs to be added to your Maven project pom:
<programlisting language="xml" linenumbering="unnumbered"><snapshotRepository>
- <id>ossrh</id>
- <name>Sonatype Nexus Snapshots</name>
- <url>https://jakarta.oss.sonatype.org/content/repositories/snapshots/</url>
- </snapshotRepository></programlisting>
+ <id>ossrh</id>
+ <name>Sonatype Nexus Snapshots</name>
+ <url>https://jakarta.oss.sonatype.org/content/repositories/snapshots/</url>
+</snapshotRepository></programlisting>
</para>
</note>
</para>
diff --git a/examples/extended-wadl-webapp/pom.xml b/examples/extended-wadl-webapp/pom.xml
index a6bf0d2..91c4d64 100644
--- a/examples/extended-wadl-webapp/pom.xml
+++ b/examples/extended-wadl-webapp/pom.xml
@@ -259,7 +259,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
diff --git a/examples/groovy/pom.xml b/examples/groovy/pom.xml
index 2038f89..89ca79c 100644
--- a/examples/groovy/pom.xml
+++ b/examples/groovy/pom.xml
@@ -28,7 +28,7 @@
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-all</artifactId>
<type>pom</type>
- <version>4.0.4</version>
+ <version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
diff --git a/examples/helloworld-weld/src/test/java/org/glassfish/jersey/examples/helloworld/RequestScopedResourceTest.java b/examples/helloworld-weld/src/test/java/org/glassfish/jersey/examples/helloworld/RequestScopedResourceTest.java
index 0821761..f39e30e 100644
--- a/examples/helloworld-weld/src/test/java/org/glassfish/jersey/examples/helloworld/RequestScopedResourceTest.java
+++ b/examples/helloworld-weld/src/test/java/org/glassfish/jersey/examples/helloworld/RequestScopedResourceTest.java
@@ -102,6 +102,10 @@
@AfterEach
public void tearDown() throws Exception {
super.tearDown();
+ }
+
+ @AfterAll
+ public void report() {
System.out.printf("SYNC: %d, ASYNC: %d, STRAIGHT: %d%n",
parameterizedCounter.intValue(), parameterizedAsyncCounter.intValue(), straightCounter.intValue());
}
diff --git a/examples/http-patch/pom.xml b/examples/http-patch/pom.xml
index 47b7302..2831595 100644
--- a/examples/http-patch/pom.xml
+++ b/examples/http-patch/pom.xml
@@ -43,6 +43,19 @@
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
<version>1.9</version>
+ <!-- Remove when a new higher version depends on Guava 24+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
diff --git a/examples/open-tracing/src/main/java/org/glassfish/jersey/examples/opentracing/App.java b/examples/open-tracing/src/main/java/org/glassfish/jersey/examples/opentracing/App.java
index 6b39f57..c92f440 100644
--- a/examples/open-tracing/src/main/java/org/glassfish/jersey/examples/opentracing/App.java
+++ b/examples/open-tracing/src/main/java/org/glassfish/jersey/examples/opentracing/App.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -113,7 +113,7 @@
public void filter(ContainerRequestContext requestContext) throws IOException {
Span span = OpenTracingUtils
.getRequestSpan(requestContext)
- .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-reqA").startManual());
+ .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-reqA").start());
span.log("ReqFilterA.filter() invoked");
}
}
@@ -128,7 +128,7 @@
public void filter(ContainerRequestContext requestContext) throws IOException {
Span span = OpenTracingUtils
.getRequestSpan(requestContext)
- .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-reqB").startManual());
+ .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-reqB").start());
span.log("ReqFilterB.filter() invoked");
}
}
@@ -141,7 +141,7 @@
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
Span span = OpenTracingUtils
.getRequestSpan(requestContext)
- .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-respA").startManual());
+ .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-respA").start());
span.log("RespFilterA.filter() invoked");
}
}
@@ -154,7 +154,7 @@
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
Span span = OpenTracingUtils
.getRequestSpan(requestContext)
- .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-respB").startManual());
+ .orElse(GlobalTracer.get().buildSpan("ad-hoc-span-respB").start());
span.log("RespFilterB.filter() invoked");
}
}
diff --git a/examples/osgi-helloworld-webapp/functional-test/pom.xml b/examples/osgi-helloworld-webapp/functional-test/pom.xml
index 6103b1e..36b35c8 100644
--- a/examples/osgi-helloworld-webapp/functional-test/pom.xml
+++ b/examples/osgi-helloworld-webapp/functional-test/pom.xml
@@ -80,15 +80,6 @@
<artifactId>javassist</artifactId>
<scope>test</scope>
</dependency>
-
- <!-- logging -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.6.4</version>
- <scope>test</scope>
- </dependency>
-
<!-- JUnit and Pax-Exam dependencies -->
<dependency>
<groupId>org.osgi</groupId>
diff --git a/ext/bean-validation/pom.xml b/ext/bean-validation/pom.xml
index 914251e..62f4686 100644
--- a/ext/bean-validation/pom.xml
+++ b/ext/bean-validation/pom.xml
@@ -100,9 +100,18 @@
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ <version>${jboss.logging.version}</version>
+ </dependency>
+ <dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<optional>true</optional>
diff --git a/ext/microprofile/mp-rest-client/pom.xml b/ext/microprofile/mp-rest-client/pom.xml
index bf2013b..4ffb25a 100644
--- a/ext/microprofile/mp-rest-client/pom.xml
+++ b/ext/microprofile/mp-rest-client/pom.xml
@@ -85,7 +85,7 @@
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
- <version>1.0.3</version>
+ <version>${reactive.streams.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
diff --git a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingApplicationEventListener.java b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingApplicationEventListener.java
index 40e2551..b6c6feb 100644
--- a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingApplicationEventListener.java
+++ b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingApplicationEventListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -25,6 +25,7 @@
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.ContainerResponseFilter;
+import io.opentracing.propagation.TextMapAdapter;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.ContainerResponse;
import org.glassfish.jersey.server.monitoring.ApplicationEvent;
@@ -36,7 +37,6 @@
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
-import io.opentracing.propagation.TextMapExtractAdapter;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
@@ -84,7 +84,7 @@
(entry) -> OpenTracingUtils.formatList(entry.getValue())));
final SpanContext extractedContext =
- globalTracer.extract(Format.Builtin.HTTP_HEADERS, new TextMapExtractAdapter(mappedHeaders));
+ globalTracer.extract(Format.Builtin.HTTP_HEADERS, new TextMapAdapter(mappedHeaders));
Tracer.SpanBuilder spanBuilder = globalTracer
.buildSpan(OpenTracingFeature.DEFAULT_REQUEST_SPAN_NAME)
@@ -99,7 +99,7 @@
spanBuilder = spanBuilder.asChildOf(extractedContext);
}
- final Span span = spanBuilder.startManual();
+ final Span span = spanBuilder.start();
request.setProperty(OpenTracingFeature.SPAN_CONTEXT_PROPERTY, span);
span.log(LocalizationMessages.OPENTRACING_LOG_REQUEST_STARTED());
return span;
@@ -157,7 +157,7 @@
resourceSpan = globalTracer.buildSpan(OpenTracingFeature.DEFAULT_RESOURCE_SPAN_NAME)
.asChildOf(requestSpan)
- .startManual();
+ .start();
event.getContainerRequest().setProperty(OpenTracingFeature.SPAN_CONTEXT_PROPERTY, resourceSpan);
break;
diff --git a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingClientRequestFilter.java b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingClientRequestFilter.java
index dc339a8..f384c91 100644
--- a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingClientRequestFilter.java
+++ b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingClientRequestFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -29,7 +29,7 @@
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
-import io.opentracing.propagation.TextMapInjectAdapter;
+import io.opentracing.propagation.TextMapAdapter;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
@@ -65,11 +65,11 @@
if (property != null && property instanceof SpanContext) {
spanBuilder = spanBuilder.asChildOf((SpanContext) property);
}
- Span span = spanBuilder.startManual();
+ Span span = spanBuilder.start();
requestContext.setProperty(OpenTracingFeature.SPAN_CONTEXT_PROPERTY, span);
Map<String, String> addedHeaders = new HashMap<>();
- GlobalTracer.get().inject(span.context(), Format.Builtin.HTTP_HEADERS, new TextMapInjectAdapter(addedHeaders));
+ GlobalTracer.get().inject(span.context(), Format.Builtin.HTTP_HEADERS, new TextMapAdapter(addedHeaders));
addedHeaders.forEach((key, value) -> requestContext.getHeaders().add(key, value));
}
}
diff --git a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingUtils.java b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingUtils.java
index c71ffac..3353be0 100644
--- a/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingUtils.java
+++ b/incubator/open-tracing/src/main/java/org/glassfish/jersey/opentracing/OpenTracingUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -89,7 +89,7 @@
spanBuilder = spanBuilder.asChildOf((Span) spanProperty);
}
}
- return spanBuilder.startManual();
+ return spanBuilder.start();
}
/**
diff --git a/pom.xml b/pom.xml
index c3473a1..d3a76a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.eclipse.ee4j</groupId>
<artifactId>project</artifactId>
- <version>1.0.7</version>
+ <version>1.0.8</version>
</parent>
<groupId>org.glassfish.jersey</groupId>
@@ -236,7 +236,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>${enforcer.version}</version>
+ <version>${enforcer.mvn.plugin.version}</version>
<executions>
<execution>
<id>enforce-versions</id>
@@ -257,7 +257,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
- <version>3.0.0</version>
+ <version>${buildhelper.mvn.plugin.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -282,7 +282,7 @@
<plugin>
<groupId>com.sun.istack</groupId>
<artifactId>istack-commons-maven-plugin</artifactId>
- <version>3.0.8</version>
+ <version>${istack.mvn.plugin.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -310,7 +310,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.8.0</version>
+ <version>${compiler.mvn.plugin.version}</version>
<inherited>true</inherited>
<configuration>
<source>${java.version}</source>
@@ -330,17 +330,17 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
- <version>3.2.0</version>
+ <version>${jar.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
- <version>2.5.2</version>
+ <version>${install.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version>
+ <version>${resources.mvn.plugin.version}</version>
<extensions>true</extensions>
<!-- Add legal information, NOTICE.md and LINCENSE.md to jars -->
<executions>
@@ -412,7 +412,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
<configuration>
<!-- print full stack trace if error -->
<trimStackTrace>false</trimStackTrace>
@@ -434,14 +434,14 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-logger-api</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
<!-- to get around bug https://github.com/junit-team/junit5/issues/1367 -->
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-api</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
@@ -449,20 +449,20 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
- <version>2.4</version>
+ <version>${assembly.mvn.plugin.version}</version>
<configuration>
- <tarLongFileMode>gnu</tarLongFileMode>
+ <tarLongFileMode>posix</tarLongFileMode>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>3.3.0</version>
+ <version>${dependency.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>3.2.0</version>
+ <version>${javadoc.mvn.plugin.version}</version>
<configuration>
<doctitle>Jersey ${jersey.version} API Documentation</doctitle>
<windowtitle>Jersey ${jersey.version} API</windowtitle>
@@ -500,7 +500,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
- <version>3.0.1</version>
+ <version>${source.mvn.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
@@ -514,7 +514,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
- <version>2.8.1</version>
+ <version>${deploy.mvn.plugin.version}</version>
<configuration>
<retryFailedDeploymentCount>10</retryFailedDeploymentCount>
</configuration>
@@ -540,12 +540,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
- <version>3.7.1</version>
+ <version>${site.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
+ <version>${exec.mvn.plugin.version}</version>
<executions>
<execution>
<goals>
@@ -557,7 +557,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
- <version>2.3</version>
+ <version>${jxr.mvn.plugin.version}</version>
<executions>
<execution>
<goals>
@@ -594,7 +594,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
- <version>${findbugs.version}</version>
+ <version>${findbugs.mvn.plugin.version}</version>
<configuration>
<skip>${findbugs.skip}</skip>
<threshold>${findbugs.threshold}</threshold>
@@ -622,7 +622,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
- <version>3.0.0-M3</version>
+ <version>${failsafe.mvn.plugin.version}</version>
<configuration>
<!-- print full stack trace if error -->
<trimStackTrace>false</trimStackTrace>
@@ -642,7 +642,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
- <version>3.3.1</version>
+ <version>${war.mvn.plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
@@ -650,12 +650,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
- <version>2.8</version>
+ <version>${ear.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.glassfish.embedded</groupId>
<artifactId>maven-embedded-glassfish-plugin</artifactId>
- <version>3.1.2.2</version>
+ <version>${gfembedded.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.glassfish.copyright</groupId>
@@ -681,7 +681,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>3.5.0</version>
+ <version>${felix.mvn.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
@@ -703,7 +703,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
- <version>1.0</version>
+ <version>${xml.mvn.plugin.version}</version>
</plugin>
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
@@ -713,7 +713,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
- <version>1.1</version>
+ <version>${buildnumber.mvn.plugin.version}</version>
</plugin>
<!-- TODO: remove the old jetty plugin dependencies -->
<plugin>
@@ -750,7 +750,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
- <version>2.4.3</version>
+ <version>${shade.mvn.plugin.version}</version>
<executions>
<execution>
<id>shade-archive</id>
@@ -781,24 +781,24 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
- <version>3.0.0</version>
+ <version>${antrun.mvn.plugin.version}</version>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
- <version>1.10.11</version>
+ <version>1.10.12</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.fortasoft</groupId>
<artifactId>gradle-maven-plugin</artifactId>
- <version>1.0.5</version>
+ <version>1.0.8</version>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
- <version>2.0.8</version>
+ <version>${proguard.mvn.plugin.version}</version>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
@@ -869,6 +869,10 @@
<activation>
<jdk>1.8</jdk>
</activation>
+ <properties>
+ <checkstyle.version>9.3</checkstyle.version>
+ <istack.mvn.plugin.version>3.0.9</istack.mvn.plugin.version>
+ </properties>
<build>
<pluginManagement>
<plugins>
@@ -1412,7 +1416,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
- <version>${findbugs.version}</version>
+ <version>${findbugs.mvn.plugin.version}</version>
<reportSets>
<reportSet>
<configuration>
@@ -1858,11 +1862,6 @@
<!-- HV OSGi dependencies. -->
<dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging</artifactId>
- <version>${jboss.logging.version}</version>
- </dependency>
- <dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<version>${fasterxml.classmate.version}</version>
@@ -1935,7 +1934,7 @@
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
- <version>1.2</version>
+ <version>${commons.logging.version}</version>
</dependency>
<!-- Weld -->
@@ -2015,21 +2014,16 @@
</dependency>
<dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
+ <groupId>org.junit</groupId>
+ <artifactId>junit-bom</artifactId>
<version>${junit5.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-engine</artifactId>
- <version>${junit5.version}</version>
- <scope>test</scope>
+ <type>pom</type>
+ <scope>import</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
- <version>6.9.13.6</version>
+ <version>${testng.version}</version>
<scope>test</scope>
</dependency>
@@ -2073,21 +2067,21 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
- <version>7.0.0</version>
+ <version>${felix.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.eventadmin</artifactId>
- <version>1.5.0</version>
+ <version>${felix.eventadmin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework.security</artifactId>
- <version>2.6.1</version>
+ <version>${felix.framework.security.version}</version>
<scope>test</scope>
</dependency>
@@ -2125,7 +2119,7 @@
</dependencyManagement>
<properties>
- <archetype.mvn.plugin.version>2.4</archetype.mvn.plugin.version>
+ <archetype.mvn.plugin.version>3.2.1</archetype.mvn.plugin.version>
<findbugs.skip>false</findbugs.skip>
<findbugs.threshold>Low</findbugs.threshold>
@@ -2142,6 +2136,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- <release.tests.args>-Dmaven.test.skip=false</release.tests.args>-->
<!-- <release.preparationGoals>clean install</release.preparationGoals>-->
+ <skip.e2e>false</skip.e2e>
<skip.tests>false</skip.tests>
<xdk.absolute.path />
<surefire.security.argline />
@@ -2150,9 +2145,44 @@
<failsafe.coverage.argline />
<server.coverage.argline>${failsafe.coverage.argline}</server.coverage.argline>
+ <!-- Versions of Maven plugins -->
+ <antrun.mvn.plugin.version>3.1.0</antrun.mvn.plugin.version>
+ <assembly.mvn.plugin.version>3.4.2</assembly.mvn.plugin.version>
+ <enforcer.mvn.plugin.version>3.1.0</enforcer.mvn.plugin.version>
+ <exec.mvn.plugin.version>3.1.0</exec.mvn.plugin.version>
+ <buildhelper.mvn.plugin.version>3.3.0</buildhelper.mvn.plugin.version>
+ <buildnumber.mvn.plugin.version>3.0.0</buildnumber.mvn.plugin.version>
+ <checkstyle.mvn.plugin.version>3.1.2</checkstyle.mvn.plugin.version>
+ <checkstyle.version>10.3.2</checkstyle.version>
+ <compiler.mvn.plugin.version>3.8.0</compiler.mvn.plugin.version>
+ <dependency.mvn.plugin.version>3.3.0</dependency.mvn.plugin.version>
+ <deploy.mvn.plugin.version>3.0.0-M2</deploy.mvn.plugin.version>
+ <ear.mvn.plugin.version>3.2.0</ear.mvn.plugin.version>
+ <failsafe.mvn.plugin.version>3.0.0-M7</failsafe.mvn.plugin.version>
+ <felix.mvn.plugin.version>5.1.8</felix.mvn.plugin.version>
+ <findbugs.mvn.plugin.version>3.0.5</findbugs.mvn.plugin.version>
+ <gfembedded.mvn.plugin.version>5.1</gfembedded.mvn.plugin.version>
+ <install.mvn.plugin.version>3.0.1</install.mvn.plugin.version>
+ <istack.mvn.plugin.version>4.1.1</istack.mvn.plugin.version>
+ <jar.mvn.plugin.version>3.2.2</jar.mvn.plugin.version>
+ <javadoc.mvn.plugin.version>3.4.0</javadoc.mvn.plugin.version>
+ <jxr.mvn.plugin.version>3.2.0</jxr.mvn.plugin.version>
+ <paxexam.mvn.plugin.version>1.2.4</paxexam.mvn.plugin.version>
+ <proguard.mvn.plugin.version>2.6.0</proguard.mvn.plugin.version>
+ <resources.mvn.plugin.version>3.3.0</resources.mvn.plugin.version>
+ <shade.mvn.plugin.version>3.3.0</shade.mvn.plugin.version>
+ <site.mvn.plugin.version>3.9.1</site.mvn.plugin.version>
+ <source.mvn.plugin.version>3.2.1</source.mvn.plugin.version>
+ <surefire.mvn.plugin.version>3.0.0-M7</surefire.mvn.plugin.version>
+ <war.mvn.plugin.version>3.3.2</war.mvn.plugin.version>
+ <wiremock.mvn.plugin.version>2.9.0</wiremock.mvn.plugin.version>
+ <xml.mvn.plugin.version>1.0.2</xml.mvn.plugin.version>
+ <!-- END of Versions of Maven plugins -->
<!-- Dependency versions -->
<jersey.version>${project.version}</jersey.version>
+ <arquillian.version>1.7.0.Alpha13</arquillian.version>
+ <arquillian.weld.version>3.0.1.Final</arquillian.weld.version>
<!-- asm is now source integrated - keeping this property to see the version -->
<!-- see core-server/src/main/java/jersey/repackaged/asm/.. -->
<asm.version>9.4</asm.version>
@@ -2161,22 +2191,19 @@
<bouncycastle.version>1.68</bouncycastle.version>
<commons.io.version>2.11.0</commons.io.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
- <checkstyle.mvn.plugin.version>3.1.0</checkstyle.mvn.plugin.version>
- <checkstyle.version>8.28</checkstyle.version>
- <easymock.version>3.3</easymock.version>
-
- <fasterxml.classmate.version>1.3.3</fasterxml.classmate.version>
+ <commons.logging.version>1.2</commons.logging.version>
+ <fasterxml.classmate.version>1.5.1</fasterxml.classmate.version>
+ <felix.eventadmin.version>1.6.4</felix.eventadmin.version>
+ <felix.framework.security.version>2.8.3</felix.framework.security.version>
+ <felix.framework.version>7.0.5</felix.framework.version>
<findbugs.glassfish.version>1.7</findbugs.glassfish.version>
- <findbugs.version>3.0.4</findbugs.version>
- <freemarker.version>2.3.27-incubating</freemarker.version>
- <gae.version>1.9.59</gae.version>
- <grizzly.client.version>1.16</grizzly.client.version>
- <enforcer.version>3.1.0</enforcer.version>
+ <freemarker.version>2.3.31</freemarker.version>
+ <gae.version>1.9.98</gae.version>
+ <groovy.version>4.0.6</groovy.version>
+ <gson.version>2.9.0</gson.version>
<!--versions, extracted here due to maven-enforcer-plugin -->
- <slf4j.version>2.0.3</slf4j.version>
<commons.codec.version>1.15</commons.codec.version>
- <reactive.streams.version>1.0.3</reactive.streams.version>
<com.uber.jaeger.version>0.27.0</com.uber.jaeger.version>
<org.codehaus.gmavenplus.version>1.13.1</org.codehaus.gmavenplus.version>
<!-- end of versions extracted here due to maven-enforcer-plugin -->
@@ -2187,56 +2214,51 @@
<helidon.config.version>3.0.0-M1</helidon.config.version>
<smallrye.config.version>3.0.0-RC1</smallrye.config.version>
-
- <grizzly2.version>2.4.4</grizzly2.version>
<guava.version>31.1-jre</guava.version>
<hamcrest.version>2.2</hamcrest.version>
- <!--<helidon.version>1.0.3</helidon.version>-->
+ <!--<helidon.version>1.4.9</helidon.version>-->
+ <helidon.jersey.connector.version>3.0.2</helidon.jersey.connector.version>
<xmlunit.version>2.9.0</xmlunit.version>
<hk2.osgi.version>org.glassfish.hk2.*;version="[2.5,4)"</hk2.osgi.version>
<hk2.jvnet.osgi.version>org.jvnet.hk2.*;version="[2.5,4)"</hk2.jvnet.osgi.version>
<httpclient.version>4.5.13</httpclient.version>
- <httpclient5.version>5.1.2</httpclient5.version>
+ <httpclient5.version>5.1.3</httpclient5.version>
<jackson.version>2.13.3</jackson.version>
- <javassist.version>3.28.0-GA</javassist.version>
- <jboss.logging.version>3.3.0.Final</jboss.logging.version>
+ <javassist.version>3.29.0-GA</javassist.version>
+ <jboss.logging.version>3.4.2.Final</jboss.logging.version>
<jersey1.version>1.19.3</jersey1.version>
<jersey1.last.final.version>${jersey1.version}</jersey1.last.final.version>
<jettison.version>1.3.7</jettison.version> <!-- TODO: 1.3.8 doesn't work; AbstractJsonTest complexBeanWithAttributes -->
- <jmh.version>1.10.2</jmh.version>
+ <jmh.version>1.35</jmh.version>
<jmockit.version>1.49</jmockit.version>
<junit4.version>4.13.2</junit4.version>
<junit5.version>5.9.1</junit5.version>
<junit-platform-suite.version>1.9.1</junit-platform-suite.version>
<kryo.version>4.0.2</kryo.version>
<mockito.version>3.12.4</mockito.version> <!-- CQ 17673 -->
- <mustache.version>0.8.17</mustache.version>
- <netty.version>4.1.75.Final</netty.version>
- <nexus-staging.mvn.plugin.version>1.6.7</nexus-staging.mvn.plugin.version>
- <opentracing.version>0.30.0</opentracing.version>
+ <mustache.version>0.9.10</mustache.version>
+ <netty.version>4.1.79.Final</netty.version>
+ <opentracing.version>0.33.0</opentracing.version>
<osgi.version>6.0.0</osgi.version>
<osgi.framework.version>1.10.0</osgi.framework.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>
<osgi.service.cm.version>1.6.0</osgi.service.cm.version>
<pax.exam.version>4.13.4</pax.exam.version>
<pax.web.version>0.7.4</pax.web.version><!-- TODO: UPGRADE! -->
- <paxexam.mvn.plugin.version>1.2.4</paxexam.mvn.plugin.version>
- <rxjava.version>1.2.5</rxjava.version>
- <rxjava2.version>2.0.4</rxjava2.version>
- <servlet3.version>3.0.1</servlet3.version>
- <servlet4.version>4.0.3</servlet4.version>
+ <reactive.streams.version>1.0.4</reactive.streams.version>
+ <rxjava.version>1.3.8</rxjava.version>
+ <rxjava2.version>2.2.21</rxjava2.version>
<simple.version>6.0.1</simple.version>
- <skip.e2e>false</skip.e2e>
+ <slf4j.version>2.0.3</slf4j.version>
<spring6.version>6.0.0-M3</spring6.version>
- <surefire.version>3.0.0-M7</surefire.version>
- <validation.impl.version>6.2.0.Final</validation.impl.version>
- <gson.version>2.9.0</gson.version>
-
+ <testng.version>7.6.1</testng.version>
+ <testng6.version>6.9.13.6</testng6.version>
<!-- Jakartified, eligible for CQ -->
<weld.version>4.0.2.Final</weld.version>
<weld3.version>3.1.7.SP1</weld3.version>
- <validation.impl.version>7.0.1.Final</validation.impl.version>
+ <validation.impl.version>7.0.5.Final</validation.impl.version>
<!-- END of Jakartified, eligible for CQ -->
+ <wiremock.version>2.27.2</wiremock.version>
<xerces.version>2.12.2</xerces.version>
<!-- Graal VM -->
@@ -2250,6 +2272,7 @@
<cdi.osgi.version>jakarta.enterprise.*;version="[3.0,5)"</cdi.osgi.version>
<ejb.version>4.0.1</ejb.version>
<grizzly2.version>3.0.1</grizzly2.version>
+ <grizzly.client.version>1.16</grizzly.client.version>
<grizzly.npn.version>2.0.0</grizzly.npn.version>
<hk2.version>3.0.3</hk2.version>
<jsp.version>3.0.0</jsp.version>
diff --git a/test-framework/core/pom.xml b/test-framework/core/pom.xml
index 2cc71a0..37cbab0 100644
--- a/test-framework/core/pom.xml
+++ b/test-framework/core/pom.xml
@@ -67,6 +67,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
+ <version>${testng6.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/test-framework/maven/custom-enforcer-rules/pom.xml b/test-framework/maven/custom-enforcer-rules/pom.xml
index b99519e..a3d77c0 100644
--- a/test-framework/maven/custom-enforcer-rules/pom.xml
+++ b/test-framework/maven/custom-enforcer-rules/pom.xml
@@ -34,7 +34,7 @@
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>${enforcer.version}</version>
+ <version>${enforcer.mvn.plugin.version}</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/HeaderUtilsTest.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/HeaderUtilsTest.java
index f252906..03446f9 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/HeaderUtilsTest.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/HeaderUtilsTest.java
@@ -25,6 +25,7 @@
import java.util.List;
import jakarta.ws.rs.core.AbstractMultivaluedMap;
+import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.ext.RuntimeDelegate;
@@ -101,19 +102,19 @@
@Test
public void testAsString() throws Exception {
- assertNull(HeaderUtils.asString(null, null));
+ assertNull(HeaderUtils.asString(null, (Configuration) null));
final String value = "value";
- assertSame(value, HeaderUtils.asString(value, null));
+ assertSame(value, HeaderUtils.asString(value, (Configuration) null));
final URI uri = new URI("test");
- assertEquals(uri.toASCIIString(), HeaderUtils.asString(uri, null));
+ assertEquals(uri.toASCIIString(), HeaderUtils.asString(uri, (Configuration) null));
}
@Test
public void testAsStringList() throws Exception {
- assertNotNull(HeaderUtils.asStringList(null, null));
- assertTrue(HeaderUtils.asStringList(null, null).isEmpty());
+ assertNotNull(HeaderUtils.asStringList(null, (Configuration) null));
+ assertTrue(HeaderUtils.asStringList(null, (Configuration) null).isEmpty());
final URI uri = new URI("test");
final List<Object> values = new LinkedList<Object>() {{
@@ -123,7 +124,7 @@
}};
// test string values
- final List<String> stringList = HeaderUtils.asStringList(values, null);
+ final List<String> stringList = HeaderUtils.asStringList(values, (Configuration) null);
assertEquals(Arrays.asList("value", "[null]", uri.toASCIIString()),
stringList);
@@ -138,7 +139,7 @@
@Test
public void testAsStringHeaders() throws Exception {
- assertNull(HeaderUtils.asStringHeaders(null, null));
+ assertNull(HeaderUtils.asStringHeaders(null, (Configuration) null));
final AbstractMultivaluedMap<String, Object> headers = HeaderUtils.createOutbound();
@@ -150,7 +151,7 @@
headers.putSingle("k3", "value3");
- final MultivaluedMap<String, String> stringHeaders = HeaderUtils.asStringHeaders(headers, null);
+ final MultivaluedMap<String, String> stringHeaders = HeaderUtils.asStringHeaders(headers, (Configuration) null);
// test string values
assertEquals(Arrays.asList("value", "value2"),
diff --git a/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java b/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java
index bc1058a..8fe509d 100644
--- a/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java
+++ b/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java
@@ -16,6 +16,7 @@
package org.glassfish.jersey.tests.e2e.header;
+
import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.internal.ServiceFinder;
@@ -36,6 +37,7 @@
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
@@ -155,7 +157,7 @@
public void testHeaderDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
MultivaluedHashMap headers = new MultivaluedHashMap();
headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest()));
- MultivaluedMap<String, String> converted = HeaderUtils.asStringHeaders(headers, null);
+ MultivaluedMap<String, String> converted = HeaderUtils.asStringHeaders(headers, (Configuration) null);
testMap(converted, BeanForHeaderDelegateProviderTest.getValue());
Client client = ClientBuilder.newClient().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false);
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/OptionalParamConverterTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/OptionalParamConverterTest.java
index 444475b..c1bfab3 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/OptionalParamConverterTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/OptionalParamConverterTest.java
@@ -16,6 +16,9 @@
package org.glassfish.jersey.tests.e2e.server;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.text.ParseException;
@@ -23,7 +26,7 @@
import java.util.Date;
import java.util.List;
import java.util.Optional;
-
+import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
@@ -39,13 +42,24 @@
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-
public class OptionalParamConverterTest extends JerseyTest {
private static final String PARAM_NAME = "paramName";
+ @Path("/IntegerResource")
+ public static class IntegerResource {
+ @GET
+ @Path("/fromInteger")
+ public Response fromInteger(@QueryParam(PARAM_NAME) Integer data) {
+ return Response.ok(0).build();
+ }
+ @GET
+ @Path("/fromIntegerNotNull")
+ public Response fromIntegerNotNull(@NotNull @QueryParam(PARAM_NAME) Integer data) {
+ return Response.ok(0).build();
+ }
+ }
+
@Path("/OptionalResource")
public static class OptionalResource {
@@ -62,6 +76,12 @@
}
@GET
+ @Path("/fromIntegerNotNull")
+ public Response fromIntegerNotNull(@NotNull @QueryParam(PARAM_NAME) Optional<Integer> data) {
+ return Response.ok(data.orElse(0)).build();
+ }
+
+ @GET
@Path("/fromDate")
public Response fromDate(@QueryParam(PARAM_NAME) Optional<Date> data) throws ParseException {
return Response.ok(data.orElse(new Date(1609459200000L))).build();
@@ -118,7 +138,7 @@
@Override
protected Application configure() {
- return new ResourceConfig(OptionalResource.class, InstantParamConverterProvider.class);
+ return new ResourceConfig(OptionalResource.class, IntegerResource.class, InstantParamConverterProvider.class);
}
@Test
@@ -137,6 +157,7 @@
Response empty = target("/OptionalResource/fromInteger").queryParam(PARAM_NAME, "").request().get();
Response notEmpty = target("/OptionalResource/fromInteger").queryParam(PARAM_NAME, 1).request().get();
Response invalid = target("/OptionalResource/fromInteger").queryParam(PARAM_NAME, "invalid").request().get();
+ Response missingNotNull = target("/OptionalResource/fromIntegerNotNull").request().get();
assertEquals(200, missing.getStatus());
assertEquals(Integer.valueOf(0), missing.readEntity(Integer.class));
assertEquals(200, empty.getStatus());
@@ -145,6 +166,17 @@
assertEquals(Integer.valueOf(1), notEmpty.readEntity(Integer.class));
assertEquals(404, invalid.getStatus());
assertFalse(invalid.hasEntity());
+ assertEquals(200, missingNotNull.getStatus());
+ assertEquals(Integer.valueOf(0), missingNotNull.readEntity(Integer.class));
+ }
+
+ @Test
+ public void fromInteger() {
+ Response missing = target("/IntegerResource/fromInteger").request().get();
+ Response missingNotNull = target("/IntegerResource/fromIntegerNotNull").request().get();
+ assertEquals(200, missing.getStatus());
+ assertEquals(Integer.valueOf(0), missing.readEntity(Integer.class));
+ assertEquals(400, missingNotNull.getStatus());
}
@Test
@@ -156,8 +188,8 @@
Response invalid = target("/OptionalResource/fromDate").queryParam(PARAM_NAME, "invalid").request().get();
assertEquals(200, missing.getStatus());
assertEquals(new Date(1609459200000L), missing.readEntity(Date.class));
- assertEquals(404, empty.getStatus());
- assertFalse(empty.hasEntity());
+ assertEquals(200, empty.getStatus());
+ assertEquals(new Date(1609459200000L), empty.readEntity(Date.class));
assertEquals(200, notEmpty.getStatus());
assertEquals(new Date(1619870400000L), notEmpty.readEntity(Date.class));
assertEquals(404, invalid.getStatus());
@@ -173,8 +205,8 @@
Response invalid = target("/OptionalResource/fromInstant").queryParam(PARAM_NAME, "invalid").request().get();
assertEquals(200, missing.getStatus());
assertEquals("2021-01-01T00:00:00Z", missing.readEntity(String.class));
- assertEquals(404, empty.getStatus());
- assertFalse(empty.hasEntity());
+ assertEquals(200, empty.getStatus());
+ assertEquals("2021-01-01T00:00:00Z", empty.readEntity(String.class));
assertEquals(200, notEmpty.getStatus());
assertEquals("2021-05-01T12:00:00Z", notEmpty.readEntity(String.class));
assertEquals(404, invalid.getStatus());
diff --git a/tests/e2e-testng/pom.xml b/tests/e2e-testng/pom.xml
index 98fad18..74d089b 100644
--- a/tests/e2e-testng/pom.xml
+++ b/tests/e2e-testng/pom.xml
@@ -52,7 +52,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
@@ -70,6 +70,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
+ <version>${testng6.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ResponseTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ResponseTest.java
index bf8c847..c9ac68c 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ResponseTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ResponseTest.java
@@ -24,6 +24,7 @@
import java.util.Locale;
import java.util.Set;
+import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
@@ -247,7 +248,7 @@
}
MultivaluedMap<String, String> mvp = HeaderUtils.asStringHeaders(
- resp.getMetadata(), null);
+ resp.getMetadata(), (Configuration) null);
for (String key : mvp.keySet()) {
sb.append(indent + "Processing Key found in response: ").append(key).append(": ").append(mvp.get(key)).append("; ")
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
index 7f9bd49..b1f5cfc 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
@@ -52,7 +52,7 @@
super(testContainerFactory);
}
- protected static List<TestContainerFactory> listContainerFactories(TestContainerFactory...factories) {
+ protected static List<TestContainerFactory> listContainerFactories(TestContainerFactory... factories) {
final JdkVersion version = JdkVersion.getJdkVersion();
boolean isJDK8 = version.getMajor() == 1;
final List<TestContainerFactory> filtered = new LinkedList<>();
diff --git a/tests/integration/cdi-integration/gf-cdi-inject/src/test/java/org/glassfish/jersey/tests/cdi/gf/GFTest.java b/tests/integration/cdi-integration/gf-cdi-inject/src/test/java/org/glassfish/jersey/tests/cdi/gf/GFTest.java
index a224bc8..5946c36 100644
--- a/tests/integration/cdi-integration/gf-cdi-inject/src/test/java/org/glassfish/jersey/tests/cdi/gf/GFTest.java
+++ b/tests/integration/cdi-integration/gf-cdi-inject/src/test/java/org/glassfish/jersey/tests/cdi/gf/GFTest.java
@@ -39,7 +39,7 @@
);
}
- private static WebArchive createDeployment(String archiveName, Class<?>...classes) {
+ private static WebArchive createDeployment(String archiveName, Class<?>... classes) {
WebArchive archive = ShrinkWrap.create(WebArchive.class, archiveName + ".war");
archive.addClasses(classes);
return archive;
diff --git a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseWrapper.java b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseWrapper.java
index de01bf9..c4c1bad 100644
--- a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseWrapper.java
+++ b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,6 +17,7 @@
package org.glassfish.jersey.tests.integration.jersey2176;
import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.WriteListener;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
diff --git a/tests/integration/microprofile/rest-client-tck/pom.xml b/tests/integration/microprofile/rest-client-tck/pom.xml
index 947348b..e5f263e 100644
--- a/tests/integration/microprofile/rest-client-tck/pom.xml
+++ b/tests/integration/microprofile/rest-client-tck/pom.xml
@@ -50,11 +50,11 @@
<artifactId>weld-se-core</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
+ <!--<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
- </dependency>
+ </dependency>-->
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
@@ -70,12 +70,13 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
+ <version>${testng6.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
- <version>2.27.2</version>
+ <version>${wiremock.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -103,7 +104,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>20.0</version>
+ <version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@@ -138,19 +139,19 @@
<dependency>
<groupId>org.jboss.arquillian.testng</groupId>
<artifactId>arquillian-testng-container</artifactId>
- <version>1.7.0.Alpha10</version>
+ <version>${arquillian.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-container-test-spi</artifactId>
- <version>1.7.0.Alpha10</version>
+ <version>${arquillian.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-embedded</artifactId>
- <version>3.0.0.Final</version>
+ <version>${arquillian.weld.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -199,12 +200,12 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
<configuration>
diff --git a/tests/integration/microprofile/rest-client-tck/tck-suite.xml b/tests/integration/microprofile/rest-client-tck/tck-suite.xml
index a317e79..05b1e48 100644
--- a/tests/integration/microprofile/rest-client-tck/tck-suite.xml
+++ b/tests/integration/microprofile/rest-client-tck/tck-suite.xml
@@ -1,7 +1,7 @@
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!--
- Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
@@ -24,14 +24,6 @@
<package name="org.eclipse.microprofile.rest.client.tck.*">
</package>
</packages>
- <classes>
- <class name="org.eclipse.microprofile.rest.client.tck.ProxyServerTest">
- <methods>
- <!--https://github.com/eclipse/microprofile-rest-client/pull/298-->
- <exclude name="testProxy"></exclude>
- </methods>
- </class>
- </classes>
</test>
</suite>
diff --git a/tests/integration/property-check/pom.xml b/tests/integration/property-check/pom.xml
index d4ee4ad..89cee9e 100644
--- a/tests/integration/property-check/pom.xml
+++ b/tests/integration/property-check/pom.xml
@@ -109,7 +109,7 @@
</plugin>
</plugins>
</build>
-
+
<profiles>
<profile>
<id>jdk19+</id>
diff --git a/tests/integration/property-check/src/test/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModelTest.java b/tests/integration/property-check/src/test/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModelTest.java
index 2a07280..ddb8e08 100644
--- a/tests/integration/property-check/src/test/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModelTest.java
+++ b/tests/integration/property-check/src/test/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModelTest.java
@@ -137,7 +137,7 @@
return Void.class;
}
});
- steam = steam.filter(Arrays.stream(predicates).reduce(x->true, Predicate::and));
+ steam = steam.filter(Arrays.stream(predicates).reduce(x -> true, Predicate::and));
return steam.collect(Collectors.toList());
}
diff --git a/tests/integration/reactive-streams/sse/pom.xml b/tests/integration/reactive-streams/sse/pom.xml
index 7e1d7f1..2eb2f4b 100644
--- a/tests/integration/reactive-streams/sse/pom.xml
+++ b/tests/integration/reactive-streams/sse/pom.xml
@@ -36,7 +36,7 @@
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams-tck</artifactId>
- <version>1.0.3</version>
+ <version>${reactive.streams.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -47,6 +47,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
+ <version>${testng6.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -93,7 +94,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
- <version>3.0.0-M3</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
diff --git a/tests/jmockit/pom.xml b/tests/jmockit/pom.xml
index 75afd57..e5e8246 100644
--- a/tests/jmockit/pom.xml
+++ b/tests/jmockit/pom.xml
@@ -92,7 +92,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
diff --git a/tests/osgi/functional/pom.xml b/tests/osgi/functional/pom.xml
index d5d4740..1f11e07 100644
--- a/tests/osgi/functional/pom.xml
+++ b/tests/osgi/functional/pom.xml
@@ -84,7 +84,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
- <version>${surefire.version}</version>
+ <version>${surefire.mvn.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
@@ -301,11 +301,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<scope>test</scope>
@@ -377,13 +372,6 @@
<scope>test</scope>
</dependency>
- <!-- logging -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.6.4</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<profiles>
diff --git a/tests/performance/benchmarks/pom.xml b/tests/performance/benchmarks/pom.xml
index 565c998..2b18b61 100644
--- a/tests/performance/benchmarks/pom.xml
+++ b/tests/performance/benchmarks/pom.xml
@@ -94,6 +94,10 @@
<type>pom</type>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jdk-http</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/AllBenchmarks.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/AllBenchmarks.java
index af66d45..bccc7c4 100644
--- a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/AllBenchmarks.java
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/AllBenchmarks.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -36,6 +36,7 @@
// .include(JacksonBenchmark.class.getSimpleName())
.include(LocatorBenchmark.class.getSimpleName())
.include(JerseyUriBuilderBenchmark.class.getSimpleName())
+ .include(HeadersServerBenchmark.class.getName())
// Measure throughput in seconds (ops/s).
.mode(Mode.Throughput)
.timeUnit(TimeUnit.SECONDS)
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersClientBenchmark.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersClientBenchmark.java
new file mode 100644
index 0000000..2c71a82
--- /dev/null
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersClientBenchmark.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.performance.benchmark;
+
+import com.sun.net.httpserver.HttpServer;
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
+import org.glassfish.jersey.tests.performance.benchmark.headers.HeadersMBRW;
+import org.glassfish.jersey.tests.performance.benchmark.headers.HeadersResource;
+import org.glassfish.jersey.tests.performance.benchmark.headers.HeadersApplication;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@Threads(4)
+@State(Scope.Benchmark)
+public class HeadersClientBenchmark {
+
+ static final String BASE_URI = "http://localhost:9009/headers";
+
+ private static final AtomicInteger counter = new AtomicInteger();
+ private static final MediaType MEDIA_PLAIN = MediaType.valueOf(HeadersResource.MEDIA_PLAIN);
+ private static final MediaType MEDIA_JSON = MediaType.valueOf(HeadersResource.MEDIA_JSON);
+
+ private static final boolean INCLUDE_INIT = false;
+
+ private volatile WebTarget webTarget;
+
+ @Setup
+ public void setUp() {
+ if (!INCLUDE_INIT) {
+ webTarget = ClientBuilder.newClient(config()).target(BASE_URI);
+ }
+ }
+
+ private WebTarget webTarget() {
+ return INCLUDE_INIT ? ClientBuilder.newClient(config()).target(BASE_URI) : webTarget;
+ }
+
+ private static class JdkServer {
+ private HttpServer server;
+ void start() {
+ server = JdkHttpServerFactory.createHttpServer(URI.create(BASE_URI), new HeadersApplication(), null, false);
+ server.start();
+ try {
+ TimeUnit.SECONDS.sleep(1L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ void stop() {
+ server.stop(1);
+ }
+ }
+
+ private static class GrizzlyServer {
+ private org.glassfish.grizzly.http.server.HttpServer httpServer;
+ void start() {
+ httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), new HeadersApplication(), null, false);
+ try {
+ httpServer.start();
+ TimeUnit.SECONDS.sleep(1L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ void stop() {
+ httpServer.shutdownNow();
+ }
+ }
+
+ @Benchmark
+ public void testGetPlainTextClient() {
+ WebTarget target = webTarget().path("headers/getPlain");
+ try (Response r = target.request(MEDIA_PLAIN).get()) {
+ consume(r, HeadersResource.CONTENT_PLAIN, MEDIA_PLAIN);
+ }
+ }
+
+ @Benchmark
+ public void testGetJsonClient() {
+ WebTarget target = webTarget().path("headers/getJson");
+ try (Response r = target.request(MEDIA_JSON).get()) {
+ consume(r, HeadersResource.CONTENT_PLAIN, MEDIA_JSON);
+ }
+ }
+
+ @Benchmark
+ public void testPostPlainTextClient() {
+ WebTarget target = webTarget().path("headers/postPlain");
+ try (Response r = target.request(MEDIA_PLAIN).post(Entity.entity(HeadersResource.CONTENT_PLAIN, MEDIA_PLAIN))) {
+ consume(r, HeadersResource.CONTENT_PLAIN, MEDIA_PLAIN);
+ }
+ }
+
+ @Benchmark
+ public void testPostJsonClient() {
+ WebTarget target = webTarget().path("headers/postJson");
+ try (Response r = target.request(MEDIA_JSON).post(Entity.entity(HeadersResource.CONTENT_PLAIN, MEDIA_JSON))) {
+ consume(r, HeadersResource.CONTENT_PLAIN, MEDIA_JSON);
+ }
+ }
+
+ @Benchmark
+ public void testRandomClient() {
+ switch (counter.incrementAndGet() % 4) {
+ case 0:
+ testGetJsonClient();
+ break;
+ case 1:
+ testGetPlainTextClient();
+ break;
+ case 2:
+ testPostJsonClient();
+ break;
+ case 3:
+ testPostPlainTextClient();
+ break;
+ }
+ }
+
+ private ClientConfig config() {
+ ClientConfig config = new ClientConfig();
+ config.property(CommonProperties.PROVIDER_DEFAULT_DISABLE, "ALL");
+ config.register(HeadersMBRW.class);
+ return config;
+ }
+
+ private void consume(Response response, String expectedContent, MediaType expectedMedia) {
+ if (response.getStatus() != 200) {
+ throw new IllegalStateException("Status:" + response.getStatus());
+ }
+ String content = response.readEntity(String.class);
+ if (!expectedContent.equals(content)) {
+ throw new IllegalStateException("Content:" + content);
+ }
+ if (!expectedMedia.equals(response.getMediaType())) {
+ throw new IllegalStateException("ContentType:" + response.getMediaType());
+ }
+ }
+
+ public static void main(String[] args) throws RunnerException {
+// JdkServer server = new JdkServer();
+ GrizzlyServer server = new GrizzlyServer();
+ server.start();
+
+ final Options opt = new OptionsBuilder()
+ // Register our benchmarks.
+ .include(HeadersClientBenchmark.class.getSimpleName())
+// .addProfiler(org.openjdk.jmh.profile.JavaFlightRecorderProfiler.class)
+ .build();
+
+ try {
+ new Runner(opt).run();
+ //new HeadersBenchmark().testGetJsonClient();
+ } finally {
+ server.stop();
+ }
+
+ }
+}
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersServerBenchmark.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersServerBenchmark.java
new file mode 100644
index 0000000..a72feef
--- /dev/null
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/HeadersServerBenchmark.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.performance.benchmark;
+
+import org.glassfish.jersey.server.ApplicationHandler;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ContainerResponse;
+import org.glassfish.jersey.test.util.server.ContainerRequestBuilder;
+import org.glassfish.jersey.tests.performance.benchmark.headers.HeadersApplication;
+import org.glassfish.jersey.tests.performance.benchmark.headers.HeadersResource;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import jakarta.ws.rs.core.MediaType;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@Threads(4)
+@State(Scope.Benchmark)
+public class HeadersServerBenchmark {
+ private static final AtomicInteger counter = new AtomicInteger();
+ private static final MediaType MEDIA_PLAIN = MediaType.valueOf(HeadersResource.MEDIA_PLAIN);
+ private static final MediaType MEDIA_JSON = MediaType.valueOf(HeadersResource.MEDIA_JSON);
+
+ private volatile ApplicationHandler handler;
+
+ @Setup
+ public void start() throws Exception {
+ handler = new ApplicationHandler(new HeadersApplication());
+ }
+
+ @TearDown
+ public void shutdown() {
+ if (counter.get() != 0) {
+ System.out.append("Executed ").append(String.valueOf(counter.get())).append(" requests");
+ }
+ }
+
+ @Benchmark
+ public void testGetPlainText() throws ExecutionException, InterruptedException {
+ ContainerRequest request = ContainerRequestBuilder
+ .from("headers/getPlain", "GET", handler.getConfiguration())
+ .accept(MEDIA_PLAIN)
+ .build();
+
+ ContainerResponse response = handler.apply(request).get();
+ consume(response, HeadersResource.CONTENT_PLAIN, MEDIA_PLAIN);
+ }
+
+ @Benchmark
+ public void testGetJson() throws ExecutionException, InterruptedException {
+ ContainerRequest request = ContainerRequestBuilder
+ .from("headers/getJson", "GET", handler.getConfiguration())
+ .accept(MEDIA_JSON)
+ .build();
+
+ ContainerResponse response = handler.apply(request).get();
+ consume(response, HeadersResource.CONTENT_PLAIN, MEDIA_JSON);
+ }
+
+ @Benchmark
+ public void testPostPlainText() throws ExecutionException, InterruptedException {
+ ContainerRequest request = ContainerRequestBuilder
+ .from("headers/postPlain", "POST", handler.getConfiguration())
+ .accept(MEDIA_PLAIN)
+ .type(MEDIA_PLAIN)
+ .entity(HeadersResource.CONTENT_PLAIN, handler)
+ .build();
+
+ ContainerResponse response = handler.apply(request).get();
+ consume(response, HeadersResource.CONTENT_PLAIN, MEDIA_PLAIN);
+ }
+
+ @Benchmark
+ public void testPostJson() throws ExecutionException, InterruptedException {
+ ContainerRequest request = ContainerRequestBuilder
+ .from("headers/postJson", "POST", handler.getConfiguration())
+ .accept(MEDIA_JSON)
+ .type(MEDIA_JSON)
+ .entity(HeadersResource.CONTENT_PLAIN, handler)
+ .build();
+
+ ContainerResponse response = handler.apply(request).get();
+ consume(response, HeadersResource.CONTENT_PLAIN, MEDIA_JSON);
+ }
+
+ @Benchmark
+ public void testRandomClient() throws ExecutionException, InterruptedException {
+ switch (counter.incrementAndGet() % 4) {
+ case 0:
+ testGetJson();
+ break;
+ case 1:
+ testGetPlainText();
+ break;
+ case 2:
+ testPostJson();
+ break;
+ case 3:
+ testPostPlainText();
+ break;
+ }
+ }
+
+ private void consume(ContainerResponse response, String expectedContent, MediaType expectedMedia) {
+ if (response.getStatus() != 200) {
+ throw new IllegalStateException("Status:" + response.getStatus());
+ }
+ String content = response.getEntity().toString();
+ if (!expectedContent.equals(content)) {
+ throw new IllegalStateException("Content:" + content);
+ }
+ if (!expectedMedia.equals(response.getMediaType())) {
+ throw new IllegalStateException("ContentType:" + response.getMediaType());
+ }
+ }
+
+ public static void main(String[] args) throws RunnerException {
+ final Options opt = new OptionsBuilder()
+ // Register our benchmarks.
+ .include(HeadersServerBenchmark.class.getSimpleName())
+// .addProfiler(org.openjdk.jmh.profile.JavaFlightRecorderProfiler.class)
+ .build();
+
+ new Runner(opt).run();
+
+// DEBUG:
+
+// try {
+// HeadersServerBenchmark benchmark = new HeadersServerBenchmark();
+// benchmark.start();
+// for (int i = 0; i != 5; i++) {
+// benchmark.testPostPlainText();
+// }
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+ }
+
+}
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersApplication.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersApplication.java
new file mode 100644
index 0000000..6ec127d
--- /dev/null
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersApplication.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.performance.benchmark.headers;
+
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+
+
+public class HeadersApplication extends ResourceConfig {
+ public HeadersApplication() {
+ register(HeadersResource.class).register(HeadersMBRW.class);
+
+ // Turn off Monitoring to not affect benchmarks.
+ property(ServerProperties.MONITORING_ENABLED, false);
+ property(ServerProperties.MONITORING_STATISTICS_ENABLED, false);
+ property(ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED, false);
+
+ property(ServerProperties.WADL_FEATURE_DISABLE, true);
+ property(CommonProperties.PROVIDER_DEFAULT_DISABLE, "ALL");
+ }
+}
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersMBRW.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersMBRW.java
new file mode 100644
index 0000000..9aeda0c
--- /dev/null
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersMBRW.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.performance.benchmark.headers;
+
+import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;
+import org.glassfish.jersey.message.internal.ReaderWriter;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class HeadersMBRW implements MessageBodyReader<String>, MessageBodyWriter<String> {
+
+ private static final JacksonJsonProvider jackson = new JacksonJsonProvider();
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return (type == String.class && HeadersResource.MEDIA_PLAIN.equals(mediaType.toString()))
+ || (type == String.class && HeadersResource.MEDIA_JSON.equals(mediaType.toString()));
+ }
+
+ @Override
+ public String readFrom(Class<String> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ switch (mediaType.toString()) {
+ case HeadersResource.MEDIA_PLAIN:
+ return ReaderWriter.readFromAsString(entityStream, MediaType.TEXT_PLAIN_TYPE);
+ case HeadersResource.MEDIA_JSON:
+ return jackson.readFrom((Class<Object>) (Class) type, genericType, annotations, mediaType,
+ httpHeaders, entityStream).toString();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return isReadable(type, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public void writeTo(String s, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+ throws IOException, WebApplicationException {
+ switch (mediaType.toString()) {
+ case HeadersResource.MEDIA_PLAIN:
+ ReaderWriter.writeToAsString(s, entityStream, MediaType.TEXT_PLAIN_TYPE);
+ break;
+ case HeadersResource.MEDIA_JSON:
+ jackson.writeTo(s, type, genericType, annotations, MediaType.APPLICATION_JSON_TYPE, httpHeaders, entityStream);
+ break;
+ }
+ }
+}
diff --git a/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersResource.java b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersResource.java
new file mode 100644
index 0000000..f7f3cee
--- /dev/null
+++ b/tests/performance/benchmarks/src/main/java/org/glassfish/jersey/tests/performance/benchmark/headers/HeadersResource.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.performance.benchmark.headers;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+
+@Path("/headers")
+public class HeadersResource {
+ public static final String MEDIA_PLAIN = "myapplication/someplaintext+someothertoolongtype";
+ public static final String MEDIA_JSON = "myapplication/somejson+someradiculouslylongtype";
+
+ public static final String CONTENT_PLAIN = "some plain text content does not matter";
+ public static final String CONTENT_JSON = "\"" + CONTENT_PLAIN + "\"";
+
+ @GET
+ @Produces(MEDIA_PLAIN)
+ @Path("getPlain")
+ public String getMediaPlain() {
+ return CONTENT_PLAIN;
+ }
+
+ @POST
+ @Produces(MEDIA_PLAIN)
+ @Consumes(MEDIA_PLAIN)
+ @Path("postPlain")
+ public String postMediaPlain(String content) {
+ if (!CONTENT_PLAIN.equals(content)) {
+ throw new WebApplicationException(Response.Status.EXPECTATION_FAILED);
+ }
+ return CONTENT_PLAIN;
+ }
+
+ @GET
+ @Produces(MEDIA_JSON)
+ @Path("getJson")
+ public Response getJson() {
+ return Response.ok(CONTENT_PLAIN, MEDIA_JSON).build();
+ }
+
+ @POST
+ @Produces(MEDIA_JSON)
+ @Consumes(MEDIA_JSON)
+ @Path("postJson")
+ public Response postJson(String json) {
+ if (!CONTENT_PLAIN.equals(json)) {
+ throw new WebApplicationException(Response.Status.EXPECTATION_FAILED);
+ }
+ return Response.ok(CONTENT_PLAIN, MEDIA_JSON).build();
+ }
+
+}
diff --git a/tests/performance/test-cases/pom.xml b/tests/performance/test-cases/pom.xml
index 60c2b73..31f2c11 100644
--- a/tests/performance/test-cases/pom.xml
+++ b/tests/performance/test-cases/pom.xml
@@ -75,7 +75,7 @@
<phase>package</phase>
<!-- append to the packaging phase. -->
<goals>
- <goal>attached</goal>
+ <goal>single</goal>
<!-- goals == mojos -->
</goals>
<configuration>
diff --git a/tests/release-test/README.MD b/tests/release-test/README.MD
new file mode 100644
index 0000000..395ec2a
--- /dev/null
+++ b/tests/release-test/README.MD
@@ -0,0 +1,20 @@
+[//]: # " Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. "
+[//]: # " "
+[//]: # " This program and the accompanying materials are made available under the "
+[//]: # " terms of the Eclipse Public License v. 2.0, which is available at "
+[//]: # " http://www.eclipse.org/legal/epl-2.0. "
+[//]: # " "
+[//]: # " This Source Code may also be made available under the following Secondary "
+[//]: # " Licenses when the conditions for such availability set forth in the "
+[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, "
+[//]: # " version 2 with the GNU Classpath Exception, which is available at "
+[//]: # " https://www.gnu.org/software/classpath/license.html. "
+[//]: # " "
+[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "
+
+This module is to check the built artifacts before release.
+
+The module can check Jersey 2.x, 3.0.x, and 3.1.x versions.
+
+Usage:
+ * mvn test -Djersey.version=<version> [-Pstaging]
diff --git a/tests/release-test/pom.xml b/tests/release-test/pom.xml
new file mode 100644
index 0000000..33eb1cf
--- /dev/null
+++ b/tests/release-test/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.ee4j</groupId>
+ <artifactId>project</artifactId>
+ <version>1.0.8</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.glassfish.jersey.tests</groupId>
+ <artifactId>release-test</artifactId>
+ <version>2.37-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>jersey-release-test</name>
+
+ <description>Jersey post-release validation tests</description>
+
+ <properties>
+ <jersey.version>${jersey.version}</jersey.version> <!-- Must pass using -Djersey.version= -->
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <maven.version>3.8.6</maven.version>
+ <maven.resolver.version>1.7.3</maven.resolver.version> <!-- 1.8.2 does not work-->
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>3.0.0-M7</version>
+ <configuration>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <enableAssertions>false</enableAssertions>
+ <includes>
+ <include>**/DownloadBomPomDependencies.java</include>
+ <include>**/*Test.class</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey</groupId>
+ <artifactId>jersey-bom</artifactId>
+ <version>${jersey.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.13.2</version>
+ <scope>test</scope>
+ <!-- maven-plugin-testing-harness does not work with junit 5 -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.plugin-testing</groupId>
+ <artifactId>maven-plugin-testing-harness</artifactId>
+ <version>3.3.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.resolver</groupId>
+ <artifactId>maven-resolver-connector-basic</artifactId>
+ <version>${maven.resolver.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.resolver</groupId>
+ <artifactId>maven-resolver-transport-http</artifactId>
+ <version>${maven.resolver.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java
new file mode 100644
index 0000000..43e5327
--- /dev/null
+++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/ClassVersionChecker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.glassfish.jersey.test.artifacts;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+class ClassVersionChecker {
+ static TestResult checkClassVersion(JarFile jar, JarEntry entry, Properties properties) throws IOException {
+ final String jerseyVersion = MavenUtil.getJerseyVersion(properties);
+ final int minVersion = jerseyVersion.startsWith("3.1") ? 11 : 8;
+ return checkClassVersion(jar.getInputStream(entry), jar.getName() + File.separator + entry.getName(), minVersion);
+ }
+
+ private static TestResult checkClassVersion(InputStream inputStream, String filename, int version) throws IOException {
+ TestResult result = new TestResult();
+ DataInputStream in = new DataInputStream(inputStream);
+
+ int magic = in.readInt();
+ if (magic != -889275714) {
+ result.exception().append(filename).println(" is not a valid class!");
+ }
+
+ int minor = in.readUnsignedShort();
+ int major = in.readUnsignedShort();
+ int classVersion = convertMajorMinorToSE(major, minor);
+ TestResult.MessageBuilder builder = classVersion <= version ? result.ok() : result.exception();
+ builder.append(filename).append(": ").append(major).append(".").append(minor).append(" = JDK ")
+ .println(String.valueOf(classVersion));
+ in.close();
+ return result;
+ }
+
+ private static int convertMajorMinorToSE(int major, int minor) {
+ int comp = (major - 44 + minor);
+ return comp;
+ }
+}
diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java
new file mode 100644
index 0000000..dd31588
--- /dev/null
+++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyPair.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.glassfish.jersey.test.artifacts;
+
+import java.util.Arrays;
+
+class DependencyPair {
+ private final String groupId;
+ private final String artifactId;
+
+ DependencyPair(String groupId, String artifactId) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ }
+
+ String artifactId() {
+ return artifactId;
+ }
+
+ String groupId() {
+ return groupId;
+ }
+
+ static DependencyPair[] concat(DependencyPair[] first, DependencyPair[] second) {
+ DependencyPair[] result = Arrays.copyOf(first, first.length + second.length);
+ System.arraycopy(second, 0, result, first.length, second.length);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return groupId + ':' + artifactId;
+ }
+}
diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java
new file mode 100644
index 0000000..5df3bc1
--- /dev/null
+++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/DependencyResolver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.glassfish.jersey.test.artifacts;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+
+import java.util.List;
+
+/**
+ *
+ * @author lukas
+ */
+final class DependencyResolver {
+ static Artifact resolveArtifact(org.apache.maven.model.Dependency d, List<RemoteRepository> remoteRepos,
+ RepositorySystem repoSystem, RepositorySystemSession repoSession)
+ throws ArtifactResolutionException {
+ DefaultArtifact artifact = new DefaultArtifact(
+ d.getGroupId(), d.getArtifactId(), d.getClassifier(), d.getType(), d.getVersion()
+ );
+ ArtifactRequest request = new ArtifactRequest();
+ request.setArtifact(artifact);
+ request.setRepositories(remoteRepos);
+ return repoSystem.resolveArtifact(repoSession, request).getArtifact();
+ }
+}
\ No newline at end of file
diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java
new file mode 100644
index 0000000..2c5b3a2
--- /dev/null
+++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/MavenUtil.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.glassfish.jersey.test.artifacts;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Stream;
+
+public final class MavenUtil {
+
+ static final String JERSEY_VERSION = "jersey.version";
+ private static final String PROJECT_VERSION = "project.version";
+
+ static File getArtifactJar(File repositoryRoot, Dependency dependency, Properties properties) {
+ return getArtifactFile(repositoryRoot, dependency, properties, "jar");
+ }
+
+ private static File getArtifactFile(File repositoryRoot, Dependency dependency, Properties properties, String extension) {
+ StringBuilder fileSuffix = new StringBuilder();
+ String groupIdParts[] = dependency.getGroupId().split("\\.");
+ for (String groupIdPart : groupIdParts) {
+ fileSuffix.append(groupIdPart).append(File.separator);
+ }
+ String artifactIdParts[] = dependency.getArtifactId().split("\\.");
+ for (String artifactIdPart : artifactIdParts) {
+ fileSuffix.append(artifactIdPart).append(File.separator);
+ }
+ String version = MavenUtil.getDependencyVersion(dependency, properties);
+ fileSuffix.append(version).append(File.separator);
+ fileSuffix.append(dependency.getArtifactId()).append('-').append(version).append(".").append(extension);
+ return new File(repositoryRoot, fileSuffix.toString());
+ }
+
+ static String getDependencyVersion(Dependency dependency, Properties properties) {
+ String version = dependency.getVersion();
+ if (version.startsWith("${") && version.endsWith("}")) {
+ String property = version.substring(2, version.length() - 1);
+ final String value;
+ switch (property) {
+ case JERSEY_VERSION: // in pom.xml
+ case PROJECT_VERSION: // in bom.pom
+ value = getJerseyVersion(properties);
+ break;
+ default:
+ value = properties.getProperty(property);
+ break;
+ }
+ version = value == null ? version : value;
+ }
+ return version;
+ }
+
+ static File getLocalMavenRepository() {
+ String folder = System.getProperty("localRepository");
+ return new File(folder);
+ }
+
+ static Properties getMavenProperties() {
+ try {
+ Model model = getModelFromFile("pom.xml");
+ return model.getProperties();
+ } catch (XmlPullParserException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Stream<Dependency> keepJerseyJars(Stream<Dependency> stream, DependencyPair... keep) {
+ return stream.filter(dependency -> {
+ for (DependencyPair pair : keep) {
+ if (dependency.getGroupId().equals(pair.groupId()) && dependency.getArtifactId().equals(pair.artifactId())) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ static Stream<Dependency> streamJerseyJars() throws IOException, XmlPullParserException {
+ Model model = getModelFromFile("pom.xml");
+ List<Dependency> deps = getBomPomDependencies(model);
+
+ return deps.stream()
+ .filter(dep -> dep.getGroupId().startsWith("org.glassfish.jersey"))
+ .filter(dep -> dep.getType().equals("jar"));
+ }
+
+ private static Model getModelFromFile(String fileName) throws IOException, XmlPullParserException {
+ File pomFile = new File(fileName);
+ return getModelFromFile(pomFile);
+ }
+
+ private static Model getModelFromFile(File file) throws IOException, XmlPullParserException {
+ MavenXpp3Reader mavenReader = new MavenXpp3Reader();
+ try (FileReader fileReader = new FileReader(file)) {
+ Model model = mavenReader.read(fileReader);
+ return model;
+ }
+ }
+
+ private static List<Dependency> getBomPomDependencies(Model model) throws IOException, XmlPullParserException {
+ Dependency bomPom = null;
+ List<Dependency> dependencies = model.getDependencyManagement().getDependencies();
+ for (Dependency dependency : dependencies) {
+ if (dependency.getGroupId().equals("org.glassfish.jersey") && dependency.getArtifactId().equals("jersey-bom")) {
+ bomPom = dependency;
+ break;
+ }
+ }
+ if (bomPom == null) {
+ throw new IllegalStateException("Bom pom not found");
+ }
+ File pom = getArtifactFile(getLocalMavenRepository(), bomPom, model.getProperties(), "pom");
+ Model bomPomModel = getModelFromFile(pom);
+ return bomPomModel.getDependencyManagement().getDependencies();
+ }
+
+ static String getJerseyVersion(Properties properties) {
+ String property = properties.getProperty(JERSEY_VERSION); // when it is in the pom.file
+ if (property == null || property.startsWith("${")) {
+ property = System.getProperty(JERSEY_VERSION); // not in pom, but -Djersey.version
+ }
+ if (property == null || property.startsWith("${")) {
+ throw new IllegalStateException("Property " + JERSEY_VERSION + " not set (-Djersey.version=)");
+ }
+ return property;
+ }
+
+ /* Unused at the moment, but could be useful in the future in the case of profiles are needed */
+ private static List<Dependency> getProfileDependency(Model model) {
+ List<Dependency> profileDependencies = Collections.EMPTY_LIST;
+ List<Profile> profiles = model.getProfiles();
+ String activeProfile = getActiveProfile();
+ for (Profile profile : profiles) {
+ if (activeProfile.equals(profile.getId())) {
+ profileDependencies = profile.getDependencies();
+ break;
+ }
+ }
+ return profileDependencies;
+ }
+
+ private static String getActiveProfile() {
+ String profileId = System.getProperty("profileId"); // set this to the surefire plugin
+ return profileId;
+ }
+}
diff --git a/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java
new file mode 100644
index 0000000..172c596
--- /dev/null
+++ b/tests/release-test/src/main/java/org/glassfish/jersey/test/artifacts/TestResult.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.glassfish.jersey.test.artifacts;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+class TestResult {
+ private List<String> oks = new LinkedList<>();
+ private List<String> exceptions = new LinkedList<>();
+
+ MessageBuilder ok() {
+ return new MessageBuilder(oks);
+ }
+
+ MessageBuilder exception() {
+ return new MessageBuilder(exceptions);
+ }
+ boolean result() {
+ for (String ok : oks) {
+ System.out.append("(pass) ").print(ok);
+ }
+
+ for (String exception : exceptions) {
+ System.out.append("\u001b[31;1m(FAIL) ").append(exception).print("\u001b[0m");
+ }
+
+ return exceptions.isEmpty();
+ }
+
+ public TestResult append(TestResult result) throws IOException {
+ oks.addAll(result.oks);
+ exceptions.addAll(result.exceptions);
+ return this;
+ }
+
+ class MessageBuilder implements Appendable {
+ final List<String> list;
+ final StringBuilder builder = new StringBuilder();
+
+ MessageBuilder(List<String> list) {
+ this.list = list;
+ }
+
+ @Override
+ public MessageBuilder append(CharSequence csq) throws IOException {
+ builder.append(csq);
+ return this;
+ }
+
+ public MessageBuilder append(int i) throws IOException {
+ builder.append(i);
+ return this;
+ }
+
+ @Override
+ public MessageBuilder append(CharSequence csq, int start, int end) throws IOException {
+ builder.append(csq, start, end);
+ return this;
+ }
+
+ @Override
+ public MessageBuilder append(char c) throws IOException {
+ builder.append(c);
+ return this;
+ }
+
+ public TestResult println(String message) {
+ builder.append(message).append('\n');
+ list.add(builder.toString());
+ return TestResult.this;
+ }
+ }
+}
diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java
new file mode 100644
index 0000000..ef31d4e
--- /dev/null
+++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/DownloadBomPomDependencies.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.glassfish.jersey.test.artifacts;
+
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.DefaultServiceLocator;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
+import org.eclipse.aether.spi.connector.transport.TransporterFactory;
+import org.eclipse.aether.transport.http.HttpTransporterFactory;
+
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
+import org.junit.Test;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+public class DownloadBomPomDependencies extends AbstractMojoTestCase {
+
+ @Test
+ public void testDownloadBomPomDependencies() throws Exception {
+// RepositorySystem repositorySystem = (RepositorySystem) lookup(RepositorySystem.class.getName());
+ DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+ locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
+ locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
+ RepositorySystem repositorySystem = locator.getService(RepositorySystem.class);
+
+ RepositorySystemSession repoSession = getRepoSession(repositorySystem);
+ List<RemoteRepository> remoteRepos = getRemoteRepositories(repoSession);
+
+ Properties properties = MavenUtil.getMavenProperties();
+ String jerseyVersion = MavenUtil.getJerseyVersion(properties);
+ List<Dependency> memberDeps = MavenUtil.streamJerseyJars().collect(Collectors.toList());
+ for (Dependency member : memberDeps) {
+ member.setVersion(jerseyVersion);
+ Artifact m = DependencyResolver.resolveArtifact(member, remoteRepos, repositorySystem, repoSession);
+ System.out.append("Resolved ").append(member.getGroupId()).append(":").append(member.getArtifactId()).append(":")
+ .append(member.getVersion()).append(" to ").println(m.getFile().getName());
+ }
+ }
+
+ private List<RemoteRepository> getRemoteRepositories(RepositorySystemSession session) throws Exception {
+ File pom = lookupResourcesPom("/release-test-pom.xml");
+ MavenExecutionRequest request = new DefaultMavenExecutionRequest();
+ request.setPom(pom);
+ request.addActiveProfile("staging");
+ ProjectBuildingRequest buildingRequest = request
+ .getProjectBuildingRequest()
+ .setRepositorySession(session)
+ .setResolveDependencies(true);
+
+ ProjectBuilder projectBuilder = lookup(ProjectBuilder.class);
+ ProjectBuildingResult projectBuildingResult = projectBuilder.build(pom, buildingRequest);
+ MavenProject project = projectBuildingResult.getProject();
+
+ List<RemoteRepository> remoteArtifactRepositories = project.getRemoteProjectRepositories();
+ return remoteArtifactRepositories;
+ }
+
+ private static RepositorySystemSession getRepoSession(RepositorySystem repositorySystem) {
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+ LocalRepository localRepo = new LocalRepository(MavenUtil.getLocalMavenRepository().getAbsolutePath());
+ session.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(session, localRepo));
+ return session;
+ }
+
+ private static File lookupResourcesPom(String pomFile) throws URISyntaxException {
+ URL resource = DownloadBomPomDependencies.class.getResource(pomFile);
+ if (resource == null) {
+ throw new IllegalStateException("Pom file " + pomFile + " was not located on classpath!");
+ }
+ File file = new File(resource.toURI());
+ if (!file.exists()) {
+ throw new IllegalStateException("Cannot locate test pom xml file!");
+ }
+ return file;
+ }
+}
diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java
new file mode 100644
index 0000000..8da0835
--- /dev/null
+++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/ManifestTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.glassfish.jersey.test.artifacts;
+
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+
+public class ManifestTest {
+ private static final File localRepository = MavenUtil.getLocalMavenRepository();
+ private static final Properties properties = MavenUtil.getMavenProperties();
+
+ private static final String BUNDLE_NAME_ATTRIBUTE = "Bundle-Name";
+ private static final String BUNDLE_VERSION_ATTRIBUTE = "Bundle-Version";
+ private static final String [] EXCLUDED_JARS = {"test", "rx-client", "oauth", "weld2-se", "spring",
+ "servlet-portability", /* obsolete */
+ "helidon-connector", /* Helidon does not contain OSGi headers */
+ "grizzly-connector", /* Limited maintenance */
+ };
+
+ @Test
+ public void testHasOsgiManifest() throws IOException, XmlPullParserException {
+ TestResult testResult = new TestResult();
+ List<File> jars = MavenUtil.streamJerseyJars()
+ .filter(dependency -> {
+ for (String excluded : EXCLUDED_JARS) {
+ if (dependency.getArtifactId().contains(excluded)) {
+ return false;
+ }
+ }
+ return true;
+ })
+ .map(dependency -> MavenUtil.getArtifactJar(localRepository, dependency, properties))
+ .collect(Collectors.toList());
+
+ for (String ATTRIBUTE : new String[]{BUNDLE_NAME_ATTRIBUTE, BUNDLE_VERSION_ATTRIBUTE}) {
+ for (File jar : jars) {
+ JarFile jarFile = new JarFile(jar);
+ String value = jarFile.getManifest().getMainAttributes().getValue(ATTRIBUTE);
+ TestResult.MessageBuilder builder = value != null ? testResult.ok() : testResult.exception();
+ builder.append(jar.getName()).append(value == null ? " DOES NOT CONTAIN " : " CONTAINS ")
+ .append(ATTRIBUTE).println(" attribute");
+ }
+ }
+
+ //Assertions.assertTrue(testResult.result(), "Some error occurred, see previous messages");
+ Assert.assertTrue("Some error occurred, see previous messages", testResult.result());
+ }
+
+}
diff --git a/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java
new file mode 100644
index 0000000..deef29a
--- /dev/null
+++ b/tests/release-test/src/test/java/org/glassfish/jersey/test/artifacts/MultiReleaseTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.glassfish.jersey.test.artifacts;
+
+import org.apache.maven.model.Dependency;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+public class MultiReleaseTest {
+ private static final String s = "";
+ private static final File localRepository = MavenUtil.getLocalMavenRepository();
+ private static final Properties properties = MavenUtil.getMavenProperties();
+
+ private static final DependencyPair[] jdk11multiRelease = jdk11multiRelease(properties);
+ private static final DependencyPair[] jdk12multiRelease = jdk12multiRelease(properties);
+ private static final DependencyPair[] jdk17multiRelease = jdk17multiRelease(properties);
+
+ @Test
+ public void testIsJdkMultiRelease() throws IOException, XmlPullParserException {
+ TestResult result = testJdkVersions("11", jdk11multiRelease);
+ result.append(testJdkVersions("12", jdk12multiRelease));
+ result.append(testJdkVersions("17", jdk17multiRelease));
+ //Assertions.assertTrue(result.result(), "Some error occurred, see previous messages");
+ Assert.assertTrue("Some error occurred, see previous messages", result.result());
+ }
+
+ private static TestResult testJdkVersions(String version, DependencyPair... dependencies)
+ throws XmlPullParserException, IOException {
+ final TestResult result = new TestResult();
+ if (dependencies == null || dependencies.length == 0) {
+ return result;
+ }
+
+ Stream<Dependency> deps = MavenUtil.streamJerseyJars();
+ List<File> files = MavenUtil.keepJerseyJars(deps, dependencies)
+ .map(dependency -> MavenUtil.getArtifactJar(localRepository, dependency, properties))
+ .collect(Collectors.toList());
+
+ //Assertions.assertEquals(dependencies.length, files.size(), "Some jdk " + version + " dependencies not found");
+ if (dependencies.length != files.size()) {
+ System.out.println("Expected:");
+ for (DependencyPair pair : dependencies) {
+ System.out.println(pair);
+ }
+ System.out.println("Resolved:");
+ for (File file : files) {
+ System.out.println(file.getName());
+ }
+ Assert.assertEquals("Some jdk " + version + " dependencies not found", dependencies.length, files.size());
+ }
+
+ for (File jar : files) {
+ JarFile jarFile = new JarFile(jar);
+ if (!jarFile.isMultiRelease()) {
+ result.exception().append("Not a multirelease jar ").append(jar.getName()).println("!");
+ }
+ ZipEntry versions = jarFile.getEntry("META-INF/versions/" + version);
+ if (versions == null) {
+ result.exception().append("No classes for JDK ").append(version).append(" for ").println(jar.getName());
+ }
+ result.ok().append("Classes for JDK ").append(version).append(" found for ").println(jar.getName());
+
+ Optional<JarEntry> file = jarFile.stream()
+ .filter(entry -> !entry.isDirectory())
+ .filter(entry -> !entry.getName().contains("versions"))
+ .filter(entry -> entry.getName().endsWith(".class"))
+ .findAny();
+ JarEntry jarEntry = file.get();
+ result.append(ClassVersionChecker.checkClassVersion(jarFile, jarEntry, properties));
+ }
+
+ return result;
+ }
+
+ private static DependencyPair[] jdk11multiRelease(Properties properties) {
+ String jerseyVersion = MavenUtil.getJerseyVersion(properties);
+ if (jerseyVersion.startsWith("3.0")) {
+ return jdk11multiRelease30();
+ } else if (jerseyVersion.startsWith("3")) {
+ return jdk11multiRelease31();
+ }
+ return jdk11multiRelease2();
+ }
+
+ private static DependencyPair[] jdk11multiRelease2() {
+ return new DependencyPair[] {
+ new DependencyPair("org.glassfish.jersey.bundles", "jaxrs-ri"),
+ new DependencyPair("org.glassfish.jersey.core", "jersey-common")
+ };
+ }
+
+ private static DependencyPair[] jdk11multiRelease30() {
+ DependencyPair[] pairs30 = {
+ new DependencyPair("org.glassfish.jersey.containers", "jersey-container-jetty-http"),
+ new DependencyPair("org.glassfish.jersey.containers", "jersey-container-jetty-servlet"),
+ new DependencyPair("org.glassfish.jersey.test-framework.providers", "jersey-test-framework-provider-jetty")
+ };
+ return DependencyPair.concat(jdk11multiRelease2(), pairs30);
+ }
+
+ private static DependencyPair[] jdk11multiRelease31() {
+ return new DependencyPair[]{};
+ }
+
+ private static DependencyPair[] jdk12multiRelease(Properties properties) {
+ return new DependencyPair[]{
+ new DependencyPair("org.glassfish.jersey.ext", "jersey-wadl-doclet")
+ };
+ }
+
+ private static DependencyPair[] jdk17multiRelease(Properties properties) {
+ String jerseyVersion = MavenUtil.getJerseyVersion(properties);
+ if (jerseyVersion.startsWith("3")) {
+ return new DependencyPair[] {
+ new DependencyPair("org.glassfish.jersey.connectors", "jersey-helidon-connector"),
+ new DependencyPair("org.glassfish.jersey.ext", "jersey-spring6")
+ };
+ }
+ return new DependencyPair[]{};
+ }
+}
diff --git a/tests/release-test/src/test/resources/release-test-pom.xml b/tests/release-test/src/test/resources/release-test-pom.xml
new file mode 100644
index 0000000..d8aa486
--- /dev/null
+++ b/tests/release-test/src/test/resources/release-test-pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.ee4j</groupId>
+ <artifactId>project</artifactId>
+ <version>1.0.7</version>
+ </parent>
+
+ <groupId>org.glassfish.jersey.tests</groupId>
+ <artifactId>release-test-test</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+</project>
\ No newline at end of file
diff --git a/tools/jersey-doc-modulelist-maven-plugin/pom.xml b/tools/jersey-doc-modulelist-maven-plugin/pom.xml
index dd83a1c..b316d42 100644
--- a/tools/jersey-doc-modulelist-maven-plugin/pom.xml
+++ b/tools/jersey-doc-modulelist-maven-plugin/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.eclipse.ee4j</groupId>
<artifactId>project</artifactId>
- <version>1.0.7</version>
+ <version>1.0.8</version>
</parent>
<groupId>org.glassfish.jersey.tools.plugins</groupId>
diff --git a/tools/jersey-release-notes-maven-plugin/pom.xml b/tools/jersey-release-notes-maven-plugin/pom.xml
index 3ede899..195212a 100644
--- a/tools/jersey-release-notes-maven-plugin/pom.xml
+++ b/tools/jersey-release-notes-maven-plugin/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.eclipse.ee4j</groupId>
<artifactId>project</artifactId>
- <version>1.0.6</version>
+ <version>1.0.8</version>
</parent>
<groupId>org.glassfish.jersey.tools.plugins</groupId>