Merge remote-tracking branch 'upstream/master' into 3.x
diff --git a/README.md b/README.md
index 92f22fa..62ab9a0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[//]: # " Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved. "
+[//]: # " Copyright (c) 2012, 2020 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 "
@@ -40,13 +40,17 @@
We use [contribution policy](CONTRIBUTING.md), which means we can only accept contributions under
the terms of [ECA][eca].
-### More Info on Jersey
+### More Information on Jersey
See the [Jersey website][jersey-web] to access Jersey documentation. If you run into any issues or have questions,
-ask at [jersey-dev@eclipse.org][jersey-users], [StackOverflow][jersey-so] or file an issue on [Jersey GitHub Project][jersey-issues].
+ask at [jersey-dev@eclipse.org][jersey-users] (need to [subscribe][jersey-users-subscribe] first),
+[StackOverflow][jersey-so] or file an issue on [Jersey GitHub Project][jersey-issues].
+You can follow us on [Twitter][jersey-twitter], too.
[eca]: http://www.eclipse.org/legal/ECA.php
[jersey-api]: https://jersey.github.io/apidocs/latest/jersey/index.html
[jersey-issues]: https://github.com/eclipse-ee4j/jersey/issues
[jersey-so]: http://stackoverflow.com/questions/tagged/jersey
[jersey-users]: mailto:jersey-dev@eclipse.org
+[jersey-users-subscribe]: https://accounts.eclipse.org/mailing-list/jersey-dev
[jersey-web]: https://projects.eclipse.org/projects/ee4j.jersey
+[jersey-twitter]: https://twitter.com/gf_jersey
diff --git a/bom/pom.xml b/bom/pom.xml
index 195dac2..f95783f 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -394,10 +394,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
- <configuration>
- <generateProjectInfo>false</generateProjectInfo>
- <generateReports>true</generateReports>
- </configuration>
</plugin>
</plugins>
</build>
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
index 9e31fd3..1c94e21 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
@@ -436,7 +436,9 @@
@Override
public void onComplete(final Result result) {
entityStream.closeQueue();
- callback.response(jerseyResponse.get());
+ if (!callbackInvoked.get()) {
+ callback.response(jerseyResponse.get());
+ }
responseFuture.complete(jerseyResponse.get());
}
diff --git a/containers/grizzly2-http/pom.xml b/containers/grizzly2-http/pom.xml
index df568a1..7d8eb09 100644
--- a/containers/grizzly2-http/pom.xml
+++ b/containers/grizzly2-http/pom.xml
@@ -61,19 +61,6 @@
<inherited>true</inherited>
</plugin>
</plugins>
-
- <resources>
- <resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>${basedir}/src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
</build>
</project>
diff --git a/containers/grizzly2-servlet/pom.xml b/containers/grizzly2-servlet/pom.xml
index 2b51ef4..30e237d 100644
--- a/containers/grizzly2-servlet/pom.xml
+++ b/containers/grizzly2-servlet/pom.xml
@@ -59,16 +59,6 @@
<build>
<resources>
<resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>${basedir}/src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- <resource>
<directory>${project.build.directory}/legal</directory>
</resource>
</resources>
diff --git a/containers/jdk-http/pom.xml b/containers/jdk-http/pom.xml
index a482ed0..3d494df 100644
--- a/containers/jdk-http/pom.xml
+++ b/containers/jdk-http/pom.xml
@@ -68,12 +68,6 @@
<resources>
<resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
diff --git a/containers/jetty-http/pom.xml b/containers/jetty-http/pom.xml
index 1734745..d2abe36 100644
--- a/containers/jetty-http/pom.xml
+++ b/containers/jetty-http/pom.xml
@@ -74,28 +74,10 @@
<resources>
<resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
- <profiles>
- <profile>
- <id>testsSkipJdk6</id>
- <activation>
- <jdk>1.6</jdk>
- </activation>
- <properties>
- <skip.tests>true</skip.tests>
- </properties>
- </profile>
- </profiles>
-
</project>
diff --git a/containers/jetty-servlet/pom.xml b/containers/jetty-servlet/pom.xml
index c318d6b..e887171 100644
--- a/containers/jetty-servlet/pom.xml
+++ b/containers/jetty-servlet/pom.xml
@@ -65,16 +65,6 @@
<build>
<resources>
<resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>${basedir}/src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- <resource>
<directory>${project.build.directory}/legal</directory>
</resource>
</resources>
diff --git a/containers/simple-http/pom.xml b/containers/simple-http/pom.xml
index 66ff8bd..4365f98 100644
--- a/containers/simple-http/pom.xml
+++ b/containers/simple-http/pom.xml
@@ -72,12 +72,6 @@
<resources>
<resource>
- <directory>${basedir}/src/main/java</directory>
- <includes>
- <include>META-INF/**/*</include>
- </includes>
- </resource>
- <resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
diff --git a/containers/simple-http/src/main/resources/org.glassfish.jersey.simple.internal/localization.properties b/containers/simple-http/src/main/resources/org/glassfish/jersey/simple/internal/localization.properties
similarity index 100%
rename from containers/simple-http/src/main/resources/org.glassfish.jersey.simple.internal/localization.properties
rename to containers/simple-http/src/main/resources/org/glassfish/jersey/simple/internal/localization.properties
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
index 8d7d812..40c99d4 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
@@ -414,12 +414,17 @@
BootstrapBag bootstrapBag = new ClientBootstrapBag();
bootstrapBag.setManagedObjectsFinalizer(new ManagedObjectsFinalizer(injectionManager));
- List<BootstrapConfigurator> bootstrapConfigurators = Arrays.asList(new RequestScope.RequestScopeConfigurator(),
+
+ final ClientMessageBodyFactory.MessageBodyWorkersConfigurator messageBodyWorkersConfigurator =
+ new ClientMessageBodyFactory.MessageBodyWorkersConfigurator();
+
+ List<BootstrapConfigurator> bootstrapConfigurators = Arrays.asList(
+ new RequestScope.RequestScopeConfigurator(),
new ParamConverterConfigurator(),
new ParameterUpdaterConfigurator(),
new RuntimeConfigConfigurator(runtimeCfgState),
new ContextResolverFactory.ContextResolversConfigurator(),
- new MessageBodyFactory.MessageBodyWorkersConfigurator(),
+ messageBodyWorkersConfigurator,
new ExceptionMapperFactory.ExceptionMappersConfigurator(),
new JaxrsProviders.ProvidersConfigurator(),
new AutoDiscoverableConfigurator(RuntimeType.CLIENT));
@@ -455,6 +460,8 @@
final ClientRuntime crt = new ClientRuntime(configuration, connector, injectionManager, bootstrapBag);
client.registerShutdownHook(crt);
+ messageBodyWorkersConfigurator.setClientRuntime(crt);
+
return crt;
}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientMessageBodyFactory.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientMessageBodyFactory.java
new file mode 100644
index 0000000..e05cb5f
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientMessageBodyFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2020 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.client;
+
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.internal.BootstrapConfigurator;
+import org.glassfish.jersey.internal.inject.Bindings;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.InstanceBinding;
+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;
+import org.glassfish.jersey.message.internal.MessageBodyFactory;
+
+import javax.ws.rs.core.Configuration;
+
+class ClientMessageBodyFactory extends MessageBodyFactory {
+
+ /**
+ * Keep reference to {@link ClientRuntime} so that {@code finalize} on it is not called
+ * before the {@link MessageBodyFactory} is used.
+ * <p>
+ * Some entity types {@code @Inject} {@code MessageBodyFactory} for their {@code read} methods,
+ * but if the finalizer is invoked before that, the HK2 injection manager gets closed.
+ * </p>
+ */
+ private final LazyValue<ClientRuntime> clientRuntime;
+
+ /**
+ * Create a new message body factory.
+ *
+ * @param configuration configuration. Optional - can be null.
+ * @param clientRuntimeValue - a reference to ClientRuntime.
+ */
+ private ClientMessageBodyFactory(Configuration configuration, Value<ClientRuntime> clientRuntimeValue) {
+ super(configuration);
+ clientRuntime = Values.lazy(clientRuntimeValue);
+ }
+
+ /**
+ * Configurator which initializes and register {@link MessageBodyWorkers} instance into {@link InjectionManager} and
+ * {@link BootstrapBag}.
+ */
+ static class MessageBodyWorkersConfigurator implements BootstrapConfigurator {
+
+ private ClientMessageBodyFactory messageBodyFactory;
+ private ClientRuntime clientRuntime;
+
+ @Override
+ public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+ messageBodyFactory = new ClientMessageBodyFactory(bootstrapBag.getConfiguration(), () -> clientRuntime);
+ InstanceBinding<ClientMessageBodyFactory> binding =
+ Bindings.service(messageBodyFactory)
+ .to(MessageBodyWorkers.class);
+ injectionManager.register(binding);
+ }
+
+ @Override
+ public void postInit(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+ messageBodyFactory.initialize(injectionManager);
+ bootstrapBag.setMessageBodyWorkers(messageBodyFactory);
+ }
+
+ void setClientRuntime(ClientRuntime clientRuntime) {
+ this.clientRuntime = clientRuntime;
+ }
+ }
+
+ ClientRuntime getClientRuntime() {
+ return clientRuntime.get();
+ }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/InboundJaxrsResponse.java b/core-client/src/main/java/org/glassfish/jersey/client/InboundJaxrsResponse.java
index 0f4cc94..615912d 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/InboundJaxrsResponse.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/InboundJaxrsResponse.java
@@ -22,6 +22,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.core.EntityTag;
@@ -51,6 +52,7 @@
private final ClientResponse context;
private final RequestScope scope;
private final RequestContext requestContext;
+ private final AtomicBoolean isClosed = new AtomicBoolean(false);
/**
* Create new scoped client response.
@@ -139,11 +141,13 @@
@Override
public void close() throws ProcessingException {
- try {
- context.close();
- } finally {
- if (requestContext != null) {
- requestContext.release();
+ if (isClosed.compareAndSet(false, true)) {
+ try {
+ context.close();
+ } finally {
+ if (requestContext != null) {
+ requestContext.release();
+ }
}
}
}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java b/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java
index 6880e0b..69b6265 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java
@@ -17,6 +17,9 @@
package org.glassfish.jersey.client;
import java.security.KeyStore;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
@@ -30,8 +33,12 @@
import org.glassfish.jersey.SslConfigurator;
import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.client.spi.ClientBuilderListener;
+import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.internal.util.collection.UnsafeValue;
import org.glassfish.jersey.internal.util.collection.Values;
+import org.glassfish.jersey.model.internal.RankedComparator;
+import org.glassfish.jersey.model.internal.RankedProvider;
/**
* Jersey provider of {@link jakarta.ws.rs.client.ClientBuilder JAX-RS client builder}.
@@ -45,6 +52,23 @@
private SslConfigurator sslConfigurator;
private SSLContext sslContext;
+ private static final List<ClientBuilderListener> CLIENT_BUILDER_LISTENERS;
+
+ static {
+ final List<RankedProvider<ClientBuilderListener>> listeners = new LinkedList<>();
+ for (ClientBuilderListener listener : ServiceFinder.find(ClientBuilderListener.class)) {
+ listeners.add(new RankedProvider<>(listener));
+ }
+ listeners.sort(new RankedComparator<>(RankedComparator.Order.ASCENDING));
+
+ final List<ClientBuilderListener> sortedList = new LinkedList<>();
+ for (RankedProvider<ClientBuilderListener> listener : listeners) {
+ sortedList.add(listener.getProvider());
+ }
+
+ CLIENT_BUILDER_LISTENERS = Collections.unmodifiableList(sortedList);
+ }
+
/**
* Create a new custom-configured {@link JerseyClient} instance.
*
@@ -72,6 +96,14 @@
*/
public JerseyClientBuilder() {
this.config = new ClientConfig();
+
+ init(this);
+ }
+
+ private static void init(ClientBuilder builder) {
+ for (ClientBuilderListener listener : CLIENT_BUILDER_LISTENERS) {
+ listener.onNewBuilder(builder);
+ }
}
@Override
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java b/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java
new file mode 100644
index 0000000..10b2511
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020 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.client.spi;
+
+import org.glassfish.jersey.Beta;
+
+import javax.ws.rs.client.ClientBuilder;
+
+/**
+ * <p>
+ * Implementations of this interface will be notified when new ClientBuilder
+ * instances are being constructed. This will allow implementations to register
+ * providers on the ClientBuilder, and is intended for global providers.
+ * </p>
+ * <p>
+ * In order for the ClientBuilder to call implementations of this interface,
+ * the implementation must be specified such that a ServiceLoader can find it -
+ * i.e. it must be specified in the <code>
+ * META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener
+ * </code> file in an archive on the current thread's context classloader's
+ * class path.
+ * </p>
+ * <p>
+ * Note that the <code>onNewBuilder</code> method will be called when the
+ * ClientBuilder is constructed, not when it's <code>build</code> method is
+ * invoked. This allows the caller to override global providers if they desire.
+ * </p>
+ * <p>
+ * The ClientBuilderListener are invoked in an order given by it's {@code @Priority}.
+ * The default is {@code Priorities.USER}.
+ * </p>
+ * @since 2.32
+ */
+// Must not be annotated with @Contract
+@Beta
+public interface ClientBuilderListener {
+ void onNewBuilder(ClientBuilder builder);
+}
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java b/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java
new file mode 100644
index 0000000..e2776fc
--- /dev/null
+++ b/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020 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.client.spi;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+
+public class ClientBuilderListenerTest {
+
+ public static final String PROPERTY_NAME = "ClientBuilderListenerProperty";
+
+ @Priority(Priorities.USER + 1000)
+ public static class FirstClientBuilderListener implements ClientBuilderListener {
+ @Override
+ public void onNewBuilder(ClientBuilder builder) {
+ builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 60));
+ }
+ }
+
+ public static class SecondClientBuilderListener implements ClientBuilderListener {
+ @Override
+ public void onNewBuilder(ClientBuilder builder) {
+ builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 50));
+ }
+ }
+
+ @Priority(Priorities.USER + 2000)
+ public static class ThirdClientBuilderListener implements ClientBuilderListener {
+ @Override
+ public void onNewBuilder(ClientBuilder builder) {
+ builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 70));
+ }
+ }
+
+ @Test
+ public void testClientBuilderListener() {
+ Client client = ClientBuilder.newClient();
+ Assert.assertEquals(70, client.getConfiguration().getProperty(PROPERTY_NAME));
+ }
+
+}
diff --git a/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener b/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener
new file mode 100644
index 0000000..4cfec49
--- /dev/null
+++ b/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener
@@ -0,0 +1,3 @@
+org.glassfish.jersey.client.spi.ClientBuilderListenerTest$ThirdClientBuilderListener
+org.glassfish.jersey.client.spi.ClientBuilderListenerTest$FirstClientBuilderListener
+org.glassfish.jersey.client.spi.ClientBuilderListenerTest$SecondClientBuilderListener
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
index d108ccb..b54f2f8 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
@@ -285,6 +285,17 @@
}
out.write(i);
}
+
+ @Override
+ public void write(byte[] ba, int off, int len) throws IOException {
+ if ((off | len | ba.length - (len + off) | off + len) < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ if ((baos.size() + len) <= maxEntitySize) {
+ baos.write(ba, off, len);
+ }
+ out.write(ba, off, len);
+ }
}
}
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ActiveBindingBindingTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ActiveBindingBindingTest.java
index 099327b..a9f241a 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ActiveBindingBindingTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ActiveBindingBindingTest.java
@@ -31,23 +31,21 @@
import jakarta.inject.Singleton;
import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.internal.inject.PerLookup;
-import org.glassfish.jersey.internal.util.collection.Ref;
import org.glassfish.jersey.process.internal.RequestScoped;
+import org.glassfish.jersey.server.internal.process.RequestProcessingContextReference;
import org.glassfish.jersey.server.ContainerResponse;
import org.glassfish.jersey.server.RequestContextBuilder;
import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.internal.process.RequestProcessingContext;
import org.glassfish.hk2.api.DescriptorType;
import org.glassfish.hk2.api.DescriptorVisibility;
+import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceHandle;
import org.glassfish.hk2.utilities.AbstractActiveDescriptor;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.jvnet.hk2.internal.ServiceHandleImpl;
-import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
@@ -139,7 +137,6 @@
}
@Test
- @Ignore("At the time of ignoring this test, ResourceConfig does not support HK2 Binder registering.")
public void testReq() throws Exception {
// bootstrap the test application
@@ -256,10 +253,10 @@
if (serviceHandle instanceof ServiceHandleImpl) {
final ServiceHandleImpl serviceHandleImpl = (ServiceHandleImpl) serviceHandle;
- final Class<? extends Annotation> scopeAnnotation =
- serviceHandleImpl.getOriginalRequest().getInjecteeDescriptor().getScopeAnnotation();
+ final String scopeAnnotation =
+ serviceHandleImpl.getOriginalRequest().getInjecteeDescriptor().getScope();
- if (scopeAnnotation == RequestScoped.class || scopeAnnotation == null) {
+ if (RequestScoped.class.getName().equals(scopeAnnotation) || scopeAnnotation == null) {
direct = true;
}
}
diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index 8eee614..4c20d9c 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -54,8 +54,10 @@
<!ENTITY jaxb.release.uri "https://eclipse-ee4j.github.io/jaxb-ri">
<!ENTITY jaxb.javadoc.uri "&jaxb.release.uri;/docs/api/jakarta.xml.bind">
<!ENTITY jaxrs.release.uri "https://github.com/jax-rs">
-<!ENTITY jaxrs.javadoc.uri "https://jax-rs.github.io/apidocs/&jax-rs.version;/">
-<!ENTITY jaxrs21.javadoc.uri "#/jakarta.ws.rs"> <!-- TODO - once we have published javadocs to link here -->
+<!ENTITY jaxrs.javadoc.uri "https://jax-rs.github.io/apidocs/&jax-rs.version;/javax/ws/rs">
+<!ENTITY jaxrs21.javadoc.uri "https://jax-rs.github.io/apidocs/&jax-rs.version;/javax/ws/rs">
+<!ENTITY jsonb.javadoc.uri "https://javaee.github.io/javaee-spec/javadocs/javax/json/bind">
+
<!ENTITY jersey.ext.bean-validation.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-bean-validation/dependencies.html'>jersey-bean-validation</link>" >
<!ENTITY jersey.ext.declarative-linking.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-declarative-linking/dependencies.html'>jersey-declarative-linking</link>" >
@@ -67,6 +69,7 @@
<!ENTITY jersey.media.json-jettison.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-json-jettison/dependencies.html'>jersey-media-json-jettison</link>" >
<!ENTITY jersey.media.json-jackson.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-json-jackson/dependencies.html'>jersey-media-json-jackson</link>" >
<!ENTITY jersey.media.json-jackson1.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-json-jackson1/dependencies.html'>jersey-media-json-jackson1</link>" >
+<!ENTITY jersey.media.json-binding.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-json-binding/dependencies.html'>jersey-media-json-binding</link>" >
<!ENTITY jersey.media.moxy.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-moxy/dependencies.html'>jersey-media-moxy</link>" >
<!ENTITY jersey.media.multipart.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-media-multipart/dependencies.html'>jersey-media-multipart</link>" >
<!ENTITY jersey.ext.mvc.deps.link "<link xlink:href='&jersey.project-info.uri.prefix;/jersey-mvc/dependencies.html'>jersey-mvc</link>" >
@@ -103,6 +106,7 @@
<!ENTITY microprofile.spec.link "<link xlink:href='https://microprofile.io/project/eclipse/microprofile-config'>Microprofile Config Specification</link>">
<!ENTITY helidon.link "<link xlink:href='https://helidon.io/'>Helidon</link>">
<!ENTITY smallrye.link "<link xlink:href='https://smallrye.io/'>SmallRye</link>">
+<!ENTITY yasson.link "<link xlink:href='https://eclipse-ee4j.github.io/yasson/'>Yasson</link>">
<!-- API Docs links -->
<!ENTITY bv.Configuration "<link xlink:href='&bv11.javadoc.uri;/jakarta.validation/Configuration.html'>Configuration</link>">
@@ -597,6 +601,8 @@
<!ENTITY jakarta.ws.rs.sse.SseEventSource "<link xlink:href='&jaxrs21.javadoc.uri;/sse/SseEventSource.html'>SseEventSource</link>">
<!ENTITY jakarta.ws.rs.sse.InboundSseEvent "<link xlink:href='&jaxrs21.javadoc.uri;/sse/InboundSseEvent.html'>InboundSseEvent</link>">
+<!ENTITY jsonb.JsonbConfig "<link xlink:href='&jsonb.javadoc.uri;/JsonbConfig'>JsonbConfig</link>">
+
<!-- Links to specific JIRA issues -->
<!ENTITY jersey.jira.2883 "<link xlink:href='&jira.uri.prefix;/2838'>JERSEY-2838</link>">
@@ -636,6 +642,7 @@
<!ENTITY lit.jersey-media-json-jettison "<literal>jersey-media-json-jettison</literal>" >
<!ENTITY lit.jersey-media-json-jackson "<literal>jersey-media-json-jackson</literal>" >
<!ENTITY lit.jersey-media-json-jackson1 "<literal>jersey-media-json-jackson1</literal>" >
+<!ENTITY lit.jersey-media-json-binding "<literal>jersey-media-json-binding</literal>" >
<!ENTITY lit.jersey-media-moxy "<literal>jersey-media-moxy</literal>" >
<!ENTITY lit.jersey-media-multipart "<literal>jersey-media-multipart</literal>" >
<!ENTITY lit.jersey-rx-client "<literal>jersey-rx-client</literal>" >
@@ -903,6 +910,7 @@
<!ENTITY lit.jersey.media.JettisonConfig "<literal>JettisonConfig</literal>" >
<!ENTITY lit.jersey.media.JettisonJaxbContext "<literal>JettisonJaxbContext</literal>" >
<!ENTITY lit.jersey.media.JsonProcessingFeature "<literal>JsonProcessingFeature</literal>" >
+<!ENTITY lit.jersey.media.JsonBindingFeature "<literal>JsonBindingFeature</literal>" >
<!ENTITY lit.jersey.media.MoxyJsonConfig "<literal>MoxyJsonConfig</literal>" >
<!ENTITY lit.jersey.media.MoxyJsonFeature "<literal>MoxyJsonFeature</literal>" >
<!ENTITY lit.jersey.media.ObjectMapper "<literal>ObjectMapper</literal>" >
@@ -1036,3 +1044,5 @@
<!ENTITY lit.jersey.test.spi.TestContainerFactory "<literal>TestContainerFactory</literal>">
<!ENTITY lit.jersey.test.util.LoopBackConnectorProvider "<literal>LoopBackConnectorProvider</literal>">
<!ENTITY lit.jersey.test.util.ContainerRequestBuilder "<literal>ContainerRequestBuilder</literal>">
+
+<!ENTITY lit.jsonb.Jsonb "<literal>Jsonb</literal>">
\ No newline at end of file
diff --git a/docs/src/main/docbook/media.xml b/docs/src/main/docbook/media.xml
index 8b7e728..9af51d3 100644
--- a/docs/src/main/docbook/media.xml
+++ b/docs/src/main/docbook/media.xml
@@ -22,6 +22,7 @@
<!ENTITY link.json-p "<link linkend='json.json-p'>Java API for JSON Processing (JSON-P)</link>" >
<!ENTITY link.jackson "<link linkend='json.jackson'>Jackson</link>" >
<!ENTITY link.jettison "<link linkend='json.jettison'>Jettison</link>" >
+ <!ENTITY link.json-b "<link linkend='json.json-b'>Java API for JSON Binding (JSON-B)</link>" >
<!ENTITY % ents SYSTEM "jersey.ent" > %ents;
]>
@@ -64,6 +65,9 @@
<listitem>
<para>&link.jettison;</para>
</listitem>
+ <listitem>
+ <para>&link.json-b;</para>
+ </listitem>
</itemizedlist>
</para>
@@ -97,7 +101,7 @@
<title>POJO support</title>
<para>POJO support represents the easiest way to convert your Java Objects to JSON and back.</para>
- <para>Media modules that support this approach are &link.moxy; and &link.jackson;</para>
+ <para>Media modules that support this approach are &link.moxy;, &link.jackson;, and &link.json-b;</para>
</section>
<section xml:id="json-jaxb">
@@ -1076,6 +1080,80 @@
</para>
</formalpara>
</section>
+ <section xml:id="json.json-b">
+ <title>Java API for JSON Binding (JSON-B)</title>
+
+ <para>
+ Jersey uses &yasson.link; for JSON Binding (JSR-367) implementation.
+ </para>
+ <section>
+ <title>Dependency</title>
+ <para>
+ To use JSON-B as your JSON provider you need to add &lit.jersey-media-json-binding; module to your
+ &lit.pom.xml; file:
+
+ <programlisting language="xml" linenumbering="unnumbered"><dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-binding</artifactId>
+ <version>&version;</version>
+</dependency></programlisting>
+
+ If you're not using Maven make sure to have all needed dependencies
+ (see &jersey.media.json-binding.deps.link;) on the classpath.
+ </para>
+ </section>
+
+ <section xml:id="json.jsonb-registration">
+ <title>Configure and register</title>
+
+ <para>
+ As stated in <xref linkend="deployment.autodiscoverable"/> JSON-Binding media module is one of the
+ modules where you don't need to explicitly register its
+ &lit.jaxrs.core.Feature;s (&lit.jersey.media.JsonBindingFeature;) in your client/server
+ &jaxrs.core.Configurable; as this feature is automatically discovered and registered when you add
+ &lit.jersey-media-json-binding; module to your classpath.
+ </para>
+ <para>
+ To use custom preconfigured JSON-B, it is simply possible to register
+ a &lit.jaxrs.ext.ContextResolver; for &lit.jsonb.Jsonb; in your &jaxrs.core.Configurable;
+ (client/server) and configure &jsonb.JsonbConfig;.
+ </para>
+
+ <example>
+ <title><literal>ContextResolver<Jsonb></literal></title>
+
+ <programlisting language="java">@Provider
+public class JsonbContextResolver implements ContextResolver<Jsonb> {
+
+ @Override
+ public Jsonb getContext(Class>?< type) {
+ JsonbConfig config = new JsonbConfig();
+ // configure JsonbConfig
+ ...
+ return JsonbBuilder.create(config);
+ }
+}</programlisting>
+ </example>
+ <example>
+ <title><literal>Register the feature and ContextResolver<Jsonb></literal></title>
+ <programlisting language="java">ClientBuilder.newClient(new ClientConfig()
+ // The line below that registers JSON-Binding feature can be
+ // omitted if FEATURE_AUTO_DISCOVERY_DISABLE is not disabled.
+ .register(JsonBindingFeature.class)
+ .register(JsonbContextResolver.class)
+);</programlisting>
+ </example>
+
+ <formalpara>
+ <title>Example</title>
+ <para>
+ You can take a look at a provided
+ <link xlink:href='&jersey.github.examples.uri;/json-binding-webapp'>JSON-B example.</link>.
+ </para>
+ </formalpara>
+ </section>
+
+ </section>
</section>
<section xml:id="xml">
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtil.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtil.java
index 44c7984..2f97dd5 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtil.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtil.java
@@ -60,6 +60,44 @@
}
/**
+ * Parses all required parameters from expr string.
+ * Parameters encapsulated by {} or parameters with regexp expressions like {param: (regex_here)}
+ *
+ * @param expr string expression
+ * @return path params
+ */
+ static List<String> getAllMatchingParams(String expr) {
+ List<String> allMatches = new ArrayList<>();
+ if (expr == null || expr.isEmpty() || expr.indexOf('{') == -1) {
+ return allMatches;
+ }
+
+ boolean matching = false;
+ int parenthesisMatched = 0;
+ StringBuilder matchingParameter = new StringBuilder();
+ for (int i = 0; i < expr.length(); i++) {
+ char x = expr.charAt(i);
+
+ if (!matching && x == '{' && parenthesisMatched == 0) {
+ matching = true;
+ } else if (matching && x != ':' && x != '}') {
+ matchingParameter.append(x);
+ } else if (matching) {
+ allMatches.add(matchingParameter.toString());
+ matchingParameter.setLength(0);
+ matching = false;
+ }
+
+ if (x == '}') {
+ parenthesisMatched--;
+ } else if (x == '{') {
+ parenthesisMatched++;
+ }
+ }
+ return allMatches;
+ }
+
+ /**
* Validates and returns proper compute method defined in {@link ClientHeaderParam}.
*
* @param iClass interface class
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java
index c6c491e..87ae56e 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java
@@ -655,7 +655,7 @@
private void validateParameters() {
UriBuilder uriBuilder = UriBuilder.fromUri(interfaceModel.getPath()).path(pathValue);
- List<String> parameters = InterfaceUtil.parseParameters(uriBuilder.toTemplate());
+ List<String> parameters = InterfaceUtil.getAllMatchingParams(uriBuilder.toTemplate());
List<String> methodPathParameters = new ArrayList<>();
List<ParamModel> pathHandlingParams = parameterModels.stream()
.filter(parameterModel -> parameterModel.handles(PathParam.class))
diff --git a/ext/mvc-jsp/src/main/java/org/glassfish/jersey/server/mvc/jsp/JspTemplateProcessor.java b/ext/mvc-jsp/src/main/java/org/glassfish/jersey/server/mvc/jsp/JspTemplateProcessor.java
index 7baf6f5..17f4904 100644
--- a/ext/mvc-jsp/src/main/java/org/glassfish/jersey/server/mvc/jsp/JspTemplateProcessor.java
+++ b/ext/mvc-jsp/src/main/java/org/glassfish/jersey/server/mvc/jsp/JspTemplateProcessor.java
@@ -134,6 +134,15 @@
public PrintWriter getWriter() throws IOException {
return responseWriter;
}
+
+ @Override
+ public void flushBuffer() throws IOException {
+ /*
+ * Need to avoid different implementations to do something else, like invalidating new
+ * headers after flushBuffer, because later when ContainerResponse.closes it flushBuffer again.
+ */
+ getOutputStream().flush();
+ }
});
} catch (final Exception e) {
throw new ContainerException(e);
diff --git a/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/KryoFeature.java b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/KryoFeature.java
index 91d62a6..7a20060 100644
--- a/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/KryoFeature.java
+++ b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/KryoFeature.java
@@ -22,21 +22,58 @@
import org.glassfish.jersey.Beta;
import org.glassfish.jersey.kryo.internal.KryoMessageBodyProvider;
+import org.glassfish.jersey.kryo.internal.RegistrationNotRequiredKryoContextResolver;
/**
+ * <p>
* Feature used to register Kryo providers.
+ * </p>
+ * <p>
+ * For the security reasons, Kryo#setRegistrationRequired(true) should be specified.
+ * Unless {@code KryoFeature#registrationRequired(false)} is registered, a {@code ContextResolver<Kryo>} should be registered.
+ * There the user is expected to create new {@code Kryo} instance with the registrations:
+ * <pre>
+ * public Kryo getContext(Class<?> type) {
+ * ...
+ * Kryo kryo = new Kryo();
+ * kryo.setRegistrationRequired(true);
+ * kryo.register(The_class_for_which_the_KryoMessageBodyProvider_should_be_allowed);
+ * ...
+ * return kryo;
+ * }
+ * </pre>
+ * Note that {@code ContextResolver#getContext} is invoked just once when creating {@code KryoPool} and the {@code type} argument
+ * is {@code null}.
+ * </p>
*
* @author Libor Kramolis
*/
@Beta
public class KryoFeature implements Feature {
+ private final boolean registrationRequired;
+
+ public KryoFeature() {
+ registrationRequired = true;
+ }
+
+ public static KryoFeature registrationRequired(boolean registrationRequired) {
+ return new KryoFeature(registrationRequired);
+ }
+
+ private KryoFeature(boolean registrationRequired) {
+ this.registrationRequired = registrationRequired;
+ }
+
@Override
public boolean configure(final FeatureContext context) {
final Configuration config = context.getConfiguration();
if (!config.isRegistered(KryoMessageBodyProvider.class)) {
context.register(KryoMessageBodyProvider.class);
+ if (!registrationRequired) {
+ context.register(RegistrationNotRequiredKryoContextResolver.class);
+ }
}
return true;
diff --git a/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/KryoMessageBodyProvider.java b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/KryoMessageBodyProvider.java
index 2773c91..afd77b1 100644
--- a/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/KryoMessageBodyProvider.java
+++ b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/KryoMessageBodyProvider.java
@@ -21,15 +21,20 @@
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
+import java.util.Optional;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.MessageBodyReader;
import jakarta.ws.rs.ext.MessageBodyWriter;
import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.Providers;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
@@ -39,6 +44,7 @@
import com.esotericsoftware.kryo.pool.KryoPool;
/**
+ * The KryoMessageBodyProvider expects a {@code ContextResolver<Kryo>} registered.
* @author Libor Kramolis
*/
@Provider
@@ -46,18 +52,27 @@
@Produces("application/x-kryo")
public class KryoMessageBodyProvider implements MessageBodyWriter<Object>, MessageBodyReader<Object> {
- private final KryoPool kryoPool;
+ private final ContextResolver<Kryo> contextResolver;
+ private final Optional<KryoPool> kryoPool;
- public KryoMessageBodyProvider() {
+ public KryoMessageBodyProvider(@Context Providers providers) {
+ final MediaType mediaType = new MediaType("application", "x-kryo");
+ contextResolver = providers.getContextResolver(Kryo.class, mediaType);
+ kryoPool = getKryoPool();
+ }
+
+ private Kryo getKryo() {
+ return contextResolver != null ? contextResolver.getContext(null) : null;
+ }
+
+ private Optional<KryoPool> getKryoPool() {
+ final Kryo kryo = getKryo();
final KryoFactory kryoFactory = new KryoFactory() {
public Kryo create() {
- final Kryo kryo = new Kryo();
- //TODO: configure kryo instance, customize settings
- //TODO: e.g. looking for Kryo via ContextResolver (like Jackson)
return kryo;
}
};
- kryoPool = new KryoPool.Builder(kryoFactory).softReferences().build();
+ return kryo == null ? Optional.empty() : Optional.of(new KryoPool.Builder(kryoFactory).softReferences().build());
}
//
@@ -73,7 +88,7 @@
@Override
public boolean isWriteable(final Class<?> type, final Type genericType,
final Annotation[] annotations, final MediaType mediaType) {
- return true;
+ return kryoPool != null;
}
@Override
@@ -82,12 +97,12 @@
final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
throws IOException, WebApplicationException {
final Output output = new Output(entityStream);
- kryoPool.run(new KryoCallback() {
+ kryoPool.ifPresent(a -> a.run(new KryoCallback() {
public Object execute(Kryo kryo) {
kryo.writeObject(output, object);
return null;
}
- });
+ }));
output.flush();
}
@@ -98,7 +113,7 @@
@Override
public boolean isReadable(final Class<?> type, final Type genericType,
final Annotation[] annotations, final MediaType mediaType) {
- return true;
+ return kryoPool != null;
}
@Override
@@ -108,11 +123,11 @@
final InputStream entityStream) throws IOException, WebApplicationException {
final Input input = new Input(entityStream);
- return kryoPool.run(new KryoCallback() {
+ return kryoPool.map(pool -> pool.run(new KryoCallback() {
public Object execute(Kryo kryo) {
return kryo.readObject(input, type);
}
- });
+ })).orElse(null);
}
}
diff --git a/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/RegistrationNotRequiredKryoContextResolver.java b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/RegistrationNotRequiredKryoContextResolver.java
new file mode 100644
index 0000000..786c2fb
--- /dev/null
+++ b/incubator/kryo/src/main/java/org/glassfish/jersey/kryo/internal/RegistrationNotRequiredKryoContextResolver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2020 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.kryo.internal;
+
+import com.esotericsoftware.kryo.Kryo;
+
+import javax.ws.rs.ext.ContextResolver;
+
+/**
+ * Backwards compatibility ContextResolver.
+ * It should only be used when the user specifically agrees on a vulnerability provided when the
+ * <code>KryoFeature#registrationRequired(false)</code> is used.
+ * The default behaviour is demanded to require {@code ContextResolver} with
+ * <pre>
+ * public Kryo getContext(Class<?> type) {
+ * ...
+ * Kryo kryo = new Kryo();
+ * kryo.setRegistrationRequired(true);
+ * kryo.register(The_class_for_which_the_KryoMessageBodyProvider_should_be_allowed);
+ * ...
+ * return kryo;
+ * }
+ * </pre>
+ */
+public class RegistrationNotRequiredKryoContextResolver implements ContextResolver<Kryo> {
+ @Override
+ public Kryo getContext(Class<?> type) {
+ return new Kryo();
+ }
+}
diff --git a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/JaxRsApplication.java b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/JaxRsApplication.java
deleted file mode 100644
index 8af51ce..0000000
--- a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/JaxRsApplication.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015, 2020 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.kryo;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import jakarta.ws.rs.core.Application;
-
-/**
- * Test case JAX-RS application.
- *
- * @author Libor Kramolis
- */
-public class JaxRsApplication extends Application {
-
- static final Set<Class<?>> APP_CLASSES = new HashSet<Class<?>>() {{
- add(PersonResource.class);
- }};
-
- @Override
- public Set<Class<?>> getClasses() {
- return APP_CLASSES;
- }
-
-}
diff --git a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/KryoContextResolver.java b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/KryoContextResolver.java
new file mode 100644
index 0000000..1db7814
--- /dev/null
+++ b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/KryoContextResolver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 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.kryo;
+
+import com.esotericsoftware.kryo.Kryo;
+
+import jakarta.ws.rs.ext.ContextResolver;
+
+public class KryoContextResolver implements ContextResolver<Kryo> {
+ @Override
+ public Kryo getContext(Class<?> type) {
+ Kryo kryo = new Kryo();
+ kryo.setRegistrationRequired(true);
+ kryo.register(Person.class);
+ return kryo;
+ }
+}
diff --git a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceBaseTest.java b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceBaseTest.java
new file mode 100644
index 0000000..2bbedf8
--- /dev/null
+++ b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceBaseTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 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.kryo;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import static org.junit.Assert.assertEquals;
+
+public abstract class PersonResourceBaseTest extends JerseyTest {
+
+ @Test
+ public void testGet() {
+ final Person getResponse = target().request().get(Person.class);
+ assertEquals("Wolfgang", getResponse.name);
+ assertEquals(21, getResponse.age);
+ assertEquals("Salzburg", getResponse.address);
+ }
+
+ @Test
+ public void testPost() {
+ final Person[] testData = new Person[] {new Person("Joseph", 23, "Nazareth"), new Person("Mary", 18, "Nazareth")};
+ for (Person original : testData) {
+ final Person postResponse = target().request()
+ .post(Entity.entity(original, "application/x-kryo"), Person.class);
+ assertEquals(original, postResponse);
+ }
+ }
+
+ @Test
+ public void testPut() {
+ final Response putResponse = target().request().put(Entity.entity(new Person("Jules", 12, "Paris"),
+ "application/x-kryo"));
+ assertEquals(204, putResponse.getStatus());
+ }
+
+}
diff --git a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceRegistrationNotRequiredTest.java b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceRegistrationNotRequiredTest.java
new file mode 100644
index 0000000..31ef246
--- /dev/null
+++ b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceRegistrationNotRequiredTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 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.kryo;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.TestProperties;
+
+import javax.ws.rs.core.Application;
+
+public class PersonResourceRegistrationNotRequiredTest extends PersonResourceBaseTest {
+ @Override
+ protected Application configure() {
+ enable(TestProperties.LOG_TRAFFIC);
+ enable(TestProperties.DUMP_ENTITY);
+ return new ResourceConfig().register(PersonResource.class).register(KryoFeature.registrationRequired(false));
+ }
+
+ @Override
+ protected void configureClient(final ClientConfig config) {
+ config.register(KryoFeature.registrationRequired(false));
+ }
+}
diff --git a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceTest.java b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceTest.java
index 37512ab..af84146 100644
--- a/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceTest.java
+++ b/incubator/kryo/src/test/java/org/glassfish/jersey/kryo/PersonResourceTest.java
@@ -21,6 +21,7 @@
import jakarta.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
@@ -32,42 +33,17 @@
*
* @author Libor Kramolis
*/
-public class PersonResourceTest extends JerseyTest {
+public class PersonResourceTest extends PersonResourceBaseTest {
@Override
protected Application configure() {
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);
- return new JaxRsApplication();
+ return new ResourceConfig().register(PersonResource.class).register(KryoContextResolver.class);
}
@Override
protected void configureClient(final ClientConfig config) {
+ config.register(KryoContextResolver.class);
}
-
- @Test
- public void testGet() {
- final Person getResponse = target().request().get(Person.class);
- assertEquals("Wolfgang", getResponse.name);
- assertEquals(21, getResponse.age);
- assertEquals("Salzburg", getResponse.address);
- }
-
- @Test
- public void testPost() {
- final Person[] testData = new Person[] {new Person("Joseph", 23, "Nazareth"), new Person("Mary", 18, "Nazareth")};
- for (Person original : testData) {
- final Person postResponse = target().request()
- .post(Entity.entity(original, "application/x-kryo"), Person.class);
- assertEquals(original, postResponse);
- }
- }
-
- @Test
- public void testPut() {
- final Response putResponse = target().request().put(Entity.entity(new Person("Jules", 12, "Paris"),
- "application/x-kryo"));
- assertEquals(204, putResponse.getStatus());
- }
-
}
diff --git a/pom.xml b/pom.xml
index 8f5be09..1b50dce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -524,10 +524,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
- <configuration>
- <generateProjectInfo>false</generateProjectInfo>
- <generateReports>true</generateReports>
- </configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -2160,7 +2156,7 @@
<javax.annotation.version>1.3.5</javax.annotation.version> <!--Deprecated, used only for @generated annotation in perf tests -->
<jetty.plugin.version>6.1.26</jetty.plugin.version>
- <jetty.version>9.4.27.v20200227</jetty.version>
+ <jetty.version>9.4.28.v20200408</jetty.version>
<jetty.servlet.api.25.version>6.1.14</jetty.servlet.api.25.version>
<mimepull.version>1.9.13</mimepull.version>
diff --git a/tests/integration/jersey-4507/pom.xml b/tests/integration/jersey-4507/pom.xml
new file mode 100644
index 0000000..4d5352c
--- /dev/null
+++ b/tests/integration/jersey-4507/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2020 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">
+ <parent>
+ <artifactId>project</artifactId>
+ <groupId>org.glassfish.jersey.tests.integration</groupId>
+ <version>2.32.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>jersey-4507</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-bundle</artifactId>
+ <type>pom</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.examples</groupId>
+ <artifactId>server-sent-events-jersey</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/tests/integration/jersey-4507/src/test/java/org/glassfish/jersey/tests/integration/jersey4507/SSETest.java b/tests/integration/jersey-4507/src/test/java/org/glassfish/jersey/tests/integration/jersey4507/SSETest.java
new file mode 100644
index 0000000..b02eda5
--- /dev/null
+++ b/tests/integration/jersey-4507/src/test/java/org/glassfish/jersey/tests/integration/jersey4507/SSETest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2020 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.integration.jersey4507;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientLifecycleListener;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.examples.sse.jersey.App;
+import org.glassfish.jersey.examples.sse.jersey.DomainResource;
+import org.glassfish.jersey.examples.sse.jersey.ServerSentEventsResource;
+import org.glassfish.jersey.media.sse.EventInput;
+import org.glassfish.jersey.media.sse.InboundEvent;
+import org.glassfish.jersey.media.sse.SseFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+
+public class SSETest extends JerseyTest {
+ private static final int MAX_CLIENTS = 10;
+ private static final int COUNT = 30;
+ private static final AtomicInteger atomicInteger = new AtomicInteger(0);
+ private static final CountDownLatch closeLatch = new CountDownLatch(COUNT);
+
+ @Override
+ protected Application configure() {
+ // enable(TestProperties.LOG_TRAFFIC);
+ return new ResourceConfig(ServerSentEventsResource.class, DomainResource.class, SseFeature.class);
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.property(ClientProperties.ASYNC_THREADPOOL_SIZE, MAX_CLIENTS + 2);
+ config.register(new ClientRuntimeCloseVerifier());
+ }
+
+ /**
+ * Test consuming multiple SSE events sequentially using event input.
+ *
+ * @throws Exception in case of a failure during the test execution.
+ */
+ public void testInboundEventReader() throws Exception {
+ final int MAX_MESSAGES = 5;
+ final CountDownLatch startLatch = new CountDownLatch(1);
+
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+ try {
+ final Future<List<String>> futureMessages =
+ executor.submit(new Callable<List<String>>() {
+
+ @Override
+ public List<String> call() throws Exception {
+ final EventInput eventInput = target(App.ROOT_PATH).register(SseFeature.class)
+ .request().get(EventInput.class);
+
+ startLatch.countDown();
+
+ final List<String> messages = new ArrayList<String>(MAX_MESSAGES);
+ try {
+ for (int i = 0; i < MAX_MESSAGES; i++) {
+ InboundEvent event = eventInput.read();
+ messages.add(event.readData());
+ }
+ } finally {
+ if (eventInput != null) {
+ eventInput.close();
+ }
+ }
+
+ return messages;
+ }
+ });
+
+ Assert.assertTrue("Waiting for receiver thread to start has timed out.",
+ startLatch.await(15000, TimeUnit.SECONDS));
+
+ for (int i = 0; i < MAX_MESSAGES; i++) {
+ target(App.ROOT_PATH).request().post(Entity.text("message " + i));
+ }
+
+ int i = 0;
+ for (String message : futureMessages.get(50, TimeUnit.SECONDS)) {
+ Assert.assertThat("Unexpected SSE event data value.", message, equalTo("message " + i++));
+ }
+ } finally {
+ executor.shutdownNow();
+ }
+ }
+
+ @Test
+ public void testInboundEventReaderMultiple() throws Exception {
+ for (int i = 0; i != COUNT; i++) {
+ testInboundEventReader();
+ }
+
+ System.gc();
+ closeLatch.await(15_000, TimeUnit.MILLISECONDS);
+ // One ClientConfig is on the Client
+ // + COUNT of them is created by .register(SseFeature.class)
+ Assert.assertEquals(COUNT + 1, atomicInteger.get());
+ Assert.assertEquals(0, closeLatch.getCount());
+ }
+
+
+
+ public static class ClientRuntimeCloseVerifier implements ClientLifecycleListener {
+
+ @Override
+ public void onInit() {
+ atomicInteger.incrementAndGet();
+ }
+
+ @Override
+ public void onClose() {
+ closeLatch.countDown();
+ }
+ }
+}
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtilTest.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtilTest.java
new file mode 100644
index 0000000..fb40a45
--- /dev/null
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/InterfaceUtilTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 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.microprofile.restclient;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class InterfaceUtilTest {
+
+ @Test
+ public void testGetAllParams() {
+ assertEquals(InterfaceUtil.getAllMatchingParams(
+ "{abc}/{xyzId: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}"),
+ Arrays.asList("abc", "xyzId"));
+ assertEquals(InterfaceUtil.getAllMatchingParams(
+ "{xyzId: [a-zA-Z]+}/{abc}"), Arrays.asList("xyzId", "abc"));
+ }
+}
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
index 19168d2..8bc1ae7 100644
--- a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
@@ -26,6 +26,7 @@
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
@@ -66,4 +67,13 @@
@Path("methodContent")
String methodContentType(@HeaderParam(HttpHeaders.CONTENT_TYPE) MediaType contentType, String entity);
+ @GET
+ @Path("{content: [a-zA-Z]+}")
+ @Produces(MediaType.TEXT_PLAIN)
+ String regex(@PathParam("content") String content);
+
+ @GET
+ @Path("content1/{content1}/content0/{content0: [0-9]{4}}")
+ @Produces(MediaType.TEXT_PLAIN)
+ String regex0(@PathParam("content1") String context0, @PathParam("content0") String context1);
}
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
index 7ee784e..12c31e2 100644
--- a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
@@ -62,4 +62,13 @@
return null;
}
+ @Override
+ public String regex(String content) {
+ return content;
+ }
+
+ @Override
+ public String regex0(String context0, String context1) {
+ return context0 + "_" + context1;
+ }
}
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java
index c53cea6..16ed03c 100644
--- a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2019, 2020 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.restclient;
import java.net.URI;
@@ -6,6 +22,7 @@
import jakarta.json.Json;
import jakarta.json.JsonValue;
+import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.core.HttpHeaders;
@@ -75,6 +92,33 @@
app.methodContentType(MediaType.TEXT_XML_TYPE, "something");
}
+ @Test
+ public void testMethodWithRegexPathParam() throws URISyntaxException {
+ ApplicationResource app = RestClientBuilder.newBuilder()
+ .baseUri(new URI("http://localhost:9998"))
+ .build(ApplicationResource.class);
+
+ assertEquals(app.regex("bar"), "bar");
+ }
+
+ @Test
+ public void testMethodWithRegexPathParam0() throws URISyntaxException {
+ ApplicationResource app = RestClientBuilder.newBuilder()
+ .baseUri(new URI("http://localhost:9998"))
+ .build(ApplicationResource.class);
+
+ assertEquals(app.regex0("foo", "1234"), "foo_1234");
+ }
+
+ @Test(expected = WebApplicationException.class)
+ public void testMethodWithRegexPathParam0Failure() throws URISyntaxException {
+ ApplicationResource app = RestClientBuilder.newBuilder()
+ .baseUri(new URI("http://localhost:9998"))
+ .build(ApplicationResource.class);
+
+ app.regex0("foo", "12345");
+ }
+
private static class TestClientRequestFilter implements ClientRequestFilter {
private final String expectedAccept;
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index 454ab81..c989c1b 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -85,6 +85,7 @@
<module>jersey-4003</module>
<module>jersey-4099</module>
<module>jersey-4321</module>
+ <module>jersey-4507</module>
<module>jetty-response-close</module>
<module>microprofile</module>
<!-- <module>portability-jersey-1</module>--> <!--TODO remove when Jakartified -->
@@ -123,6 +124,7 @@
<module>servlet-3-init-provider</module>
<module>servlet-3-params</module>
<module>servlet-3-sse-1</module>
+ <module>servlet-4.0-mvc-1</module>
<module>servlet-request-wrapper-binding-2</module>
<module>servlet-request-wrapper-binding</module>
<module>servlet-tests</module>
diff --git a/tests/integration/servlet-4.0-mvc-1/pom.xml b/tests/integration/servlet-4.0-mvc-1/pom.xml
new file mode 100644
index 0000000..01f5af4
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2020 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.glassfish.jersey.tests.integration</groupId>
+ <artifactId>project</artifactId>
+ <version>2.32.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>servlet-4.0-mvc-1</artifactId>
+ <packaging>war</packaging>
+ <name>jersey-tests-integration-servlet-4.0-mvc-1</name>
+
+ <description>Servlet integration test - servlet-2.5-mvc-4 - filter - MVC - jersey.config.servlet.JspTemplatesBasePath</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc-jsp</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <version>${servlet4.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-external</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>jdk11+</id>
+ <activation>
+ <jdk>[11,)</jdk>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-osgi</artifactId>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/MyApplication.java b/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/MyApplication.java
new file mode 100644
index 0000000..e17abda
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/MyApplication.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 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.integration.servlet_40_mvc_1;
+
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.filter.EncodingFilter;
+import org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
+import org.glassfish.jersey.tests.integration.servlet_40_mvc_1.resource.ExampleResource;
+
+public class MyApplication extends ResourceConfig {
+
+ public MyApplication() {
+ property("jersey.config.server.mvc.templateBasePath.jsp", "/WEB-INF/jsp");
+ property("jersey.config.servlet.filter.forwardOn404", "true");
+ property("jersey.config.servlet.filter.staticContentRegex", "/WEB-INF/.*\\.jsp");
+ packages(ExampleResource.class.getPackage().getName());
+ EncodingFilter.enableFor(this, new Class[] {GZipEncoder.class});
+ register(JspMvcFeature.class);
+ }
+}
diff --git a/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/resource/ExampleResource.java b/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/resource/ExampleResource.java
new file mode 100644
index 0000000..2a8aaf8
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/main/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/resource/ExampleResource.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020 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.integration.servlet_40_mvc_1.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+import org.glassfish.jersey.server.mvc.Viewable;
+
+@Path("/{client}")
+public class ExampleResource {
+
+ @GET
+ @Path("html")
+ @Produces({ "text/html" })
+ public Viewable displayMain(@PathParam("client") String inClientId) {
+ return new Viewable("/main");
+ }
+
+ @GET
+ @Path("string")
+ @Produces({ "text/html" })
+ public String string(@PathParam("client") String inClientId) {
+ return "string string string string string string";
+ }
+}
diff --git a/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/jsp/main.jsp b/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/jsp/main.jsp
new file mode 100644
index 0000000..dfc67cb
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/jsp/main.jsp
@@ -0,0 +1,28 @@
+<%--
+
+ Copyright (c) 2020 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
+
+--%>
+
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test</title>
+
+</head>
+<body>
+find this string
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/web.xml b/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..a0adce3
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2020 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
+
+-->
+
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
+ version="4.0"
+ metadata-complete="true">
+ <filter>
+ <filter-name>org.glassfish.jersey.tests.integration.servlet_40_mvc_1.MyApplication</filter-name>
+ <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.glassfish.jersey.tests.integration.servlet_40_mvc_1.MyApplication</param-value>
+ </init-param>
+ </filter>
+ <filter-mapping>
+ <filter-name>org.glassfish.jersey.tests.integration.servlet_40_mvc_1.MyApplication</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+</web-app>
diff --git a/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/GzipITCase.java b/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/GzipITCase.java
new file mode 100644
index 0000000..9db8de7
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/GzipITCase.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2020 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.integration.servlet_40_mvc_1;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.message.GZipEncoder;
+import org.junit.Test;
+
+public class GzipITCase extends TestSupport {
+
+ @Test
+ public void testString() throws Exception {
+ Response response = target("/client/string").register(GZipEncoder.class)
+ .request("text/html").acceptEncoding("gzip").get();
+ String resp = response.readEntity(String.class);
+ assertResponseContains(resp, "string string string string string string");
+ assertEquals("gzip", response.getHeaderString("Content-Encoding"));
+ }
+
+ @Test
+ public void testJsp() throws Exception {
+ Response response = target("/client/html").register(GZipEncoder.class)
+ .request("text/html", "application/xhtml+xml", "application/xml;q=0.9", "*/*;q=0.8").acceptEncoding("gzip")
+ .get();
+ String resp = response.readEntity(String.class);
+ assertHtmlResponse(resp);
+ assertResponseContains(resp, "find this string");
+ assertEquals("gzip", response.getHeaderString("Content-Encoding"));
+ }
+
+ @Test
+ public void testJspNotDecoded() throws Exception {
+ Response response = target("/client/html")
+ .request("text/html", "application/xhtml+xml", "application/xml;q=0.9", "*/*;q=0.8").acceptEncoding("gzip")
+ .get();
+ String resp = response.readEntity(String.class);
+ assertFalse(resp.contains("find this string"));
+ assertEquals("gzip", response.getHeaderString("Content-Encoding"));
+ }
+
+}
diff --git a/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/TestSupport.java b/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/TestSupport.java
new file mode 100644
index 0000000..4185a64
--- /dev/null
+++ b/tests/integration/servlet-4.0-mvc-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_40_mvc_1/TestSupport.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020 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.integration.servlet_40_mvc_1;
+
+import javax.ws.rs.core.Application;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerException;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.glassfish.jersey.tests.integration.servlet_40_mvc_1.MyApplication;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public abstract class TestSupport extends JerseyTest {
+
+ @Override
+ protected Application configure() {
+ enable(TestProperties.LOG_TRAFFIC);
+ enable(TestProperties.DUMP_ENTITY);
+ return new MyApplication();
+ }
+
+ @Override
+ protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
+ return new ExternalTestContainerFactory();
+ }
+
+ protected void assertHtmlResponse(final String response) {
+ assertNotNull("No text returned!", response);
+
+ assertResponseContains(response, "<html>");
+ assertResponseContains(response, "</html>");
+ }
+
+ protected void assertResponseContains(final String response, final String text) {
+ assertTrue("Response should contain " + text + " but was: " + response, response.contains(text));
+ }
+}
diff --git a/tests/performance/test-cases/mbw-kryo/src/main/java/org/glassfish/jersey/tests/performance/mbw/kryo/JaxRsApplication.java b/tests/performance/test-cases/mbw-kryo/src/main/java/org/glassfish/jersey/tests/performance/mbw/kryo/JaxRsApplication.java
index 8558489..9c388a8 100644
--- a/tests/performance/test-cases/mbw-kryo/src/main/java/org/glassfish/jersey/tests/performance/mbw/kryo/JaxRsApplication.java
+++ b/tests/performance/test-cases/mbw-kryo/src/main/java/org/glassfish/jersey/tests/performance/mbw/kryo/JaxRsApplication.java
@@ -16,6 +16,9 @@
package org.glassfish.jersey.tests.performance.mbw.kryo;
+import org.glassfish.jersey.kryo.KryoFeature;
+
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -37,4 +40,8 @@
return APP_CLASSES;
}
+ @Override
+ public Set<Object> getSingletons() {
+ return Collections.singleton(KryoFeature.registrationRequired(false));
+ }
}
diff --git a/tests/performance/test-cases/mbw-kryo/src/test/java/org/glassfish/jersey/tests/performance/mbw/kryo/PersonResourceTest.java b/tests/performance/test-cases/mbw-kryo/src/test/java/org/glassfish/jersey/tests/performance/mbw/kryo/PersonResourceTest.java
index 0a0c2cd..481e103 100644
--- a/tests/performance/test-cases/mbw-kryo/src/test/java/org/glassfish/jersey/tests/performance/mbw/kryo/PersonResourceTest.java
+++ b/tests/performance/test-cases/mbw-kryo/src/test/java/org/glassfish/jersey/tests/performance/mbw/kryo/PersonResourceTest.java
@@ -21,6 +21,7 @@
import jakarta.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.kryo.KryoFeature;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
@@ -40,6 +41,7 @@
@Override
protected void configureClient(final ClientConfig config) {
+ config.register(KryoFeature.registrationRequired(false));
}
@Test
diff --git a/tests/performance/test-cases/monitoring/pom.xml b/tests/performance/test-cases/monitoring/pom.xml
index 3b1404b..f868244 100644
--- a/tests/performance/test-cases/monitoring/pom.xml
+++ b/tests/performance/test-cases/monitoring/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2014, 2020 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
@@ -60,12 +60,6 @@
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>14.0.1</version>
- </dependency>
-
- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.1</version>