Merge pull request #4838 from senivam/3x_merged
merge master into 3.x
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 92750fc..43737f1 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
@@ -43,6 +43,7 @@
import org.glassfish.jersey.internal.BootstrapConfigurator;
import org.glassfish.jersey.internal.ContextResolverFactory;
import org.glassfish.jersey.internal.ExceptionMapperFactory;
+import org.glassfish.jersey.internal.FeatureConfigurator;
import org.glassfish.jersey.internal.JaxrsProviders;
import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.internal.inject.Bindings;
@@ -53,7 +54,6 @@
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.internal.MessageBodyFactory;
import org.glassfish.jersey.model.internal.CommonConfig;
import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.model.internal.ManagedObjectsFinalizer;
@@ -429,7 +429,8 @@
new ExceptionMapperFactory.ExceptionMappersConfigurator(),
new JaxrsProviders.ProvidersConfigurator(),
new AutoDiscoverableConfigurator(RuntimeType.CLIENT),
- new ClientComponentConfigurator());
+ new ClientComponentConfigurator(),
+ new FeatureConfigurator(RuntimeType.CLIENT));
bootstrapConfigurators.forEach(configurator -> configurator.init(injectionManager, bootstrapBag));
// AutoDiscoverable.
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/JaxRsFeatureRegistrationClientTest.java b/core-client/src/test/java/org/glassfish/jersey/client/JaxRsFeatureRegistrationClientTest.java
new file mode 100644
index 0000000..f56bc26
--- /dev/null
+++ b/core-client/src/test/java/org/glassfish/jersey/client/JaxRsFeatureRegistrationClientTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021 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.CommonProperties;
+import org.junit.Test;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.Response;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class JaxRsFeatureRegistrationClientTest {
+
+ private static final String REGISTERED_FEATURE_RESPONSE = "RegisteredFeature";
+
+ private static final ClientRequestFilter component =
+ requestContext -> requestContext
+ .abortWith(Response.status(400).entity(REGISTERED_FEATURE_RESPONSE).build());
+
+ public static class FeatureClientImpl implements Feature {
+
+ @Override
+ public boolean configure(FeatureContext context) {
+ if ("true".equals(context.getConfiguration().getProperty("runWithJaxRsClient"))) {
+ context.register(component);
+ }
+ return true;
+ }
+ }
+
+ @Test
+ public void featureRegistrationTest() {
+ final ClientConfig config = new ClientConfig().property("runWithJaxRsClient", "true");
+ final Client client = ClientBuilder.newClient(config);
+ final Invocation.Builder request = client.target("").request();
+
+ assertEquals(REGISTERED_FEATURE_RESPONSE, request.get().readEntity(String.class));
+
+ client.close();
+ }
+
+ @Test
+ public void featureNotRegistrationTest() {
+ final ClientConfig config = new ClientConfig()
+ .property(CommonProperties.JAXRS_SERVICE_LOADING_ENABLE, false);
+ final Client client = ClientBuilder.newClient(config);
+ final Invocation.Builder request = client.target("").request();
+
+ assertFalse(client.getConfiguration().isRegistered(FeatureClientImpl.class));
+
+ client.close();
+ }
+
+}
\ No newline at end of file
diff --git a/core-client/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature b/core-client/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature
new file mode 100644
index 0000000..99c6b86
--- /dev/null
+++ b/core-client/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature
@@ -0,0 +1 @@
+org.glassfish.jersey.client.JaxRsFeatureRegistrationClientTest$FeatureClientImpl
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/AbstractFeatureConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/AbstractFeatureConfigurator.java
new file mode 100644
index 0000000..0e4be99
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/AbstractFeatureConfigurator.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2021 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;
+
+import org.glassfish.jersey.internal.AbstractServiceFinderConfigurator;
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.internal.ServiceFinder;
+import org.glassfish.jersey.internal.spi.AutoDiscoverable;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+import jakarta.ws.rs.RuntimeType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public abstract class AbstractFeatureConfigurator<T> extends AbstractServiceFinderConfigurator<T> {
+ /**
+ * Create a new configurator.
+ *
+ * @param contract contract of the service providers bound by this binder.
+ * @param runtimeType runtime (client or server) where the service finder binder is used.
+ */
+ protected AbstractFeatureConfigurator(Class contract, RuntimeType runtimeType) {
+ super(contract, runtimeType);
+ }
+
+ /**
+ * Specification specific implementation which allows find classes by specified classloader
+ *
+ * @param applicationProperties map of properties to check if search is allowed
+ * @param loader specific classloader (must not be NULL)
+ * @return list of found classes
+ */
+ protected List<Class<T>> loadImplementations(Map<String, Object> applicationProperties, ClassLoader loader) {
+ if (PropertiesHelper.isMetaInfServicesEnabled(applicationProperties, getRuntimeType())) {
+ return Stream.of(ServiceFinder.find(getContract(), loader, true).toClassArray())
+ .collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Allows feature registration as part of autoDiscoverables list
+ *
+ * @param features list of features to be registered
+ * @param bootstrapBag place where features are being registered
+ */
+ protected void registerFeatures(List<Class<T>> features,
+ BootstrapBag bootstrapBag) {
+ final List<AutoDiscoverable> autoDiscoverables = new ArrayList<>();
+
+ features.forEach(feature -> autoDiscoverables.add(registerClass(feature)));
+
+ bootstrapBag.getAutoDiscoverables().addAll(autoDiscoverables);
+ }
+
+ /**
+ * Register particular feature as an autoDiscoverable
+ *
+ * @param classToRegister class to be registered
+ * @param <T> type of class which is being registered
+ * @return initialized autoDiscoverable
+ */
+ private static <T> AutoDiscoverable registerClass(Class<T> classToRegister) {
+ return context -> {
+ if (!context.getConfiguration().isRegistered(classToRegister)) {
+ context.register(classToRegister, AutoDiscoverable.DEFAULT_PRIORITY);
+ }
+ };
+ }
+
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
index a05f199..6b2021d 100644
--- a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
+++ b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
@@ -245,6 +245,16 @@
*/
public static final String PROVIDER_DEFAULT_DISABLE = "jersey.config.disableDefaultProvider";
+
+ /**
+ * Allows API services loading. If absent or true JAXRS services loading is allowed.
+ * Services shall implement Feature or DynamicFeature interface and be listed as SPI
+ * in user's application.
+ *
+ * @since 2.35
+ */
+ public static final String JAXRS_SERVICE_LOADING_ENABLE = "jakarta.ws.rs.loadServices";
+
/**
* Prevent instantiation.
*/
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/AbstractServiceFinderConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/AbstractServiceFinderConfigurator.java
index 0f16119..ea7c62c 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/AbstractServiceFinderConfigurator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/AbstractServiceFinderConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2021 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
@@ -65,4 +65,22 @@
}
return Collections.emptyList();
}
+
+ /**
+ * Mainly aimed to provide runtime type to abstract classes which extends this finder
+ *
+ * @return runtime type
+ */
+ protected RuntimeType getRuntimeType() {
+ return runtimeType;
+ }
+
+ /**
+ * Mainly aimed to provide contract class to abstract classes which extends this finder
+ *
+ * @return contract class
+ */
+ protected Class<T> getContract() {
+ return contract;
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java
new file mode 100644
index 0000000..e17770e
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal;
+
+import org.glassfish.jersey.AbstractFeatureConfigurator;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.container.DynamicFeature;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Registers JAX-RS {@link DynamicFeature} which are listed as SPIs for registration.
+ * Also checks if JAX-RS service loading is enabled by the jakarta.ws.rs.loadServices property. In order for
+ * registration to proceed the property shall be true (or null).
+ *
+ * Configurator is used only at Server side.
+ *
+ * This configurator's instance shall be after {@link AutoDiscoverableConfigurator}
+ * in the list of configurators due to same list of {@link org.glassfish.jersey.internal.spi.AutoDiscoverable}
+ * used in the {@link BootstrapBag} to register discovered features.
+ */
+public class DynamicFeatureConfigurator extends AbstractFeatureConfigurator<DynamicFeature> {
+
+ /**
+ * Create a new configurator.
+ *
+ * Must be used at server side only (takes no effect as a client).
+ */
+ public DynamicFeatureConfigurator() {
+ super(DynamicFeature.class, RuntimeType.SERVER);
+ }
+
+ @Override
+ public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+ final Map<String, Object> properties = bootstrapBag.getConfiguration().getProperties();
+ if (PropertiesHelper.isJaxRsServiceLoadingEnabled(properties)) {
+ final List<Class<DynamicFeature>> dynamicFeatures = loadImplementations(properties);
+ dynamicFeatures.addAll(loadImplementations(properties, DynamicFeature.class.getClassLoader()));
+
+ registerFeatures(dynamicFeatures, bootstrapBag);
+ }
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/FeatureConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/FeatureConfigurator.java
new file mode 100644
index 0000000..c3cdfc9
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/FeatureConfigurator.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal;
+
+import org.glassfish.jersey.AbstractFeatureConfigurator;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Feature;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Registers JAX-RS {@link Feature} which are listed as SPIs for registration.
+ * Also checks if JAX-RS service loading is enabled by the jakarta.ws.rs.loadServices property. In order for
+ * registration to proceed the property shall be true (or null).
+ *
+ * This configurator's instance shall be the last (or at least after {@link AutoDiscoverableConfigurator})
+ * in the list of configurators due to same list of {@link org.glassfish.jersey.internal.spi.AutoDiscoverable}
+ * used in the {@link BootstrapBag} to register discovered features.
+ */
+public class FeatureConfigurator extends AbstractFeatureConfigurator<Feature> {
+
+ public FeatureConfigurator(RuntimeType runtimeType) {
+ super(Feature.class, runtimeType);
+ }
+
+ @Override
+ public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+ final Map<String, Object> properties = bootstrapBag.getConfiguration().getProperties();
+ if (PropertiesHelper.isJaxRsServiceLoadingEnabled(properties)) {
+ final List<Class<Feature>> features = loadImplementations(properties);
+ features.addAll(loadImplementations(properties, Feature.class.getClassLoader()));
+
+ registerFeatures(features, bootstrapBag);
+ }
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/PropertiesHelper.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/PropertiesHelper.java
index 1b8b5b6..94acf7c 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/util/PropertiesHelper.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/PropertiesHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 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
@@ -41,6 +41,7 @@
private static final Logger LOGGER = Logger.getLogger(PropertiesHelper.class.getName());
private static final boolean METAINF_SERVICES_LOOKUP_DISABLE_DEFAULT = false;
+ private static final boolean JAXRS_SERVICE_LOADING_ENABLE_DEFAULT = true;
/**
* Get system properties.
@@ -334,6 +335,24 @@
}
/**
+ * Check whether loading of JAX-RS services is allowed or not. Services shall implement Feature or DynamicFeature
+ * interface and be listed as SPI in an application
+ *
+ * @param properties list of properties to be checked
+ * @return false if loading of JAX-RS services is not enabled
+ *
+ * @since 2.35
+ */
+ public static boolean isJaxRsServiceLoadingEnabled(Map<String, Object> properties) {
+ boolean enableServicesLoading = JAXRS_SERVICE_LOADING_ENABLE_DEFAULT;
+ if (properties != null) {
+ enableServicesLoading = CommonProperties.getValue(properties,
+ CommonProperties.JAXRS_SERVICE_LOADING_ENABLE, JAXRS_SERVICE_LOADING_ENABLE_DEFAULT);
+ }
+ return enableServicesLoading;
+ }
+
+ /**
* Get the value of the property with a given name converted to {@code boolean}. Returns {@code false} if the value is
* not convertible.
*
diff --git a/core-server/pom.xml b/core-server/pom.xml
index 4a8d442..fe4ea1c 100644
--- a/core-server/pom.xml
+++ b/core-server/pom.xml
@@ -156,6 +156,7 @@
<threadCount>1</threadCount>
<forkCount>1C</forkCount>
<reuseForks>true</reuseForks>
+ <systemPropertiesFile>${project.basedir}/../etc/jenkins/systemPropertiesFile</systemPropertiesFile>
</configuration>
</plugin>
</plugins>
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
index c4c95e5..42d11dd 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Payara Foundation and/or its affiliates.
*
* This program and the accompanying materials are made available under the
@@ -50,8 +50,10 @@
import org.glassfish.jersey.internal.BootstrapBag;
import org.glassfish.jersey.internal.BootstrapConfigurator;
import org.glassfish.jersey.internal.ContextResolverFactory;
+import org.glassfish.jersey.internal.DynamicFeatureConfigurator;
import org.glassfish.jersey.internal.Errors;
import org.glassfish.jersey.internal.ExceptionMapperFactory;
+import org.glassfish.jersey.internal.FeatureConfigurator;
import org.glassfish.jersey.internal.JaxrsProviders;
import org.glassfish.jersey.internal.Version;
import org.glassfish.jersey.internal.inject.Binder;
@@ -285,7 +287,9 @@
new ResourceMethodInvokerConfigurator(),
new ProcessingProvidersConfigurator(),
new ContainerProviderConfigurator(RuntimeType.SERVER),
- new AutoDiscoverableConfigurator(RuntimeType.SERVER));
+ new AutoDiscoverableConfigurator(RuntimeType.SERVER),
+ new DynamicFeatureConfigurator(),
+ new FeatureConfigurator(RuntimeType.SERVER));
bootstrapConfigurators.forEach(configurator -> configurator.init(injectionManager, bootstrapBag));
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/JaxRsFeatureRegistrationTest.java b/core-server/src/test/java/org/glassfish/jersey/server/JaxRsFeatureRegistrationTest.java
new file mode 100644
index 0000000..1ac3403
--- /dev/null
+++ b/core-server/src/test/java/org/glassfish/jersey/server/JaxRsFeatureRegistrationTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 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.server;
+
+import org.glassfish.jersey.CommonProperties;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.container.ResourceInfo;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+
+public class JaxRsFeatureRegistrationTest {
+
+ public static class FeatureImpl implements Feature {
+
+ @Override
+ public boolean configure(FeatureContext context) {
+ return true;
+ }
+ }
+
+ public static class DynamicFeatureImpl implements DynamicFeature {
+
+ @Override
+ public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+ }
+ }
+
+ @Test
+ public void featureRegistrationTest() {
+ final ResourceConfig config = new ResourceConfig();
+ final ApplicationHandler ah = new ApplicationHandler(config);
+
+ Assert.assertTrue(ah.getConfiguration().isRegistered(FeatureImpl.class));
+ Assert.assertTrue(ah.getConfiguration().isRegistered(DynamicFeatureImpl.class));
+ }
+
+ @Test
+ public void serviceLoadingPropertyTest() {
+
+ final ResourceConfig config = new ResourceConfig()
+ .property(CommonProperties.JAXRS_SERVICE_LOADING_ENABLE, "false");
+ final ApplicationHandler ah = new ApplicationHandler(config);
+
+ Assert.assertFalse(ah.getConfiguration().isRegistered(FeatureImpl.class));
+ Assert.assertFalse(ah.getConfiguration().isRegistered(DynamicFeatureImpl.class));
+ }
+}
\ No newline at end of file
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java b/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
index da2fee8..53501e6 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Payara Foundation and/or its affiliates.
*
* This program and the accompanying materials are made available under the
@@ -25,7 +25,9 @@
import org.glassfish.jersey.internal.AutoDiscoverableConfigurator;
import org.glassfish.jersey.internal.BootstrapConfigurator;
import org.glassfish.jersey.internal.ContextResolverFactory;
+import org.glassfish.jersey.internal.DynamicFeatureConfigurator;
import org.glassfish.jersey.internal.ExceptionMapperFactory;
+import org.glassfish.jersey.internal.FeatureConfigurator;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.Binder;
import org.glassfish.jersey.internal.inject.InjectionManager;
@@ -113,7 +115,9 @@
new ExternalRequestScopeConfigurator(),
new ModelProcessorConfigurator(),
new ResourceModelConfigurator(),
- new ServerExecutorProvidersConfigurator());
+ new ServerExecutorProvidersConfigurator(),
+ new DynamicFeatureConfigurator(),
+ new FeatureConfigurator(RuntimeType.SERVER));
bootstrapConfigurators.forEach(configurator -> configurator.init(injectionManager, bootstrapBag));
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java
index d92393e..d8f9a8c 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java
@@ -37,12 +37,6 @@
private static final int COLLISION_BUFFER_POWER = 3;
private static final double DELTA = 0.0001;
- @BeforeClass
- public static void beforeClass() {
- System.setProperty(ServerProperties.COLLISION_BUFFER_POWER_JVM_ARG,
- Integer.toString(COLLISION_BUFFER_POWER));
- }
-
@Test
public void jvmLoaded() {
assertEquals(COLLISION_BUFFER_POWER, ReservoirConstants.COLLISION_BUFFER_POWER);
diff --git a/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.container.DynamicFeature b/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.container.DynamicFeature
new file mode 100644
index 0000000..56c113e
--- /dev/null
+++ b/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.container.DynamicFeature
@@ -0,0 +1 @@
+org.glassfish.jersey.server.JaxRsFeatureRegistrationTest$DynamicFeatureImpl
\ No newline at end of file
diff --git a/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature b/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature
new file mode 100644
index 0000000..050876b
--- /dev/null
+++ b/core-server/src/test/resources/META-INF/services/jakarta.ws.rs.core.Feature
@@ -0,0 +1 @@
+org.glassfish.jersey.server.JaxRsFeatureRegistrationTest$FeatureImpl
\ No newline at end of file
diff --git a/docs/src/main/docbook/client.xml b/docs/src/main/docbook/client.xml
index e74f459..4814b9d 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -848,7 +848,7 @@
</example>
<para>
For more information see javadoc of &jersey.client.InjectionManagerClientProvider;
- (and javadoc of &jersey.common.InjectionManagerProvider; which supports common JAX-RS components).
+ (and javadoc of &lit.jersey.common.InjectionManagerProvider; which supports common JAX-RS components).
</para>
</section>
diff --git a/docs/src/main/docbook/graalvm-native-image.xml b/docs/src/main/docbook/graalvm-native-image.xml
new file mode 100644
index 0000000..c64bbc3
--- /dev/null
+++ b/docs/src/main/docbook/graalvm-native-image.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0"?>
+<!--
+
+ Copyright (c) 2021 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
+
+-->
+
+<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents; ]>
+<chapter xmlns="http://docbook.org/ns/docbook"
+ version="5.0"
+ xml:lang="en"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
+ http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
+ xml:id="graalvm-native-image">
+ <title>GraalVM native-image generation</title>
+ <para>
+ This chapter describes Jersey's compatibility with GraalVM native image. This functionality is available since
+ Jersey 2.35 and is under development and configuration. For now Jersey provides native image configuration
+ basics for some modules and example on how to really generate native image for an existing application.
+ </para>
+ <section xml:id="supported_modules">
+ <title>Modules with GraalVM native image support</title>
+ <para>
+ Currently Jersey provides basic support for native image generation within following modules:
+ <literal>jersey-common</literal>,<literal>jersey-server</literal>,<literal>jersey-client</literal>,
+ <literal>jersey-hk2</literal>.
+
+ This support means that most of reflection and resource related settings are extracted into reflect-config
+ and resource-config JSON files to be used while generating a native image. Those files are included in
+ the native image generation process automatically (unless some tricky configuration is applied), so there is
+ no need to include those files manually and/or duplicate their contents in some custom configuration.
+ </para>
+ </section>
+ <section xml:id="native-image">
+ <title>HelloWorld native image generation</title>
+ <para>
+ The example for the GraalVM native image generation is hidden under examples/helloworld example.
+ To generate native image there it's required to perform some preliminary steps:
+ <simplelist>
+ <member>Download GraalVM at least 20.3.2 version</member>
+ <member>Set JAVA_HOME to point to that [GraalVM_HOME]</member>
+ <member>Perform <markup>$JAVA_HOME/bin/gu install native-image</markup> because native-image tool is not bundled within GraalVM itself</member>
+ <member>Download Jersey examples source codes (preferable some released version like 2.35),
+ and go to [path_to_jersey_examples]/examples/helloworld</member>
+ <member>Run <markup>mvn -Pnative-image clean package -DskipTests</markup></member>
+ </simplelist>
+ </para>
+ <para>
+ If all was correctly performed from previous steps the native image shall be already generated inside the targed folder
+ of the helloworld example with the name helloworld-native and it's possible to run it by
+ <programlisting language="bash">target/./helloworld-native</programlisting>
+ After it's run, console should print our following output:
+ <screen linenumbering="unnumbered">
+ "Hello World" Jersey Example App
+ May 27, 2021 1:37:49 PM org.glassfish.jersey.server.wadl.WadlFeature configure
+ WARNING: JAX-B API not found . WADL feature is disabled.
+ May 27, 2021 1:37:49 PM org.glassfish.grizzly.http.server.NetworkListener start
+ INFO: Started listener bound to [localhost:8080]
+ May 27, 2021 1:37:49 PM org.glassfish.grizzly.http.server.HttpServer start
+ INFO: [HttpServer] Started.
+ Application started.
+ Try out http://localhost:8080/base/helloworld
+ Stop the application using CTRL+C
+ </screen>
+ If you see this, you can open given link in browser and check how application actually works.
+ In general we are done here and you can use that example to generate native images for your own projects.
+ </para>
+ </section>
+ <section xml:id="undercover">
+ <title>What's under the cover</title>
+ <para>
+ For the example above the following command line was used:
+ <programlisting language="bash">
+ -H:EnableURLProtocols=http,https
+ --initialize-at-build-time=org.glassfish.jersey.client.internal.HttpUrlConnector
+ -H:+ReportExceptionStackTraces
+ --verbose
+ --no-fallback
+ --report-unsupported-elements-at-runtime
+ </programlisting>
+ This might be useful to generate another native image. It's possible to add another bunch of parameters to the command line
+ (and put those into the <literal>native-image.properties</literal> file inside of your project). Important parameter here is
+ --initialize-at-build-time (opposite to --initialize-at-run-time) and --no-fallback which says to the native
+ image to generate pure native image with everything bundled inside the image and not just fall back wrapper for JDK.
+ </para>
+ <para>
+ Another important aspect for generating the native image is the proper listing of reflection classes (classes that use reflection
+ in an application). For those needs, there is a native image agent which helps to generate those lists automatically.
+ In order to generate a list of reflection classes (and JNI classes and resources), it is required to run:
+ <programlisting language="bash">$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=[output_location] -jar [app_name].jar</programlisting>
+ And afterwords, the [output_location] directory will be created with generated lists (in JSON format). Those files can be
+ included as is into native image generation, but it's very preferable to edit them manually to reduce possible ambiguous classes listings.
+ </para>
+ </section>
+</chapter>
\ No newline at end of file
diff --git a/docs/src/main/docbook/user-guide.xml b/docs/src/main/docbook/user-guide.xml
index 84530ba..34da07a 100644
--- a/docs/src/main/docbook/user-guide.xml
+++ b/docs/src/main/docbook/user-guide.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
- Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2021 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
@@ -116,6 +116,7 @@
<xi:include href="custom-di.xml" />
<xi:include href="cdi.xml" />
<!-- <xi:include href="spring.xml" />--> <!--Spring is not supported in Jakarta -->
+ <xi:include href="graalvm-native-image.xml" />
<xi:include href="test-framework.xml" />
<xi:include href="how-to-build.xml" />
<xi:include href="migration.xml" />
diff --git a/etc/jenkins/jenkins_build.sh b/etc/jenkins/jenkins_build.sh
index afa8b15..e612cbb 100644
--- a/etc/jenkins/jenkins_build.sh
+++ b/etc/jenkins/jenkins_build.sh
@@ -2,4 +2,4 @@
export DEBUG=true
-mvn -V -U -B -e clean install glassfish-copyright:check -Dcopyright.quiet=false -Dsurefire.systemPropertiesFile=${WORKSPACE}/etc/jenkins/systemPropertiesFile
\ No newline at end of file
+mvn -V -U -B -e clean install glassfish-copyright:check -Dcopyright.quiet=false
\ No newline at end of file
diff --git a/ext/microprofile/mp-rest-client/pom.xml b/ext/microprofile/mp-rest-client/pom.xml
index e90137c..02c2939 100644
--- a/ext/microprofile/mp-rest-client/pom.xml
+++ b/ext/microprofile/mp-rest-client/pom.xml
@@ -98,6 +98,11 @@
<build>
<plugins>
<plugin>
+ <groupId>com.sun.istack</groupId>
+ <artifactId>istack-commons-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceModel.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceModel.java
index fdf8ecf..254df0e 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceModel.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/InterfaceModel.java
@@ -40,13 +40,9 @@
import org.eclipse.microprofile.rest.client.RestClientDefinitionException;
import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
-import org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptor;
-import org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptorFactory;
import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;
-import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
import org.glassfish.jersey.client.inject.ParameterUpdater;
import org.glassfish.jersey.client.inject.ParameterUpdaterProvider;
-import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.Providers;
import org.glassfish.jersey.model.Parameter;
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientExtension.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientExtension.java
index 35537ba..df16da6 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientExtension.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java
index bb30b7f..94c5fa4 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java
@@ -20,9 +20,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.ws.rs.client.WebTarget;
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
index f2b3b9e..8a5fe0d 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
@@ -55,7 +55,6 @@
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
-import org.eclipse.microprofile.rest.client.ext.QueryParamStyle;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.glassfish.jersey.internal.util.ReflectionHelper;
@@ -139,26 +138,11 @@
getConfigOption(Long.class, CONFIG_READ_TIMEOUT)
.ifPresent(aLong -> restClientBuilder.readTimeout(aLong, TimeUnit.MILLISECONDS));
getConfigOption(Boolean.class, CONFIG_FOLLOW_REDIRECTS)
- .ifPresent(restClientBuilder::followRedirects);
+ .ifPresent(follow -> VersionSupport.followRedirects(restClientBuilder, follow));
getConfigOption(String.class, CONFIG_QUERY_PARAM_STYLE)
- .ifPresent(value -> restClientBuilder.queryParamStyle(QueryParamStyle.valueOf(value)));
+ .ifPresent(value -> VersionSupport.queryParamStyle(restClientBuilder, value));
getConfigOption(String.class, CONFIG_PROXY_ADDRESS)
- .ifPresent(proxy -> {
- int index = proxy.lastIndexOf(':');
- //If : was not found at all or it is the last character of the proxy string
- if (index < 0 || proxy.length() - 1 == index) {
- throw new IllegalArgumentException("Invalid proxy URI: " + proxy);
- }
- String proxyHost = proxy.substring(0, index);
- int proxyPort;
- String proxyPortStr = proxy.substring(index + 1);
- try {
- proxyPort = Integer.parseInt(proxyPortStr);
- } catch (NumberFormatException nfe) {
- throw new IllegalArgumentException("Invalid proxy port: " + proxyPortStr, nfe);
- }
- restClientBuilder.proxyAddress(proxyHost, proxyPort);
- });
+ .ifPresent(proxy -> VersionSupport.proxyAddress(restClientBuilder, proxy));
// Providers from configuration
addConfiguredProviders(restClientBuilder);
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/VersionSupport.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/VersionSupport.java
new file mode 100644
index 0000000..c3d8da0
--- /dev/null
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/VersionSupport.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2021 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 org.eclipse.microprofile.rest.client.RestClientBuilder;
+import org.glassfish.jersey.microprofile.restclient.internal.LocalizationMessages;
+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 java.util.logging.Logger;
+
+/**
+ * Backward compatibility support not to throw an exception when an old API is used.
+ */
+abstract class VersionSupport {
+
+ protected abstract RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow);
+ protected abstract RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy);
+ protected abstract RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style);
+
+ private static final Logger logger = Logger.getLogger(VersionSupport.class.getName());
+
+ // determine the version only once per jvm
+ private static LazyValue<VersionSupport> currentVersion = Values.lazy((Value<VersionSupport>) () -> {
+ final Class<?> restClientBuilderClass = RestClientBuilder.class;
+ try {
+ if (null != restClientBuilderClass.getMethod("followRedirects", boolean.class)) {
+ return new Version20Support();
+ }
+ } catch (NoSuchMethodException e) {
+ // VERSION 1.4
+ }
+ return new Version14Support();
+ });
+
+ static RestClientBuilder followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
+ return currentVersion.get()._followRedirects(restClientBuilder, follow);
+ }
+
+ static RestClientBuilder proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
+ return currentVersion.get()._proxyAddress(restClientBuilder, proxy);
+ }
+
+ static RestClientBuilder queryParamStyle(RestClientBuilder restClientBuilder, String style) {
+ return currentVersion.get()._queryParamStyle(restClientBuilder, style);
+ }
+
+ private static class Version14Support extends VersionSupport {
+ protected RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
+ logger.warning(LocalizationMessages.WARN_VERSION_14_FOLLOWREDIRECT());
+ return restClientBuilder;
+ }
+
+ protected RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
+ logger.warning(LocalizationMessages.WARN_VERSION_14_PROXY());
+ return restClientBuilder;
+ }
+
+ protected RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style) {
+ logger.warning(LocalizationMessages.WARN_VERSION_14_QUERYPARAMSTYLE());
+ return restClientBuilder;
+ }
+ }
+
+ private static class Version20Support extends VersionSupport {
+ protected RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
+ return restClientBuilder.followRedirects(follow);
+ }
+
+ protected RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
+ int index = proxy.lastIndexOf(':');
+ //If : was not found at all or it is the last character of the proxy string
+ if (index < 0 || proxy.length() - 1 == index) {
+ throw new IllegalArgumentException(LocalizationMessages.ERR_INVALID_PROXY_URI(proxy));
+ }
+ String proxyHost = proxy.substring(0, index);
+ int proxyPort;
+ String proxyPortStr = proxy.substring(index + 1);
+ try {
+ proxyPort = Integer.parseInt(proxyPortStr);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException(LocalizationMessages.ERR_INVALID_PROXY_PORT(proxyPortStr), nfe);
+ }
+ return restClientBuilder.proxyAddress(proxyHost, proxyPort);
+ }
+
+ protected RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style) {
+ // do not import for compatibility with 1.4
+ org.eclipse.microprofile.rest.client.ext.QueryParamStyle queryParamStyle =
+ org.eclipse.microprofile.rest.client.ext.QueryParamStyle.valueOf(style);
+ return restClientBuilder.queryParamStyle(queryParamStyle);
+ }
+ }
+}
diff --git a/ext/microprofile/mp-rest-client/src/main/resources/org/glassfish/jersey/microprofile/restclient/internal/localization.properties b/ext/microprofile/mp-rest-client/src/main/resources/org/glassfish/jersey/microprofile/restclient/internal/localization.properties
new file mode 100644
index 0000000..71f05e0
--- /dev/null
+++ b/ext/microprofile/mp-rest-client/src/main/resources/org/glassfish/jersey/microprofile/restclient/internal/localization.properties
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2021 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
+#
+
+err.invalid.proxy.uri=Invalid proxy URI: {0}.
+err.invalid.proxy.port=Invalid proxy port: {0}.
+warn.version14.followredirect=MP Rest Client Version 1.4 does not support RestClientBuilder#followRedirect and it is ignored.
+warn.version14.proxy=MP Rest Client Version 1.4 does not support RestClientBuilder#proxy and it is ignored.
+warn.version14.queryparamstyle=MP Rest Client Version 1.4 does not support RestClientBuilder#queryParamStyle and it is ignored.
+
diff --git a/pom.xml b/pom.xml
index 29b8a77..04285e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -773,7 +773,7 @@
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
- <version>1.10.9</version>
+ <version>1.10.11</version>
</dependency>
</dependencies>
</plugin>
diff --git a/tests/integration/cdi-integration/cdi-singleton/pom.xml b/tests/integration/cdi-integration/cdi-singleton/pom.xml
index 83b16d7..6aef2a0 100644
--- a/tests/integration/cdi-integration/cdi-singleton/pom.xml
+++ b/tests/integration/cdi-integration/cdi-singleton/pom.xml
@@ -23,11 +23,11 @@
<parent>
<artifactId>cdi-integration-project</artifactId>
<groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
- <version>2.35-SNAPSHOT</version>
+ <version>3.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>cdi-sigleton</artifactId>
+ <artifactId>cdi-singleton</artifactId>
<dependencies>
<dependency>
@@ -41,7 +41,6 @@
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
- <version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java
index 2f95a80..46f5e28 100644
--- a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java
@@ -16,9 +16,9 @@
package org.glassfish.jersey.tests.cdi.singleton;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
@Path("/")
@Singleton
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java
index 59aa774..3578328 100644
--- a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java
@@ -16,7 +16,7 @@
package org.glassfish.jersey.tests.cdi.singleton;
-import javax.ws.rs.core.Application;
+import jakarta.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java
index 34a1f2c..68f7a63 100644
--- a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java
@@ -16,9 +16,9 @@
package org.glassfish.jersey.tests.cdi.singleton;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.core.Context;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.core.Context;
import java.io.IOException;
public class SingletonTestContainerRequestFilter implements ContainerRequestFilter {
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java
index 6e853d3..a76c64f 100644
--- a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java
@@ -16,10 +16,10 @@
package org.glassfish.jersey.tests.cdi.singleton;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerResponseContext;
-import javax.ws.rs.container.ContainerResponseFilter;
-import javax.ws.rs.core.Context;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.core.Context;
import java.io.IOException;
public class SingletonTestContainerResponseFilter implements ContainerResponseFilter {
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java b/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java
index eb5e9c6..5fe5070 100644
--- a/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java
+++ b/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java
@@ -25,8 +25,8 @@
import org.junit.Before;
import org.junit.Test;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
public class SingletonTest extends JerseyTest {
private Weld weld;
diff --git a/tests/integration/cdi-integration/pom.xml b/tests/integration/cdi-integration/pom.xml
index a16adb6..c4ed648 100644
--- a/tests/integration/cdi-integration/pom.xml
+++ b/tests/integration/cdi-integration/pom.xml
@@ -42,6 +42,7 @@
<module>cdi-multimodule</module>
<module>cdi-multipart-webapp</module>
<module>cdi-resource-with-at-context</module>
+ <module>cdi-singleton</module>
<module>cdi-test-webapp</module>
<module>cdi-with-jersey-injection-custom-cfg-webapp</module>
<module>cdi-with-jersey-injection-custom-hk2-banned-webapp</module>
diff --git a/tests/integration/microprofile/pom.xml b/tests/integration/microprofile/pom.xml
index 76be6eb..e41fdae 100644
--- a/tests/integration/microprofile/pom.xml
+++ b/tests/integration/microprofile/pom.xml
@@ -33,6 +33,7 @@
<modules>
<module>config</module>
<!-- <module>rest-client</module>-->
+<!-- <module>rest-client14-compatibility</module>-->
</modules>
<build>
diff --git a/tests/integration/microprofile/rest-client14-compatibility/pom.xml b/tests/integration/microprofile/rest-client14-compatibility/pom.xml
new file mode 100644
index 0000000..567c6f4
--- /dev/null
+++ b/tests/integration/microprofile/rest-client14-compatibility/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2021 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>microprofile-integration-project</artifactId>
+ <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>jersey-rest-client14-compatibility</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+ <artifactId>jersey-mp-rest-client</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>jakarta.enterprise</groupId>
+ <artifactId>jakarta.enterprise.cdi-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.microprofile.rest.client</groupId>
+ <artifactId>microprofile-rest-client-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- Overrides CDI from parent pom -->
+ <dependency>
+ <groupId>jakarta.enterprise</groupId>
+ <artifactId>jakarta.enterprise.cdi-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.microprofile.rest.client</groupId>
+ <artifactId>microprofile-rest-client-api</artifactId>
+ <!-- specifically this version we check with the backward compatibility -->
+ <version>1.4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-weld2-se</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.smallrye.config</groupId>
+ <artifactId>smallrye-config</artifactId>
+ <version>1.8.4</version> <!-- Workswith CQ 22471 -->
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <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.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-bundle</artifactId>
+ <type>pom</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-weld2-se</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tests/integration/microprofile/rest-client14-compatibility/src/test/java/org/glassfish/jersey/tests/restclient/compatibility/Compatibility14Test.java b/tests/integration/microprofile/rest-client14-compatibility/src/test/java/org/glassfish/jersey/tests/restclient/compatibility/Compatibility14Test.java
new file mode 100644
index 0000000..8507722
--- /dev/null
+++ b/tests/integration/microprofile/rest-client14-compatibility/src/test/java/org/glassfish/jersey/tests/restclient/compatibility/Compatibility14Test.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2021 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.restclient.compatibility;
+
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.jboss.weld.environment.se.Weld;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+public class Compatibility14Test extends JerseyTest {
+ private Weld weld;
+
+ @Before
+ public void setup() {
+ Assume.assumeTrue(Hk2InjectionManagerFactory.isImmediateStrategy());
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ if (Hk2InjectionManagerFactory.isImmediateStrategy()) {
+ weld = new Weld();
+ weld.initialize();
+ super.setUp();
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ if (Hk2InjectionManagerFactory.isImmediateStrategy()) {
+ weld.shutdown();
+ super.tearDown();
+ }
+ }
+
+ @RegisterRestClient
+ public static interface CompatibilityClient {
+ @GET
+ public String get();
+ }
+
+ @Path("/resource")
+ @RequestScoped
+ public static class CompatibilityResource {
+
+ @Inject
+ @RestClient
+ CompatibilityClient client;
+
+ @GET
+ public String get() {
+ return client.get();
+ }
+ }
+
+ @Path("/inner")
+ public static class InnerResource implements CompatibilityClient {
+
+ public String get() {
+ return "INNER";
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ set(TestProperties.RECORD_LOG_LEVEL, Level.WARNING.intValue());
+ return new ResourceConfig(InnerResource.class, CompatibilityResource.class)
+ .property(ServerProperties.WADL_FEATURE_DISABLE, true);
+ }
+
+ @Test
+ public void testCompatibility() {
+ final String loggerName = "org.glassfish.jersey.microprofile.restclient.VersionSupport";
+
+ try (Response r = target("/resource").request().get()) {
+ String entity = r.readEntity(String.class);
+ Assert.assertEquals(new InnerResource().get(), entity);
+ }
+
+ int warningCounts = 0;
+ for (final LogRecord logRecord : getLoggedRecords()) {
+ if (loggerName.equals(logRecord.getLoggerName()) && logRecord.getLevel() == Level.WARNING) {
+ warningCounts++;
+ }
+ }
+
+ Assert.assertEquals(3, warningCounts);
+ }
+}
diff --git a/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/beans.xml b/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..70897bd
--- /dev/null
+++ b/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2021 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
+
+-->
+
+<beans 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/beans_1_1.xsd"
+ bean-discovery-mode="annotated">
+</beans>
diff --git a/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/microprofile-config.properties b/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..616d545
--- /dev/null
+++ b/tests/integration/microprofile/rest-client14-compatibility/src/test/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2021 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
+
+org.glassfish.jersey.tests.restclient.compatibility.Compatibility14Test$CompatibilityClient/mp-rest/uri=http://localhost:9998/inner
+org.glassfish.jersey.tests.restclient.compatibility.Compatibility14Test$CompatibilityClient/mp-rest/followRedirects=true
+org.glassfish.jersey.tests.restclient.compatibility.Compatibility14Test$CompatibilityClient/mp-rest/queryParamStyle=COMMA_SEPARATED
+org.glassfish.jersey.tests.restclient.compatibility.Compatibility14Test$CompatibilityClient/mp-rest/proxyAddress=http://localhost:1010/nowehere
\ No newline at end of file