Merge remote-tracking branch 'origin/2.x' into 'origin/3.0' Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/containers/jdk-http/pom.xml b/containers/jdk-http/pom.xml index 659b4dc..f81c101 100644 --- a/containers/jdk-http/pom.xml +++ b/containers/jdk-http/pom.xml
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2025 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 @@ -34,12 +34,6 @@ <dependencies> <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - <scope>test</scope> - <version>${commons.io.version}</version> - </dependency> - <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> <scope>test</scope>
diff --git a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java index 01e9e34..d8a2798 100644 --- a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java +++ b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025 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 @@ -30,9 +30,9 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; -import org.apache.commons.io.IOUtils; import org.glassfish.jersey.SslConfigurator; import org.glassfish.jersey.internal.util.JdkVersion; +import org.glassfish.jersey.message.internal.ReaderWriter; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.AfterEach; @@ -195,9 +195,9 @@ final SslConfigurator sslConfigClient = SslConfigurator.newInstance() - .trustStoreBytes(IOUtils.toByteArray(trustStore)) + .trustStoreBytes(ReaderWriter.readFromAsBytes(trustStore)) .trustStorePassword(TRUSTSTORE_CLIENT_PWD) - .keyStoreBytes(IOUtils.toByteArray(keyStore)) + .keyStoreBytes(ReaderWriter.readFromAsBytes(keyStore)) .keyPassword(KEYSTORE_CLIENT_PWD); return sslConfigClient.createSSLContext(); @@ -208,9 +208,9 @@ final InputStream keyStore = JdkHttpsServerTest.class.getResourceAsStream(KEYSTORE_SERVER_FILE); final SslConfigurator sslConfigServer = SslConfigurator.newInstance() - .keyStoreBytes(IOUtils.toByteArray(keyStore)) + .keyStoreBytes(ReaderWriter.readFromAsBytes(keyStore)) .keyPassword(KEYSTORE_SERVER_PWD) - .trustStoreBytes(IOUtils.toByteArray(trustStore)) + .trustStoreBytes(ReaderWriter.readFromAsBytes(trustStore)) .trustStorePassword(TRUSTSTORE_SERVER_PWD); return sslConfigServer.createSSLContext();
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java index 35fcef5..698fb39 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java
@@ -63,8 +63,12 @@ * @param response JAX-RS response to be used to initialize the response context. */ public ClientResponse(final ClientRequest requestContext, final Response response) { - this(response.getStatusInfo(), requestContext); - this.headers(OutboundJaxrsResponse.from(response, requestContext.getConfiguration()).getContext().getStringHeaders()); + super(requestContext.getConfiguration(), + OutboundJaxrsResponse.from(response, requestContext.getConfiguration()).getContext().getStringHeaders(), + false + ); + this.requestContext = requestContext; + init(response.getStatusInfo(), requestContext, requestContext.getUri()); final Object entity = response.getEntity(); if (entity != null) { @@ -122,10 +126,13 @@ */ public ClientResponse(Response.StatusType status, ClientRequest requestContext, URI resolvedRequestUri) { super(requestContext.getConfiguration()); + this.requestContext = requestContext; + init(status, requestContext, resolvedRequestUri); + } + + private void init(Response.StatusType status, ClientRequest requestContext, URI resolvedRequestUri) { this.status = status; this.resolvedUri = resolvedRequestUri; - this.requestContext = requestContext; - setWorkers(requestContext.getWorkers()); }
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java index caffa4d..ae487bf 100644 --- a/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java +++ b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
@@ -16,19 +16,30 @@ package org.glassfish.jersey.client; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import jakarta.ws.rs.Priorities; import jakarta.ws.rs.Produces; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.ClientRequestContext; import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.client.ClientResponseContext; +import jakarta.ws.rs.client.ClientResponseFilter; +import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.GenericEntity; +import jakarta.ws.rs.core.Link; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.core.Variant; import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.ReaderInterceptor; +import jakarta.ws.rs.ext.ReaderInterceptorContext; +import jakarta.ws.rs.ext.RuntimeDelegate; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -37,18 +48,25 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; -//import static java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.assertEquals; public class AbortTest { private static final String TEXT_CSV = "text/csv"; + private static final String TEXT_HEADER = "text/header"; private static final String EXPECTED_CSV = "hello;goodbye\nsalutations;farewell"; private static final List<List<String>> CSV_LIST = Arrays.asList( Arrays.asList("hello", "goodbye"), Arrays.asList("salutations", "farewell") ); + private final String entity = "HI"; + private final String header = "CUSTOM_HEADER"; + @Test void testAbortWithGenericEntity() { @@ -77,7 +95,6 @@ @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { - System.out.println(genericType.getTypeName()); return List.class.isAssignableFrom(type) && genericType instanceof ParameterizedType && ((ParameterizedType) genericType).getActualTypeArguments()[0] instanceof ParameterizedType && String.class.equals(((ParameterizedType) ((ParameterizedType) genericType).getActualTypeArguments()[0]) @@ -99,4 +116,172 @@ } } + @Test + void testAbortWithMBWWritingHeaders() { + try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() { + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.abortWith(Response.ok(entity, TEXT_HEADER).build()); + } + }).register(new MessageBodyWriter<String>() { + + @Override + public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return mediaType.toString().equals(TEXT_HEADER); + } + + @Override + public void writeTo(String s, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, + MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, + WebApplicationException { + httpHeaders.add(header, entity); + entityStream.write(s.getBytes()); + } + }, Priorities.USER - 1).target("http://localhost:8080").request().get()) { + Assertions.assertEquals(entity, response.readEntity(String.class)); + Assertions.assertEquals(entity, response.getHeaderString(header)); + } + } + + @Test + void testInterceptorHeaderAdd() { + final String header2 = "CUSTOM_HEADER_2"; + + try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() { + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.abortWith(Response.ok().entity(entity).build()); + } + }).register(new ReaderInterceptor() { + @Override + public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException { + MultivaluedMap<String, String> headers = context.getHeaders(); + headers.put(header, Collections.singletonList(entity)); + headers.add(header2, entity); + return context.proceed(); + } + }) + .target("http://localhost:8080").request().get()) { + Assertions.assertEquals(entity, response.readEntity(String.class)); + Assertions.assertEquals(entity, response.getHeaderString(header)); + Assertions.assertEquals(entity, response.getHeaderString(header2)); + } + } + + @Test + void testInterceptorHeaderIterate() { + final AtomicReference<String> originalHeader = new AtomicReference<>(); + + try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() { + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.abortWith(Response.ok().header(header, header).entity(entity).build()); + } + }).register(new ReaderInterceptor() { + @Override + public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException { + MultivaluedMap<String, String> headers = context.getHeaders(); + Iterator<Map.Entry<String, List<String>>> it = headers.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<String, List<String>> next = it.next(); + if (header.equals(next.getKey())) { + originalHeader.set(next.setValue(Collections.singletonList(entity)).get(0)); + } + } + return context.proceed(); + } + }) + .target("http://localhost:8080").request().get()) { + Assertions.assertEquals(entity, response.readEntity(String.class)); + Assertions.assertEquals(entity, response.getHeaderString(header)); + Assertions.assertEquals(header, originalHeader.get()); + } + } + + @Test + void testNullHeader() { + final AtomicReference<String> originalHeader = new AtomicReference<>(); + RuntimeDelegate.setInstance(new StringHeaderRuntimeDelegate(RuntimeDelegate.getInstance())); + try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() { + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.abortWith(Response.ok() + .header(header, new StringHeader()) + .entity(entity).build()); + } + }).register(new ClientResponseFilter() { + @Override + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) + throws IOException { + originalHeader.set(responseContext.getHeaderString(header)); + } + }) + .target("http://localhost:8080").request().get()) { + Assertions.assertEquals(entity, response.readEntity(String.class)); + Assertions.assertEquals("", originalHeader.get()); + } + } + + private static class StringHeader extends AtomicReference<String> { + + } + + private static class StringHeaderDelegate implements RuntimeDelegate.HeaderDelegate<StringHeader> { + @Override + public StringHeader fromString(String value) { + StringHeader stringHeader = new StringHeader(); + stringHeader.set(value); + return stringHeader; + } + + @Override + public String toString(StringHeader value) { + //on purpose + return null; + } + } + + private static class StringHeaderRuntimeDelegate extends RuntimeDelegate { + private final RuntimeDelegate original; + + private StringHeaderRuntimeDelegate(RuntimeDelegate original) { + this.original = original; + } + + @Override + public UriBuilder createUriBuilder() { + return original.createUriBuilder(); + } + + @Override + public Response.ResponseBuilder createResponseBuilder() { + return original.createResponseBuilder(); + } + + @Override + public Variant.VariantListBuilder createVariantListBuilder() { + return original.createVariantListBuilder(); + } + + @Override + public <T> T createEndpoint(Application application, Class<T> endpointType) + throws IllegalArgumentException, UnsupportedOperationException { + return original.createEndpoint(application, endpointType); + } + + @Override + @SuppressWarnings("unchecked") + public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> type) throws IllegalArgumentException { + if (StringHeader.class.equals(type)) { + return (HeaderDelegate<T>) new StringHeaderDelegate(); + } + return original.createHeaderDelegate(type); + } + + @Override + public Link.Builder createLinkBuilder() { + return original.createLinkBuilder(); + } + } + }
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java index 4765056..75b1987 100644 --- a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java +++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025 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 @@ -129,60 +129,107 @@ * @return transformed map view. */ public static <K, V, O> Map<K, V> mapView(Map<K, O> originalMap, Function<O, V> valuesTransformer) { - return new AbstractMap<K, V>() { - @Override - public Set<Entry<K, V>> entrySet() { - return new AbstractSet<Entry<K, V>>() { + return new KVOMap<K, V, O>(originalMap, valuesTransformer); + } + private static class KVOMap<K, V, O> extends AbstractMap<K, V> { + protected final Map<K, O> originalMap; + protected final Function<O, V> valuesTransformer; - Set<Entry<K, O>> originalSet = originalMap.entrySet(); - Iterator<Entry<K, O>> original = originalSet.iterator(); + private KVOMap(Map<K, O> originalMap, Function<O, V> valuesTransformer) { + this.originalMap = originalMap; + this.valuesTransformer = valuesTransformer; + } - @Override - public Iterator<Entry<K, V>> iterator() { - return new Iterator<Entry<K, V>>() { - @Override - public boolean hasNext() { - return original.hasNext(); - } + @Override + public Set<Entry<K, V>> entrySet() { + return new AbstractSet<Entry<K, V>>() { - @Override - public Entry<K, V> next() { + Set<Entry<K, O>> originalSet = originalMap.entrySet(); + Iterator<Entry<K, O>> original = originalSet.iterator(); - Entry<K, O> next = original.next(); + @Override + public Iterator<Entry<K, V>> iterator() { + return new Iterator<Entry<K, V>>() { + @Override + public boolean hasNext() { + return original.hasNext(); + } - return new Entry<K, V>() { - @Override - public K getKey() { - return next.getKey(); - } + @Override + public Entry<K, V> next() { - @Override - public V getValue() { - return valuesTransformer.apply(next.getValue()); - } + Entry<K, O> next = original.next(); - @Override - public V setValue(V value) { - throw new UnsupportedOperationException("Not supported."); - } - }; - } + return new Entry<K, V>() { + @Override + public K getKey() { + return next.getKey(); + } - @Override - public void remove() { - original.remove(); - } - }; - } + @Override + public V getValue() { + return valuesTransformer.apply(next.getValue()); + } - @Override - public int size() { - return originalSet.size(); - } - }; - } - }; + @Override + public V setValue(V value) { + return KVOMap.this.setValue(next, value); + } + }; + } + + @Override + public void remove() { + original.remove(); + } + }; + } + + @Override + public int size() { + return originalSet.size(); + } + }; + } + + protected V setValue(Map.Entry<K, O> entry, V value) { + throw new UnsupportedOperationException("Not supported."); + } + } + + /** + * Create a {@link Map} view, which transforms the values of provided original map. + * <p> + * + * @param originalMap provided map. + * @param valuesTransformer values transformer. + * @return transformed map view. + */ + public static Map<String, List<String>> mapObjectToStringView(Map<String, List<Object>> originalMap, + Function<List<Object>, List<String>> valuesTransformer) { + return new ObjectToStringMap(originalMap, valuesTransformer); + } + + private static class ObjectToStringMap extends KVOMap<String, List<String>, List<Object>> { + + private ObjectToStringMap(Map<String, List<Object>> originalMap, Function<List<Object>, List<String>> valuesTransformer) { + super(originalMap, valuesTransformer); + } + + @Override + protected List<String> setValue(Entry<String, List<Object>> entry, List<String> value) { + @SuppressWarnings("unchecked") + final List<Object> old = entry.setValue((List<Object>) (List<?>) value); + return valuesTransformer.apply(old); + } + + @Override + public List<String> put(String key, List<String> value) { + @SuppressWarnings("unchecked") + final List<Object> old = originalMap.put(key, (List<Object>) (List<?>) value); + return valuesTransformer.apply(old); + } } /**
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java index f8bec0a..51bb99e 100644 --- a/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java +++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025 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 @@ -86,20 +86,29 @@ } /** - * Check if a cookie with identical name had been parsed. - * If yes, the one with the longest string will be kept + * Check if a cookie with similar names had been parsed. + * If yes, the one with the longest path will be kept + * For similar paths the newest is stored * @param cookies : Map of cookies * @param cookie : Cookie to be checked */ private static void checkSimilarCookieName(Map<String, Cookie> cookies, MutableCookie cookie) { - if (cookie != null) { - if (cookies.containsKey(cookie.name)){ - if (cookie.value.length() > cookies.get(cookie.name).getValue().length()){ - cookies.put(cookie.name, cookie.getImmutableCookie()); - } - } else { - cookies.put(cookie.name, cookie.getImmutableCookie()); - } + if (cookie == null) { + return; + } + + boolean alreadyPresent = cookies.containsKey(cookie.name); + boolean recordCookie = !alreadyPresent; + + if (alreadyPresent) { + final String newPath = cookie.path == null ? "" : cookie.path; + final String existingPath = cookies.get(cookie.name).getPath() == null ? "" + : cookies.get(cookie.name).getPath(); + recordCookie = (newPath.length() >= existingPath.length()); + } + + if (recordCookie) { + cookies.put(cookie.name, cookie.getImmutableCookie()); } }
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 aeea686..c60386b 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, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025 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 @@ -210,7 +210,7 @@ } return new AbstractMultivaluedMap<String, String>( - Views.mapView(headers, input -> HeaderUtils.asStringList(input, rd)) + Views.mapObjectToStringView(headers, input -> HeaderUtils.asStringList(input, rd)) ) { }; }
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 29cb6e0..46446a4 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
@@ -157,8 +157,22 @@ * as required by JAX-RS specification on the server side. */ public InboundMessageContext(Configuration configuration, boolean translateNce) { + this(configuration, HeaderUtils.createInbound(), translateNce); + } + + /** + * Create new inbound message context. + * + * @param configuration the related client/server side {@link Configuration}. If {@code null}, + * the default behaviour is expected. + * @param httpHeaders the http headers map. + * @param translateNce if {@code true}, the {@link javax.ws.rs.core.NoContentException} thrown by a + * selected message body reader will be translated into a {@link javax.ws.rs.BadRequestException} + * as required by JAX-RS specification on the server side. + */ + public InboundMessageContext(Configuration configuration, MultivaluedMap<String, String> httpHeaders, boolean translateNce) { super(configuration); - this.headers = new GuardianStringKeyMultivaluedMap<>(HeaderUtils.createInbound()); + this.headers = new GuardianStringKeyMultivaluedMap<>(httpHeaders); this.entityContent = new EntityContent(); this.translateNce = translateNce; this.configuration = configuration; @@ -302,7 +316,11 @@ } final Iterator<String> valuesIterator = values.iterator(); - StringBuilder buffer = new StringBuilder(valuesIterator.next()); + String next = valuesIterator.next(); + if (next == null) { + next = ""; + } + StringBuilder buffer = new StringBuilder(next); while (valuesIterator.hasNext()) { buffer.append(',').append(valuesIterator.next()); }
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 018c9f0..38b5013 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, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025 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 @@ -160,11 +160,23 @@ } return sb.toString(); } + /** - * The maximum size of array to allocate. + * Read/convert stream to the byte array. + * + * @param in stream to be converted to the byte array + * @return the byte array + * @throws IOException if there is an error reading from the stream + * @since 2.47 + */ + public static byte[] readFromAsBytes(InputStream in) throws IOException { + return readAllBytes(in); + } + /** + * The maximum size of an 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 + * OutOfMemoryError: Requested array size exceeds the VM limit */ private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
diff --git a/pom.xml b/pom.xml index eb7f65a..7aa01a2 100644 --- a/pom.xml +++ b/pom.xml
@@ -2205,7 +2205,6 @@ <aspectj.weaver.version>1.9.22.1</aspectj.weaver.version> <!-- <bnd.plugin.version>2.3.6</bnd.plugin.version>--> <bouncycastle.version>1.70</bouncycastle.version> - <commons.io.version>2.19.0</commons.io.version> <commons.codec.version>1.16.1</commons.codec.version> <!-- <commons-lang3.version>3.3.2</commons-lang3.version>--> <commons.logging.version>1.3.5</commons.logging.version>
diff --git a/test-framework/maven/container-runner-maven-plugin/pom.xml b/test-framework/maven/container-runner-maven-plugin/pom.xml index 21bbfd3..b84c7b3 100644 --- a/test-framework/maven/container-runner-maven-plugin/pom.xml +++ b/test-framework/maven/container-runner-maven-plugin/pom.xml
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2015, 2024 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2025 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 @@ -168,10 +168,10 @@ <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-archiver</artifactId> </exclusion> - <exclusion> + <!--<exclusion> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - </exclusion> + </exclusion>--> <exclusion> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId>
diff --git a/test-framework/maven/custom-enforcer-rules/pom.xml b/test-framework/maven/custom-enforcer-rules/pom.xml index 5f702fc..ada81c9 100644 --- a/test-framework/maven/custom-enforcer-rules/pom.xml +++ b/test-framework/maven/custom-enforcer-rules/pom.xml
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2015, 2024 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2025 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 @@ -49,10 +49,6 @@ <artifactId>plexus-utils</artifactId> </exclusion> <exclusion> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - </exclusion> - <exclusion> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </exclusion> @@ -68,12 +64,6 @@ </dependency> <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - <version>${commons.io.version}</version> - </dependency> - - <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>compile</scope>
diff --git a/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/FilePatternDoesNotExistRule.java b/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/FilePatternDoesNotExistRule.java index f9c8fde..ee275ba 100644 --- a/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/FilePatternDoesNotExistRule.java +++ b/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/FilePatternDoesNotExistRule.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025 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,17 +17,19 @@ package org.glassfish.jersey.test.maven.rule; import java.io.File; -import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; -import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.maven.enforcer.rule.api.EnforcerRuleException; import org.apache.maven.enforcer.rules.AbstractStandardEnforcerRule; /** - * Maven enforcer rule to enforce that given set of files does not exist.<br/> + * Maven enforcer rule to enforce that a given set of files does not exist.<br/> * This rule is similar to apache {@code requireFilesDontExist} with a support for wildcards. * * @author Stepan Vavra @@ -55,8 +57,13 @@ } final Set<File> matchedFiles = new TreeSet<>(); - for (File matchedFile : dir.listFiles((FileFilter) new WildcardFileFilter(fileItselfPattern))) { - matchedFiles.add(matchedFile); + try { + final DirectoryStream<Path> directoryStream + = Files.newDirectoryStream(dir.toPath(), fileItselfPattern); + directoryStream.forEach(path -> matchedFiles.add(path.toFile())); + directoryStream.close(); + } catch (IOException e) { + throw new EnforcerRuleException(e); } if (!matchedFiles.isEmpty()) {
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml index b01f938..22104d4 100644 --- a/tests/e2e-client/pom.xml +++ b/tests/e2e-client/pom.xml
@@ -225,11 +225,7 @@ <version>${junit-platform-suite.version}</version> <scope>test</scope> </dependency> - <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - <version>${commons.io.version}</version> - </dependency> + </dependencies> <profiles>
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java index a458eb9..6564024 100644 --- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java +++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025 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 @@ -18,7 +18,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.stream.Stream; import javax.net.ssl.SSLContext; @@ -32,11 +31,10 @@ import org.glassfish.jersey.internal.util.JdkVersion; import org.glassfish.jersey.jetty.connector.JettyConnectorProvider; +import org.glassfish.jersey.message.internal.ReaderWriter; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.apache.commons.io.IOUtils; - /** * SSL connector hostname verification tests. * @@ -96,9 +94,9 @@ final InputStream trustStore = SslConnectorConfigurationTest.class.getResourceAsStream(clientTrustStore()); final InputStream keyStore = SslConnectorConfigurationTest.class.getResourceAsStream(CLIENT_KEY_STORE); return SslConfigurator.newInstance() - .trustStoreBytes(IOUtils.toByteArray(trustStore)) + .trustStoreBytes(ReaderWriter.readFromAsBytes(trustStore)) .trustStorePassword("asdfgh") - .keyStoreBytes(IOUtils.toByteArray(keyStore)) + .keyStoreBytes(ReaderWriter.readFromAsBytes(keyStore)) .keyPassword("asdfgh") .createSSLContext(); }
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java index 20795c3..b66ff73 100644 --- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java +++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025 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,9 +23,9 @@ import jakarta.ws.rs.core.UriBuilder; -import org.apache.commons.io.IOUtils; import org.glassfish.jersey.logging.LoggingFeature; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.message.internal.ReaderWriter; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.grizzly.http.server.HttpServer; @@ -86,9 +86,9 @@ SSLContextConfigurator sslContext = new SSLContextConfigurator(); // set up security context - sslContext.setKeyStoreBytes(IOUtils.toByteArray(keyStore)); // contains server key pair + sslContext.setKeyStoreBytes(ReaderWriter.readFromAsBytes(keyStore)); // contains server key pair sslContext.setKeyStorePass("asdfgh"); - sslContext.setTrustStoreBytes(IOUtils.toByteArray(trustStore)); // contains client certificate + sslContext.setTrustStoreBytes(ReaderWriter.readFromAsBytes(trustStore)); // contains client certificate sslContext.setTrustStorePass("asdfgh"); ResourceConfig rc = new ResourceConfig();
diff --git a/tests/e2e-server/pom.xml b/tests/e2e-server/pom.xml index e0d7298..73c9d23 100644 --- a/tests/e2e-server/pom.xml +++ b/tests/e2e-server/pom.xml
@@ -217,12 +217,6 @@ </dependency> <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - <version>${commons.io.version}</version> - </dependency> - - <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> <scope>test</scope>
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/SimilarInputStreamTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/SimilarInputStreamTest.java index cedad3a..58e180c 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/SimilarInputStreamTest.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/SimilarInputStreamTest.java
@@ -16,7 +16,6 @@ package org.glassfish.jersey.tests.e2e.server; -import org.apache.commons.io.IOUtils; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -25,6 +24,7 @@ import org.glassfish.jersey.internal.InternalProperties; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.jetty.JettyHttpContainerFactory; +import org.glassfish.jersey.message.internal.ReaderWriter; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; import org.glassfish.jersey.test.JerseyTest; @@ -203,7 +203,7 @@ private void cacheInputStream() throws IOException { // Cache the inputstream in order to read it multiple times. - cachedBytes = IOUtils.toByteArray(super.getInputStream()); + cachedBytes = ReaderWriter.readFromAsBytes(super.getInputStream()); }
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java index 1068272..5438e71 100644 --- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java +++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025 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 @@ -151,27 +151,46 @@ @Test public void testMultipleCookiesWithSameName(){ - String cookieHeader = "kobe=longeststring; kobe=shortstring"; + String cookieHeader = "kobe=oldeststring; kobe=neweststring"; Map<String, Cookie> cookies = HttpHeaderReader.readCookies(cookieHeader); assertEquals(cookies.size(), 1); Cookie c = cookies.get("kobe"); assertEquals(c.getVersion(), 0); assertEquals("kobe", c.getName()); - assertEquals("longeststring", c.getValue()); + assertEquals("neweststring", c.getValue()); - cookieHeader = "bryant=longeststring; bryant=shortstring; fred=shortstring ;fred=longeststring;$Path=/path"; + cookieHeader = "bryant=longeststring; bryant=neweststring; fred=oldeststring ;fred=neweststring;$Path=/path"; cookies = HttpHeaderReader.readCookies(cookieHeader); assertEquals(cookies.size(), 2); c = cookies.get("bryant"); assertEquals(c.getVersion(), 0); assertEquals("bryant", c.getName()); - assertEquals("longeststring", c.getValue()); + assertEquals("neweststring", c.getValue()); c = cookies.get("fred"); assertEquals(c.getVersion(), 0); assertEquals("fred", c.getName()); - assertEquals("longeststring", c.getValue()); + assertEquals("neweststring", c.getValue()); assertEquals("/path", c.getPath()); + cookieHeader = "cookiewithpath=longeststring;$Path=/path; cookiewithpath=string1;$Path=/path;" + + " cookiewithpath=string2;$Path=/path ;cookiewithpath=string3;$Path=/path"; + cookies = HttpHeaderReader.readCookies(cookieHeader); + assertEquals(cookies.size(), 1); + c = cookies.get("cookiewithpath"); + assertEquals(c.getVersion(), 0); + assertEquals("cookiewithpath", c.getName()); + assertEquals("string3", c.getValue()); + + cookieHeader = "cookiewithpath=longeststring;$Path=/path/added/path; cookiewithpath=string1;$Path=/path;" + + " cookiewithpath=string2;$Path=/path ;cookiewithpath=string3;$Path=/path"; + cookies = HttpHeaderReader.readCookies(cookieHeader); + assertEquals(cookies.size(), 1); + c = cookies.get("cookiewithpath"); + assertEquals(c.getVersion(), 0); + assertEquals("cookiewithpath", c.getName()); + assertEquals("longeststring", c.getValue()); + assertEquals("/path/added/path", c.getPath()); + } @Test
diff --git a/tools/jersey-release-notes-maven-plugin/pom.xml b/tools/jersey-release-notes-maven-plugin/pom.xml index 1522089..dfd342b 100644 --- a/tools/jersey-release-notes-maven-plugin/pom.xml +++ b/tools/jersey-release-notes-maven-plugin/pom.xml
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2019, 2024 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2019, 2025 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 @@ -56,7 +56,7 @@ <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> - <version>3.6.0</version> + <version>3.15.1</version> <scope>provided</scope> </dependency> <dependency> @@ -74,7 +74,8 @@ <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.17.0</version> + <version>${commons.io.version}</version> + <scope>test</scope> </dependency> <dependency> <groupId>org.apache.maven</groupId> @@ -83,9 +84,15 @@ <scope>test</scope> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.13.2</version> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${junit.version}</version> <scope>test</scope> </dependency> @@ -96,7 +103,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> - <version>3.6.0</version> + <version>3.15.1</version> <configuration> <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> </configuration> @@ -113,7 +120,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.1</version> + <version>3.14.0</version> <inherited>true</inherited> <configuration> <source>${java.version}</source> @@ -127,6 +134,8 @@ <properties> <java.version>1.8</java.version> - <maven.version>3.8.1</maven.version> + <maven.version>3.9.9</maven.version> + <commons.io.version>2.19.0</commons.io.version> + <junit.version>5.12.2</junit.version> </properties> </project>
diff --git a/tools/jersey-release-notes-maven-plugin/src/test/java/org/glassfish/jersey/tools/plugins/releasenotes/GenerateReleaseNotesMojoTest.java b/tools/jersey-release-notes-maven-plugin/src/test/java/org/glassfish/jersey/tools/plugins/releasenotes/GenerateReleaseNotesMojoTest.java index 93287ee..1826730 100644 --- a/tools/jersey-release-notes-maven-plugin/src/test/java/org/glassfish/jersey/tools/plugins/releasenotes/GenerateReleaseNotesMojoTest.java +++ b/tools/jersey-release-notes-maven-plugin/src/test/java/org/glassfish/jersey/tools/plugins/releasenotes/GenerateReleaseNotesMojoTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025 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,17 +23,14 @@ import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingRequest; import org.eclipse.aether.DefaultRepositorySystemSession; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.File; -@RunWith(JUnit4.class) public class GenerateReleaseNotesMojoTest extends AbstractMojoTestCase { - @Before + @BeforeEach public void setUp() throws Exception { // required for mojo lookups to work