Next iteration towards supporting HK2 & Weld injection
Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyBootstrapPreinitialization.java b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyBootstrapPreinitialization.java
new file mode 100644
index 0000000..e521c8b
--- /dev/null
+++ b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyBootstrapPreinitialization.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024 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.grizzly2.httpserver;
+
+import org.glassfish.jersey.innate.BootstrapPreinitialization;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+
+import jakarta.ws.rs.RuntimeType;
+
+public final class GrizzlyBootstrapPreinitialization implements BootstrapPreinitialization {
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager injectionManager) {
+ injectionManager.register(new GrizzlyHttpContainer.GrizzlyBinder());
+ }
+}
diff --git a/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization b/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
new file mode 100644
index 0000000..a5be574
--- /dev/null
+++ b/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
@@ -0,0 +1 @@
+org.glassfish.jersey.grizzly2.httpserver.GrizzlyBootstrapPreinitialization
\ No newline at end of file
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientBinder.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientBinder.java
index a48e353..92a4e8c 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientBinder.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientBinder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -82,24 +82,26 @@
@Override
protected void configure() {
install(new MessagingBinders.MessageBodyProviders(clientRuntimeProperties, RuntimeType.CLIENT),
- new MessagingBinders.HeaderDelegateProviders());
+ new MessagingBinders.HeaderDelegateProviders(RuntimeType.CLIENT));
bindFactory(ReferencingFactory.referenceFactory()).to(new GenericType<Ref<ClientConfig>>() {
- }).in(RequestScoped.class);
+ }).in(RequestScoped.class).id(2101);
bindFactory(RequestContextInjectionFactory.class)
.to(ClientRequest.class)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(2102);
bindFactory(RequestContextInjectionFactory.class).to(HttpHeaders.class)
- .proxy(true).proxyForSameScope(false).in(RequestScoped.class);
+ .proxy(true).proxyForSameScope(false).in(RequestScoped.class).id(2103);
bindFactory(ReferencingFactory.referenceFactory()).to(new GenericType<Ref<ClientRequest>>() {
- }).in(RequestScoped.class);
+ }).in(RequestScoped.class).id(2104);
- bindFactory(PropertiesDelegateFactory.class, Singleton.class).to(PropertiesDelegate.class).in(RequestScoped.class);
+ bindFactory(PropertiesDelegateFactory.class, Singleton.class).to(PropertiesDelegate.class).in(RequestScoped.class)
+ .forClient(true).id(1001);
// ChunkedInput entity support
- bind(ChunkedInputReader.class).to(MessageBodyReader.class).in(Singleton.class);
+ bind(ChunkedInputReader.class).to(MessageBodyReader.class).in(Singleton.class).id(2105);
}
}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapPreinitialization.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapPreinitialization.java
new file mode 100644
index 0000000..c73cf7f
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapPreinitialization.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024 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.innate.BootstrapPreinitialization;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+
+import jakarta.ws.rs.RuntimeType;
+
+public class ClientBootstrapPreinitialization implements BootstrapPreinitialization {
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager injectionManager) {
+ if (runtimeType == RuntimeType.CLIENT) {
+ new ClientConfig.PreInitialization(injectionManager);
+ }
+ }
+}
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 b072c1d..6931a2d 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -88,7 +88,7 @@
@Override
public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
bootstrapBag.setConfiguration(runtimeConfig);
- injectionManager.register(Bindings.service(runtimeConfig).to(Configuration.class));
+ injectionManager.register(Bindings.service(runtimeConfig).to(Configuration.class).forClient(true).id(1000));
}
}
@@ -417,69 +417,27 @@
runtimeCfgState.markAsShared();
final InjectionManager injectionManager = findInjectionManager();
- injectionManager.register(new ClientBinder(runtimeCfgState.getProperties()));
-
- final ClientBootstrapBag bootstrapBag = new ClientBootstrapBag();
- bootstrapBag.setManagedObjectsFinalizer(new ManagedObjectsFinalizer(injectionManager));
-
- 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(),
- messageBodyWorkersConfigurator,
- new ExceptionMapperFactory.ExceptionMappersConfigurator(),
- new JaxrsProviders.ProvidersConfigurator(),
- new AutoDiscoverableConfigurator(RuntimeType.CLIENT),
- new ClientComponentConfigurator(),
- new FeatureConfigurator(RuntimeType.CLIENT));
- bootstrapConfigurators.forEach(configurator -> configurator.init(injectionManager, bootstrapBag));
-
- // AutoDiscoverable.
- if (!CommonProperties.getValue(runtimeCfgState.getProperties(), RuntimeType.CLIENT,
- CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, Boolean.FALSE, Boolean.class)) {
- runtimeCfgState.configureAutoDiscoverableProviders(injectionManager, bootstrapBag.getAutoDiscoverables());
- } else {
- runtimeCfgState.configureForcedAutoDiscoverableProviders(injectionManager);
- }
-
- // Configure binders and features.
- runtimeCfgState.configureMetaProviders(injectionManager, bootstrapBag.getManagedObjectsFinalizer());
-
- // Bind providers.
- final Collection<ComponentProvider> componentProviders = bootstrapBag.getComponentProviders().get();
- ProviderBinder.bindProviders(
- runtimeCfgState.getComponentBag(), RuntimeType.CLIENT, null, injectionManager, componentProviders
- );
-
- ClientExecutorProvidersConfigurator executorProvidersConfigurator =
- new ClientExecutorProvidersConfigurator(runtimeCfgState.getComponentBag(),
- runtimeCfgState.client,
- this.executorService,
- this.scheduledExecutorService);
- executorProvidersConfigurator.init(injectionManager, bootstrapBag);
+ final PreInitialization preInit =
+ new PreInitialization(runtimeCfgState, injectionManager, this.executorService, this.scheduledExecutorService);
+ List<BootstrapConfigurator> bootstrapConfigurators = preInit.bootstrapConfigurators;
injectionManager.completeRegistration();
- bootstrapConfigurators.forEach(configurator -> configurator.postInit(injectionManager, bootstrapBag));
+ bootstrapConfigurators.forEach(configurator -> configurator.postInit(injectionManager, preInit.bootstrapBag));
final ClientConfig configuration = new ClientConfig(runtimeCfgState);
final Connector connector = connectorProvider.getConnector(client, configuration);
- final ClientRuntime crt = new ClientRuntime(configuration, connector, injectionManager, bootstrapBag);
+ final ClientRuntime crt = new ClientRuntime(configuration, connector, injectionManager, preInit.bootstrapBag);
client.registerShutdownHook(crt);
- messageBodyWorkersConfigurator.setClientRuntime(crt);
+ preInit.messageBodyWorkersConfigurator.setClientRuntime(crt);
return crt;
}
- private final InjectionManager findInjectionManager() {
+ private InjectionManager findInjectionManager() {
try {
- return Injections.createInjectionManager(RuntimeType.CLIENT);
+ return Injections.createInjectionManager(commonConfig);
} catch (IllegalStateException ise) {
return new NonInjectionManager(true);
}
@@ -515,6 +473,68 @@
}
}
+ /* package */ static class PreInitialization {
+ private final ClientBootstrapBag bootstrapBag;
+ private final List<BootstrapConfigurator> bootstrapConfigurators;
+ private final ClientMessageBodyFactory.MessageBodyWorkersConfigurator messageBodyWorkersConfigurator;
+
+ /* package */ PreInitialization(InjectionManager injectionManager) {
+ this(new State(new JerseyClient()), injectionManager, null, null);
+ }
+
+
+ /* package */ PreInitialization(
+ State runtimeCfgState,
+ InjectionManager injectionManager,
+ ExecutorService executorService,
+ ScheduledExecutorService scheduledExecutorService) {
+ injectionManager.register(new ClientBinder(runtimeCfgState.getProperties()));
+
+ bootstrapBag = new ClientBootstrapBag();
+ bootstrapBag.setManagedObjectsFinalizer(new ManagedObjectsFinalizer(injectionManager));
+
+ messageBodyWorkersConfigurator = new ClientMessageBodyFactory.MessageBodyWorkersConfigurator(); // 2020
+
+ bootstrapConfigurators = Arrays.asList(
+ new RequestScope.RequestScopeConfigurator(),
+ new ParamConverterConfigurator(), // 2010
+ new ParameterUpdaterConfigurator(), // 2011
+ new RuntimeConfigConfigurator(runtimeCfgState), // 2012
+ new ContextResolverFactory.ContextResolversConfigurator(), // 2014
+ messageBodyWorkersConfigurator,
+ new ExceptionMapperFactory.ExceptionMappersConfigurator(), // 2015
+ new JaxrsProviders.ProvidersConfigurator(), // 2016
+ new AutoDiscoverableConfigurator(RuntimeType.CLIENT),
+ new ClientComponentConfigurator(),
+ new FeatureConfigurator(RuntimeType.CLIENT));
+ bootstrapConfigurators.forEach(configurator -> configurator.init(injectionManager, bootstrapBag));
+
+ // AutoDiscoverable.
+ if (!CommonProperties.getValue(runtimeCfgState.getProperties(), RuntimeType.CLIENT,
+ CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, Boolean.FALSE, Boolean.class)) {
+ runtimeCfgState.configureAutoDiscoverableProviders(injectionManager, bootstrapBag.getAutoDiscoverables());
+ } else {
+ runtimeCfgState.configureForcedAutoDiscoverableProviders(injectionManager);
+ }
+
+ // Configure binders and features.
+ runtimeCfgState.configureMetaProviders(injectionManager, bootstrapBag.getManagedObjectsFinalizer());
+
+ // Bind providers.
+ final Collection<ComponentProvider> componentProviders = bootstrapBag.getComponentProviders().get();
+ ProviderBinder.bindProviders(
+ runtimeCfgState.getComponentBag(), RuntimeType.CLIENT, null, injectionManager, componentProviders
+ );
+
+ ClientExecutorProvidersConfigurator executorProvidersConfigurator =
+ new ClientExecutorProvidersConfigurator(runtimeCfgState.getComponentBag(),
+ runtimeCfgState.client,
+ executorService,
+ scheduledExecutorService);
+ executorProvidersConfigurator.init(injectionManager, bootstrapBag);
+ }
+ }
+
/**
* Construct a new Jersey configuration instance with the default features
* and property values.
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientExecutorProvidersConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientExecutorProvidersConfigurator.java
index df26b22..b575a5c 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientExecutorProvidersConfigurator.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientExecutorProvidersConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -37,6 +37,8 @@
import org.glassfish.jersey.spi.ExecutorServiceProvider;
import org.glassfish.jersey.spi.ScheduledExecutorServiceProvider;
+import jakarta.ws.rs.RuntimeType;
+
/**
* Configurator which initializes and register {@link ExecutorServiceProvider} and
* {@link ScheduledExecutorServiceProvider}.
@@ -106,7 +108,9 @@
InstanceBinding<ExecutorServiceProvider> executorBinding = Bindings
.service(defaultAsyncExecutorProvider)
- .to(ExecutorServiceProvider.class);
+ .to(ExecutorServiceProvider.class)
+ .forClient(true)
+ .id(2020);
injectionManager.register(executorBinding);
@@ -130,11 +134,13 @@
InstanceBinding<ScheduledExecutorServiceProvider> schedulerBinding = Bindings
.service(defaultScheduledExecutorProvider)
- .to(ScheduledExecutorServiceProvider.class);
+ .to(ScheduledExecutorServiceProvider.class)
+ .forClient(true)
+ .id(2021);
injectionManager.register(schedulerBinding);
registerExecutors(injectionManager, componentBag, defaultAsyncExecutorProvider,
- defaultScheduledExecutorProvider, bootstrapBag.getManagedObjectsFinalizer());
+ defaultScheduledExecutorProvider, bootstrapBag.getManagedObjectsFinalizer(), RuntimeType.CLIENT);
}
private static ExecutorService lookupManagedExecutorService() {
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
index bbd0abc..f16cd34 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientMessageBodyFactory.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientMessageBodyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024 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,8 +65,7 @@
public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
messageBodyFactory = new ClientMessageBodyFactory(bootstrapBag.getConfiguration(), () -> clientRuntime);
InstanceBinding<ClientMessageBodyFactory> binding =
- Bindings.service(messageBodyFactory)
- .to(MessageBodyWorkers.class);
+ Bindings.service(messageBodyFactory).to(MessageBodyWorkers.class).id(2020);
injectionManager.register(binding);
}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterUpdaterConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterUpdaterConfigurator.java
index f8627f8..4d58a8a 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterUpdaterConfigurator.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterUpdaterConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -53,6 +53,6 @@
ParameterUpdaterFactory parameterUpdaterFactory = new ParameterUpdaterFactory(lazyParamConverterFactory);
clientBag.setParameterUpdaterProvider(parameterUpdaterFactory);
injectionManager.register(Bindings.service(parameterUpdaterFactory)
- .to(ParameterUpdaterProvider.class));
+ .to(ParameterUpdaterProvider.class).id(2011));
}
}
diff --git a/core-client/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization b/core-client/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
new file mode 100644
index 0000000..c8f92f0
--- /dev/null
+++ b/core-client/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
@@ -0,0 +1 @@
+org.glassfish.jersey.client.ClientBootstrapPreinitialization
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/innate/BootstrapPreinitialization.java b/core-common/src/main/java/org/glassfish/jersey/innate/BootstrapPreinitialization.java
new file mode 100644
index 0000000..29f7fe9
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/BootstrapPreinitialization.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024 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.innate;
+
+import org.glassfish.jersey.Beta;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.FeatureContext;
+
+/**
+ * <p>
+ * The entry point for pre-initialize Jersey during bootstrap. Register the beans that are not recognized by the injection
+ * framework to be injected in runtime. Register beans for the specific runtime type into the {@link InjectionManager}.
+ * </p>
+ */
+@Beta
+public interface BootstrapPreinitialization {
+ /**
+ * Manually register beans that are not automatically recognised by the injection framework.
+ * @param runtimeType
+ * @param injectionManager
+ */
+ void preregister(RuntimeType runtimeType, InjectionManager injectionManager);
+
+ static FeatureContext featureContextInstance() {
+ return new PreinitializationFeatureContext();
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/innate/PreinitializationFeatureContext.java b/core-common/src/main/java/org/glassfish/jersey/innate/PreinitializationFeatureContext.java
new file mode 100644
index 0000000..6882630
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/PreinitializationFeatureContext.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2024 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.innate;
+
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.Binding;
+import org.glassfish.jersey.internal.inject.ClassBinding;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.model.internal.CommonConfig;
+import org.glassfish.jersey.model.internal.ComponentBag;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.FeatureContext;
+import java.util.Map;
+
+/**
+ * Feature Context to be used during the Bootstrap Preinitialization phase
+ */
+class PreinitializationFeatureContext implements FeatureContext {
+
+ private final AbstractBinder binder;
+
+ PreinitializationFeatureContext() {
+ this.binder = new AbstractBinder() {
+ @Override
+ protected void configure() {
+
+ }
+ };
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ return new CommonConfig(RuntimeType.SERVER, ComponentBag.INCLUDE_ALL);
+ }
+
+ @Override
+ public FeatureContext property(String name, Object value) {
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Class<?> componentClass) {
+ binder.bindAsContract(componentClass);
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Class<?> componentClass, int priority) {
+ binder.bindAsContract(componentClass).ranked(priority);
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Class<?> componentClass, Class<?>... contracts) {
+ final ClassBinding binding = binder.bind(componentClass);
+ if (contracts != null) {
+ for (Class<?> contract : contracts) {
+ binding.to(contract);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Class<?> componentClass, Map<Class<?>, Integer> contracts) {
+ for (Map.Entry<Class<?>, Integer> contract : contracts.entrySet()) {
+ final AbstractBinder abstractBinder = new AbstractBinder() {
+ @Override
+ protected void configure() {
+ }
+ };
+ final ClassBinding binding = abstractBinder.bind(componentClass);
+ binding.to(contract.getKey()).ranked(contract.getValue());
+ binder.install(abstractBinder);
+ }
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Object component) {
+ if (InjectionManager.class.isInstance(component)) {
+ ((InjectionManager) component).register(binder);
+ } else if (AbstractBinder.class.isInstance(component)) {
+ binder.install((AbstractBinder) component);
+ } else {
+ binder.bind(component).to(component.getClass());
+ }
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Object component, int priority) {
+ binder.bind(component).to(component.getClass()).ranked(priority);
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Object component, Class<?>... contracts) {
+ Binding binding = binder.bind(component);
+ if (contracts != null) {
+ for (Class<?> contract : contracts) {
+ binding.to(contract);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public FeatureContext register(Object component, Map<Class<?>, Integer> contracts) {
+ for (Map.Entry<Class<?>, Integer> contract : contracts.entrySet()) {
+ final AbstractBinder abstractBinder = new AbstractBinder() {
+ @Override
+ protected void configure() {
+ }
+ };
+ final Binding binding = abstractBinder.bind(component);
+ binding.to(contract.getKey()).ranked(contract.getValue());
+ binder.install(abstractBinder);
+ }
+ return this;
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
index b0648e7..7d5ae69 100644
--- a/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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/core-common/src/main/java/org/glassfish/jersey/internal/ContextResolverFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/ContextResolverFactory.java
index 9c5bb7a..f5631a7 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/ContextResolverFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/ContextResolverFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -24,6 +24,7 @@
import java.util.concurrent.ConcurrentHashMap;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.ContextResolver;
@@ -60,7 +61,9 @@
contextResolverFactory = new ContextResolverFactory();
InstanceBinding<ContextResolverFactory> binding =
Bindings.service(contextResolverFactory)
- .to(ContextResolvers.class);
+ .to(ContextResolvers.class)
+ .forClient(bootstrapBag.getConfiguration().getRuntimeType() == RuntimeType.CLIENT)
+ .id(1014);
injectionManager.register(binding);
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
index 55e5a68..cf0171a 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -30,9 +30,9 @@
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.ext.ExceptionMapper;
-import org.glassfish.jersey.JerseyPriorities;
import org.glassfish.jersey.internal.inject.Bindings;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InstanceBinding;
@@ -75,7 +75,9 @@
exceptionMapperFactory = new ExceptionMapperFactory(injectionManager);
InstanceBinding<ExceptionMapperFactory> binding =
Bindings.service(exceptionMapperFactory)
- .to(ExceptionMappers.class);
+ .to(ExceptionMappers.class)
+ .forClient(bootstrapBag.getConfiguration().getRuntimeType() == RuntimeType.CLIENT)
+ .id(1015);
injectionManager.register(binding);
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/JaxrsProviders.java b/core-common/src/main/java/org/glassfish/jersey/internal/JaxrsProviders.java
index fa075fb..596860b 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/JaxrsProviders.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/JaxrsProviders.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,6 +19,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.ContextResolver;
@@ -59,7 +60,8 @@
injectionManager.register(
Bindings.service(JaxrsProviders.class)
.to(Providers.class)
- .in(PerLookup.class));
+ .in(PerLookup.class)
+ .id(injectionManager.getRuntimeType() == RuntimeType.CLIENT ? 2016 : 3016));
}
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
index db16be8..ce3aa43 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024 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
@@ -16,14 +16,13 @@
package org.glassfish.jersey.internal;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.EntityPart;
import jakarta.ws.rs.ext.RuntimeDelegate;
import org.glassfish.jersey.message.internal.MessagingBinders;
-import java.util.Optional;
import java.util.concurrent.CompletionStage;
/**
@@ -40,7 +39,7 @@
public class RuntimeDelegateImpl extends AbstractRuntimeDelegate {
public RuntimeDelegateImpl() {
- super(new MessagingBinders.HeaderDelegateProviders().getHeaderDelegateProviders());
+ super(new MessagingBinders.HeaderDelegateProviders(RuntimeType.CLIENT).getHeaderDelegateProviders());
}
@Override
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/Binding.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/Binding.java
index 69a534a..f793792 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/Binding.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/Binding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -16,10 +16,14 @@
package org.glassfish.jersey.internal.inject;
+import org.glassfish.jersey.Beta;
+
import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
import jakarta.ws.rs.core.GenericType;
@@ -46,6 +50,8 @@
private Boolean proxiable = null;
private Boolean proxyForSameScope = null;
private Integer ranked = null;
+ private boolean forClient = false;
+ private long id = 0;
/**
* Gets information whether the service is proxiable.
@@ -138,6 +144,15 @@
}
/**
+ * Get the hint of the bean that exists both on the client and the server
+ * @return the hint that this binding if for being injected on the client.
+ */
+ @Beta
+ public boolean isForClient() {
+ return forClient;
+ }
+
+ /**
* Adds service's analyzer.
*
* @return current instance.
@@ -260,8 +275,9 @@
*
* @return current instance.
*/
- public void ranked(int rank) {
+ public D ranked(int rank) {
this.ranked = rank;
+ return (D) this;
}
/**
@@ -273,4 +289,58 @@
this.implementationType = type;
return (D) this;
}
+
+ /**
+ * A hint whether the bean is for being injected using {@code @Inject} on the client side
+ * but there is also a bean with the same contract on the server, such as for {@code Configuration}.
+ *
+ * <p>Default is false.</p>
+ *
+ * @param forClient {@code true} when injectable for the same contract exists both on the client and server and
+ * this binding is for the client side.
+ * @return current instance.
+ */
+ @Beta
+ public D forClient(boolean forClient) {
+ this.forClient = forClient;
+ return (D) this;
+ }
+
+ /**
+ * The binding id used to match the binding in the pre-binding phase and in the binding phase.
+ * @param id the unique id.
+ * @return current instance.
+ */
+ @Beta
+ public D id(long id) {
+ // 1000 - 1999 Core-Common
+ // 2000 - 2999 Core-Client
+ // 3000 - 3999 Core-Server
+ this.id = id;
+ return (D) this;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return contractsAsString() + " <- " + implementationType.getSimpleName();
+ }
+
+ protected String contractsAsString() {
+ StringBuilder sb = new StringBuilder();
+ Iterator<Type> it = contracts.iterator();
+ while (it.hasNext()) {
+ Type next = it.next();
+ if (Class.class.isInstance(next)) {
+ sb.append(((Class) next).getSimpleName());
+ } else if (ParameterizedType.class.isInstance(next)) {
+ sb.append(next);
+ }
+ }
+ return sb.toString();
+ }
+
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManager.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManager.java
index 4d5fd1c..3961d55 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManager.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -16,6 +16,9 @@
package org.glassfish.jersey.internal.inject;
+import org.glassfish.jersey.Beta;
+
+import jakarta.ws.rs.RuntimeType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
@@ -257,4 +260,13 @@
* @param preDestroyMe The object to preDestroy
*/
void preDestroy(Object preDestroyMe);
+
+ /**
+ * Get RuntimeType of the InjectionManager.
+ * @return the runtimeType
+ */
+ @Beta
+ default RuntimeType getRuntimeType() {
+ return null;
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManagerFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManagerFactory.java
index 2a74b37..41e3dca 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManagerFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -16,6 +16,8 @@
package org.glassfish.jersey.internal.inject;
+import jakarta.ws.rs.core.Configuration;
+
/**
* Factory which is able to create {@link InjectionManager}. Every DI provider must create its own {@link InjectionManagerFactory}
* and register it in META-INF.services. Then the {@code InjectionManagerFactory} can be looked up and {@code InjectionManager}
@@ -39,4 +41,13 @@
* @return initialized injection manager.
*/
InjectionManager create(Object parent);
+
+ /**
+ * Load a new injection manager with parent object for a given RuntimeType.
+ *
+ * @param configuration the configuration including RuntimeType of the InjectionManager used.
+ * @param parent injection manager parent or concrete DI specific object which is compatible with DI provider.
+ * @return initialized injection manager.
+ */
+ InjectionManager create(Object parent, Configuration configuration);
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionResolverBinding.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionResolverBinding.java
index 44f8dee..590cb54 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionResolverBinding.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InjectionResolverBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -42,4 +42,10 @@
public T getResolver() {
return resolver;
}
+
+ @Override
+ public String toString() {
+ return resolver.getClass().getSimpleName() + " <- " + resolver.getClass().getSimpleName();
+
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/Injections.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/Injections.java
index 1750dd8..ac5f012 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/Injections.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/Injections.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -16,13 +16,20 @@
package org.glassfish.jersey.internal.inject;
+import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import jakarta.ws.rs.ConstrainedTo;
import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+
import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.ServiceFinder;
@@ -43,7 +50,7 @@
* @return an injection manager with all the bindings.
*/
public static InjectionManager createInjectionManager() {
- return lookupInjectionManagerFactory(RuntimeType.SERVER).create();
+ return createInjectionManager(new EmptyConfiguration(RuntimeType.SERVER));
}
/**
@@ -53,7 +60,17 @@
* @return an injection manager with all the bindings.
*/
public static InjectionManager createInjectionManager(RuntimeType type) {
- return lookupInjectionManagerFactory(type).create();
+ return createInjectionManager(new EmptyConfiguration(type));
+ }
+
+ /**
+ * Creates an {@link InjectionManager} without parent and initial binder.
+ * @param configuration {@link Configuration} including {@link RuntimeType} the {@link InjectionManagerFactory}
+ * must be {@link ConstrainedTo} if annotated.
+ * @return an injection manager with all the bindings.
+ */
+ public static InjectionManager createInjectionManager(Configuration configuration) {
+ return lookupInjectionManagerFactory(configuration.getRuntimeType()).create(null, configuration);
}
/**
@@ -63,8 +80,7 @@
* @return an injection manager with all the bindings.
*/
public static InjectionManager createInjectionManager(Binder binder) {
- InjectionManagerFactory injectionManagerFactory = lookupInjectionManagerFactory(RuntimeType.SERVER);
- InjectionManager injectionManager = injectionManagerFactory.create();
+ InjectionManager injectionManager = createInjectionManager(RuntimeType.SERVER);
injectionManager.register(binder);
return injectionManager;
}
@@ -78,7 +94,21 @@
* @return an injection manager with all the bindings.
*/
public static InjectionManager createInjectionManager(Object parent) {
- return lookupInjectionManagerFactory(RuntimeType.SERVER).create(parent);
+ return createInjectionManager(parent, new EmptyConfiguration(RuntimeType.SERVER));
+ }
+
+ /**
+ * Creates an unnamed, parented {@link InjectionManager}. In case the {@code parent} injection manager is not specified, the
+ * locator will not be parented.
+ *
+ * @param parent The parent of this injection manager. Services can be found in the parent (and all grand-parents). May be
+ * {@code null}. An underlying DI provider checks whether the parent is in a proper type.
+ * @param configuration {@link Configuration} including {@link RuntimeType} the {@link InjectionManagerFactory}
+ * must be {@link ConstrainedTo} if annotated.
+ * @return an injection manager with all the bindings.
+ */
+ public static InjectionManager createInjectionManager(Object parent, Configuration configuration) {
+ return lookupInjectionManagerFactory(configuration.getRuntimeType()).create(parent, configuration);
}
private static InjectionManagerFactory lookupInjectionManagerFactory(RuntimeType type) {
@@ -136,4 +166,68 @@
throw e;
}
}
+
+ private static final class EmptyConfiguration implements Configuration {
+
+ private final RuntimeType runtimeType;
+
+ private EmptyConfiguration(RuntimeType runtimeType) {
+ this.runtimeType = runtimeType;
+ }
+
+ @Override
+ public RuntimeType getRuntimeType() {
+ return runtimeType;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return getProperties().get(name);
+ }
+
+ @Override
+ public Collection<String> getPropertyNames() {
+ return getProperties().keySet();
+ }
+
+ @Override
+ public boolean isEnabled(Feature feature) {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(Class<? extends Feature> featureClass) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Object component) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Class<?> componentClass) {
+ return false;
+ }
+
+ @Override
+ public Map<Class<?>, Integer> getContracts(Class<?> componentClass) {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<Object> getInstances() {
+ return Collections.emptySet();
+ }
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InstanceBinding.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InstanceBinding.java
index af51072..6f9f786 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InstanceBinding.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InstanceBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -59,4 +59,10 @@
public T getService() {
return service;
}
+
+
+ @Override
+ public String toString() {
+ return contractsAsString() + " <- " + service.getClass().getSimpleName();
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
index f10976a..6fa7127 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -17,6 +17,7 @@
package org.glassfish.jersey.internal.inject;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.ext.ParamConverterProvider;
import org.glassfish.jersey.internal.BootstrapBag;
@@ -31,9 +32,10 @@
@Override
public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+ long id = injectionManager.getRuntimeType() == RuntimeType.CLIENT ? 2010 : 3010;
final ClassBinding<ParamConverters.AggregatedProvider> aggregatedConverters =
Bindings.service(ParamConverters.AggregatedProvider.class)
- .to(ParamConverterProvider.class);
+ .to(ParamConverterProvider.class).id(id);
injectionManager.register(aggregatedConverters);
}
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierClassBinding.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierClassBinding.java
index f07b4ff..fd6f86e 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierClassBinding.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierClassBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -58,4 +58,9 @@
public Class<? extends Annotation> getSupplierScope() {
return supplierScope;
}
+
+ @Override
+ public String toString() {
+ return contractsAsString() + " <- " + supplierClass.getSimpleName();
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierInstanceBinding.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierInstanceBinding.java
index e3f6643..1d826b5 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierInstanceBinding.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/SupplierInstanceBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -45,4 +45,9 @@
public Supplier<T> getSupplier() {
return supplier;
}
+
+ @Override
+ public String toString() {
+ return contractsAsString() + " <- " + supplier.get().getClass().getSimpleName();
+ }
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/MessageBodyFactory.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/MessageBodyFactory.java
index ab95eaf..43abe49 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/MessageBodyFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/MessageBodyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2024 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
@@ -105,7 +105,8 @@
messageBodyFactory = new MessageBodyFactory(bootstrapBag.getConfiguration());
InstanceBinding<MessageBodyFactory> binding =
Bindings.service(messageBodyFactory)
- .to(MessageBodyWorkers.class);
+ .to(MessageBodyWorkers.class)
+ .id(3182);
injectionManager.register(binding);
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/MessagingBinders.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/MessagingBinders.java
index fa1117a..85c56b0 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/MessagingBinders.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/MessagingBinders.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -20,10 +20,12 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import jakarta.ws.rs.RuntimeType;
@@ -89,17 +91,17 @@
protected void configure() {
// Message body providers (both readers & writers)
- bindSingletonWorker(ByteArrayProvider.class);
+ bindSingletonWorker(ByteArrayProvider.class, runtimeType == RuntimeType.CLIENT ? 2030 : 3030);
// bindSingletonWorker(DataSourceProvider.class);
- bindSingletonWorker(FileProvider.class);
- bindSingletonWorker(FormMultivaluedMapProvider.class);
- bindSingletonWorker(FormProvider.class);
- bindSingletonWorker(InputStreamProvider.class);
- bindSingletonWorker(BasicTypesMessageProvider.class);
- bindSingletonWorker(ReaderProvider.class);
+ bindSingletonWorker(FileProvider.class, runtimeType == RuntimeType.CLIENT ? 2031 : 3031);
+ bindSingletonWorker(FormMultivaluedMapProvider.class, runtimeType == RuntimeType.CLIENT ? 2032 : 3032);
+ bindSingletonWorker(FormProvider.class, runtimeType == RuntimeType.CLIENT ? 2033 : 3033);
+ bindSingletonWorker(InputStreamProvider.class, runtimeType == RuntimeType.CLIENT ? 2034 : 3034);
+ bindSingletonWorker(BasicTypesMessageProvider.class, runtimeType == RuntimeType.CLIENT ? 2035 : 3035);
+ bindSingletonWorker(ReaderProvider.class, runtimeType == RuntimeType.CLIENT ? 2036 : 3036);
// bindSingletonWorker(RenderedImageProvider.class); - enabledProvidersBinder
- bindSingletonWorker(StringMessageProvider.class);
- bindSingletonWorker(EnumMessageProvider.class);
+ bindSingletonWorker(StringMessageProvider.class, runtimeType == RuntimeType.CLIENT ? 2037 : 3037);
+ bindSingletonWorker(EnumMessageProvider.class, runtimeType == RuntimeType.CLIENT ? 2038 : 3038);
// Message body readers -- enabledProvidersBinder
// bind(SourceProvider.StreamSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
@@ -110,7 +112,8 @@
*/
// Message body writers
- bind(StreamingOutputProvider.class).to(MessageBodyWriter.class).in(Singleton.class);
+ bind(StreamingOutputProvider.class).to(MessageBodyWriter.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2039 : 3039);
// bind(SourceProvider.SourceWriter.class).to(MessageBodyWriter.class).in(Singleton.class); - enabledProvidersBinder
final EnabledProvidersBinder enabledProvidersBinder = new EnabledProvidersBinder();
@@ -119,14 +122,14 @@
String.valueOf(applicationProperties.get(CommonProperties.PROVIDER_DEFAULT_DISABLE))
);
}
- enabledProvidersBinder.bindToBinder(this);
+ enabledProvidersBinder.bindToBinder(this, runtimeType);
// Header Delegate Providers registered in META-INF.services
install(new ServiceFinderBinder<>(HeaderDelegateProvider.class, applicationProperties, runtimeType));
}
- private <T extends MessageBodyReader & MessageBodyWriter> void bindSingletonWorker(final Class<T> worker) {
- bind(worker).to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class);
+ private <T extends MessageBodyReader & MessageBodyWriter> void bindSingletonWorker(final Class<T> worker, long id) {
+ bind(worker).to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class).id(id);
}
}
@@ -136,9 +139,11 @@
public static class HeaderDelegateProviders extends AbstractBinder {
private final Set<HeaderDelegateProvider> providers;
+ private final RuntimeType runtimeType;
- public HeaderDelegateProviders() {
- Set<HeaderDelegateProvider> providers = new HashSet<>();
+ public HeaderDelegateProviders(RuntimeType runtimeType) {
+ this.runtimeType = runtimeType;
+ Set<HeaderDelegateProvider> providers = new LinkedHashSet<>();
providers.add(new CacheControlProvider());
providers.add(new CookieProvider());
providers.add(new DateProvider());
@@ -154,7 +159,9 @@
@Override
protected void configure() {
- providers.forEach(provider -> bind(provider).to(HeaderDelegateProvider.class));
+ AtomicLong id = new AtomicLong(40);
+ providers.forEach(provider -> bind(provider).to(HeaderDelegateProvider.class)
+ .id((runtimeType == RuntimeType.CLIENT ? 2000 : 3000) + id.getAndIncrement()));
}
/**
@@ -207,7 +214,7 @@
}
}
- private void bindToBinder(AbstractBinder binder) {
+ private void bindToBinder(AbstractBinder binder, RuntimeType runtimeType) {
ProviderBinder providerBinder = null;
for (Provider provider : enabledProviders) {
if (isClass(provider.className)) {
@@ -231,7 +238,7 @@
providerBinder = new StreamSourceBinder();
break;
}
- providerBinder.bind(binder, provider);
+ providerBinder.bind(binder, provider, runtimeType);
} else {
if (warningMap.get(provider).compareAndSet(false, true)) {
switch (provider) {
@@ -260,50 +267,56 @@
}
private interface ProviderBinder {
- void bind(AbstractBinder binder, Provider provider);
+ void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType);
}
private static class DataSourceBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
binder.bind(DataSourceProvider.class)
- .to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class);
+ .to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2070 : 3070);
}
}
private static class DomSourceBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
- binder.bind(SourceProvider.DomSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
+ binder.bind(SourceProvider.DomSourceReader.class).to(MessageBodyReader.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2071 : 3071);
}
}
private static class RenderedImageBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
binder.bind(RenderedImageProvider.class)
- .to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class);
+ .to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2072 : 3072);
}
}
private static class SaxSourceBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
- binder.bind(SourceProvider.SaxSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
+ binder.bind(SourceProvider.SaxSourceReader.class).to(MessageBodyReader.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2073 : 3073);
}
}
private static class SourceBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
- binder.bind(SourceProvider.SourceWriter.class).to(MessageBodyWriter.class).in(Singleton.class);
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
+ binder.bind(SourceProvider.SourceWriter.class).to(MessageBodyWriter.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2074 : 3074);
}
}
private static class StreamSourceBinder implements ProviderBinder {
@Override
- public void bind(AbstractBinder binder, Provider provider) {
- binder.bind(SourceProvider.StreamSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
+ public void bind(AbstractBinder binder, Provider provider, RuntimeType runtimeType) {
+ binder.bind(SourceProvider.StreamSourceReader.class).to(MessageBodyReader.class).in(Singleton.class)
+ .id(runtimeType == RuntimeType.CLIENT ? 2075 : 3075);
}
}
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/process/internal/AbstractExecutorProvidersConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/process/internal/AbstractExecutorProvidersConfigurator.java
index 2a9c8b4..7ee23d8 100644
--- a/core-common/src/main/java/org/glassfish/jersey/process/internal/AbstractExecutorProvidersConfigurator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/process/internal/AbstractExecutorProvidersConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -28,6 +28,8 @@
import org.glassfish.jersey.spi.ExecutorServiceProvider;
import org.glassfish.jersey.spi.ScheduledExecutorServiceProvider;
+import jakarta.ws.rs.RuntimeType;
+
/**
* Abstract Configurator which initializes and register {@link ExecutorServiceProvider} and
* {@link ScheduledExecutorServiceProvider}.
@@ -57,7 +59,8 @@
ComponentBag componentBag,
ExecutorServiceProvider defaultAsyncExecutorProvider,
ScheduledExecutorServiceProvider defaultScheduledExecutorProvider,
- ManagedObjectsFinalizer finalizer) {
+ ManagedObjectsFinalizer finalizer,
+ RuntimeType runtimeType) {
List<ExecutorServiceProvider> customExecutors =
Stream.concat(
@@ -79,6 +82,6 @@
customScheduledExecutors.add(defaultScheduledExecutorProvider);
customScheduledExecutors.stream().forEach(e -> finalizer.registerForPreDestroyCall(e));
- ExecutorProviders.registerExecutorBindings(injectionManager, customExecutors, customScheduledExecutors);
+ ExecutorProviders.registerExecutorBindings(injectionManager, customExecutors, customScheduledExecutors, runtimeType);
}
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/process/internal/ExecutorProviders.java b/core-common/src/main/java/org/glassfish/jersey/process/internal/ExecutorProviders.java
index 2a71beb..f7da69e 100644
--- a/core-common/src/main/java/org/glassfish/jersey/process/internal/ExecutorProviders.java
+++ b/core-common/src/main/java/org/glassfish/jersey/process/internal/ExecutorProviders.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -31,6 +31,7 @@
import jakarta.inject.Named;
import jakarta.inject.Qualifier;
import jakarta.inject.Singleton;
+import jakarta.ws.rs.RuntimeType;
import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.inject.Bindings;
@@ -68,13 +69,13 @@
*
* @param injectionManager application's injection manager.
*/
- public static void registerExecutorBindings(InjectionManager injectionManager) {
+ public static void registerExecutorBindings(InjectionManager injectionManager, RuntimeType runtimeType) {
List<ExecutorServiceProvider> executorProviders =
getExecutorProviders(injectionManager, ExecutorServiceProvider.class);
List<ScheduledExecutorServiceProvider> scheduledProviders =
getExecutorProviders(injectionManager, ScheduledExecutorServiceProvider.class);
- registerExecutorBindings(injectionManager, executorProviders, scheduledProviders);
+ registerExecutorBindings(injectionManager, executorProviders, scheduledProviders, runtimeType);
}
private static <T> List<T> getExecutorProviders(InjectionManager injectionManager, Class<T> providerClass) {
@@ -103,7 +104,8 @@
public static void registerExecutorBindings(
InjectionManager injectionManager,
List<ExecutorServiceProvider> executorProviders,
- List<ScheduledExecutorServiceProvider> scheduledProviders) {
+ List<ScheduledExecutorServiceProvider> scheduledProviders,
+ RuntimeType runtimeType) {
Map<Class<? extends Annotation>, List<ExecutorServiceProvider>> executorProviderMap =
getQualifierToProviderMap(executorProviders);
@@ -122,7 +124,9 @@
SupplierInstanceBinding<ExecutorService> descriptor =
Bindings.supplier(new ExecutorServiceSupplier(executorProvider))
.in(Singleton.class)
- .to(ExecutorService.class);
+ .to(ExecutorService.class)
+// .forClient(runtimeType == RuntimeType.CLIENT)
+ .id(runtimeType == RuntimeType.CLIENT ? 1011 : 1111);
Annotation qualifier = executorProvider.getClass().getAnnotation(qualifierAnnotationClass);
if (qualifier instanceof Named) {
@@ -151,7 +155,9 @@
SupplierInstanceBinding<ScheduledExecutorService> descriptor =
Bindings.supplier(new ScheduledExecutorServiceSupplier(executorProvider))
.in(Singleton.class)
- .to(ScheduledExecutorService.class);
+ .to(ScheduledExecutorService.class)
+// .forClient(runtimeType == RuntimeType.CLIENT)
+ .id(runtimeType == RuntimeType.CLIENT ? 1013 : 1113);
if (!executorProviderMap.containsKey(qualifierAnnotationClass)) {
// it is safe to register binding for ExecutorService too...
diff --git a/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java b/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
index b7d0472..790d92f 100644
--- a/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
+++ b/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 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
@@ -16,6 +16,7 @@
package org.glassfish.jersey.internal;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Application;
@@ -41,7 +42,7 @@
public class TestRuntimeDelegate extends AbstractRuntimeDelegate {
public TestRuntimeDelegate() {
- super(new MessagingBinders.HeaderDelegateProviders().getHeaderDelegateProviders());
+ super(new MessagingBinders.HeaderDelegateProviders(RuntimeType.CLIENT).getHeaderDelegateProviders());
}
@Override
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationConfigurator.java
index 08e1460..8531a25 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -81,7 +81,7 @@
}
serverBag.setApplication(resultApplication);
- injectionManager.register(Bindings.service(resultApplication).to(Application.class));
+ injectionManager.register(Bindings.service(resultApplication).to(Application.class).id(3199));
}
private static Application createApplication(
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 7d75df1..6fcbe67 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, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024 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
@@ -186,12 +186,14 @@
// TODO: Do we really need these three bindings in DI provider? What JAX-RS specification says?
InstanceBinding<ApplicationHandler> handlerBinding =
Bindings.service(ApplicationHandler.this)
- .to(ApplicationHandler.class);
+ .to(ApplicationHandler.class)
+ .id(3180);
InstanceBinding<ResourceConfig> configBinding =
Bindings.service(serverBag.getRuntimeConfig())
.to(Configuration.class)
- .to(ServerConfig.class);
+ .to(ServerConfig.class)
+ .id(1000);
injectionManager.register(handlerBinding);
injectionManager.register(configBinding);
@@ -274,6 +276,10 @@
initialize(new ApplicationConfigurator(application), Injections.createInjectionManager(parentManager), customBinder);
}
+ /* package */ ApplicationHandler(InjectionManager injectionManager) {
+ initialize(new ApplicationConfigurator(new Application()), injectionManager, null);
+ }
+
private void initialize(ApplicationConfigurator applicationConfigurator, InjectionManager injectionManager,
Binder customBinder) {
LOGGER.config(LocalizationMessages.INIT_MSG(Version.getBuildId()));
@@ -284,19 +290,19 @@
ServerBootstrapBag bootstrapBag = new ServerBootstrapBag();
bootstrapBag.setManagedObjectsFinalizer(managedObjectsFinalizer);
List<BootstrapConfigurator> bootstrapConfigurators = Arrays.asList(
- new RequestProcessingConfigurator(),
+ new RequestProcessingConfigurator(), // 3100-3110
new RequestScope.RequestScopeConfigurator(),
- new ParamConverterConfigurator(),
- new ParamExtractorConfigurator(),
- new ValueParamProviderConfigurator(),
- new JerseyResourceContextConfigurator(),
+ new ParamConverterConfigurator(), // 3010
+ new ParamExtractorConfigurator(), // 3111
+ new ValueParamProviderConfigurator(), // 3120-3150
+ new JerseyResourceContextConfigurator(), // 3112
new ComponentProviderConfigurator(),
- new JaxrsProviders.ProvidersConfigurator(),
- applicationConfigurator,
- new RuntimeConfigConfigurator(),
- new ContextResolverFactory.ContextResolversConfigurator(),
- new MessageBodyFactory.MessageBodyWorkersConfigurator(),
- new ExceptionMapperFactory.ExceptionMappersConfigurator(),
+ new JaxrsProviders.ProvidersConfigurator(), // 3016
+ applicationConfigurator, // 3190 - 3199
+ new RuntimeConfigConfigurator(), // 3180 - 3181
+ new ContextResolverFactory.ContextResolversConfigurator(), // 3014
+ new MessageBodyFactory.MessageBodyWorkersConfigurator(), // 3182
+ new ExceptionMapperFactory.ExceptionMappersConfigurator(), // 3015
new ResourceMethodInvokerConfigurator(),
new ProcessingProvidersConfigurator(),
new ContainerProviderConfigurator(RuntimeType.SERVER),
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/JerseyResourceContextConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/JerseyResourceContextConfigurator.java
index 942237b..1e17d97 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/JerseyResourceContextConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/JerseyResourceContextConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -50,7 +50,8 @@
InstanceBinding<JerseyResourceContext> resourceContextBinding =
Bindings.service(resourceContext)
.to(ResourceContext.class)
- .to(ExtendedResourceContext.class);
+ .to(ExtendedResourceContext.class)
+ .id(3112);
injectionManager.register(resourceContextBinding);
serverBag.setResourceContext(resourceContext);
}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerBootstrapPreinitialization.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerBootstrapPreinitialization.java
new file mode 100644
index 0000000..a7e8963
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerBootstrapPreinitialization.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024 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.innate.BootstrapPreinitialization;
+import org.glassfish.jersey.internal.inject.Bindings;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.process.internal.RequestScoped;
+import org.glassfish.jersey.server.wadl.WadlFeature;
+import org.glassfish.jersey.server.wadl.processor.WadlModelProcessor;
+
+import jakarta.ws.rs.RuntimeType;
+
+public class ServerBootstrapPreinitialization implements BootstrapPreinitialization {
+
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager injectionManager) {
+ if (runtimeType == RuntimeType.SERVER) {
+ new ApplicationHandler(injectionManager);
+ if (new WadlFeature().configure(BootstrapPreinitialization.featureContextInstance())) {
+ injectionManager.register(
+ Bindings.serviceAsContract(WadlModelProcessor.OptionsHandler.class).in(RequestScoped.class)
+ );
+ }
+ }
+ }
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerExecutorProvidersConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerExecutorProvidersConfigurator.java
index 77974f1..1a8b91b 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ServerExecutorProvidersConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerExecutorProvidersConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -28,6 +28,8 @@
import org.glassfish.jersey.spi.ScheduledThreadPoolExecutorProvider;
import org.glassfish.jersey.spi.ThreadPoolExecutorProvider;
+import jakarta.ws.rs.RuntimeType;
+
/**
* Configurator which initializes and register {@link org.glassfish.jersey.spi.ExecutorServiceProvider} and
* {@link org.glassfish.jersey.spi.ScheduledExecutorServiceProvider}.
@@ -57,7 +59,7 @@
injectionManager.register(executorBinding);
registerExecutors(injectionManager, componentBag, defaultAsyncExecutorProvider,
- defaultScheduledExecutorProvider, serverBag.getManagedObjectsFinalizer());
+ defaultScheduledExecutorProvider, serverBag.getManagedObjectsFinalizer(), RuntimeType.SERVER);
}
/**
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
index bfaad0e..0b7abc2 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,6 +19,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.core.Application;
@@ -45,7 +46,7 @@
public class RuntimeDelegateImpl extends AbstractRuntimeDelegate {
public RuntimeDelegateImpl() {
- super(new MessagingBinders.HeaderDelegateProviders().getHeaderDelegateProviders());
+ super(new MessagingBinders.HeaderDelegateProviders(RuntimeType.SERVER).getHeaderDelegateProviders());
}
@Override
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
index ef540e2..ec6f7dd 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -52,6 +52,7 @@
serverBag.setMultivaluedParameterExtractorProvider(multiExtractor);
injectionManager.register(
Bindings.service(multiExtractor)
- .to(MultivaluedParameterExtractorProvider.class));
+ .to(MultivaluedParameterExtractorProvider.class)
+ .id(3111));
}
}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
index 07337eb..f4e1376 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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,17 +116,17 @@
serverBag.setValueParamProviders(Collections.unmodifiableCollection(suppliers));
// Needs to be in InjectionManager because of CdiComponentProvider
- injectionManager.register(Bindings.service(asyncProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(cookieProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(formProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(headerProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(matrixProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(pathProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(queryProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(webTargetProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(beanProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(entityProvider).to(ValueParamProvider.class));
- injectionManager.register(Bindings.service(contextProvider).to(ValueParamProvider.class));
+ injectionManager.register(Bindings.service(asyncProvider).to(ValueParamProvider.class).id(3120));
+ injectionManager.register(Bindings.service(cookieProvider).to(ValueParamProvider.class).id(3121));
+ injectionManager.register(Bindings.service(formProvider).to(ValueParamProvider.class).id(3122));
+ injectionManager.register(Bindings.service(headerProvider).to(ValueParamProvider.class).id(3123));
+ injectionManager.register(Bindings.service(matrixProvider).to(ValueParamProvider.class).id(3124));
+ injectionManager.register(Bindings.service(pathProvider).to(ValueParamProvider.class).id(3125));
+ injectionManager.register(Bindings.service(queryProvider).to(ValueParamProvider.class).id(3126));
+ injectionManager.register(Bindings.service(webTargetProvider).to(ValueParamProvider.class).id(3127));
+ injectionManager.register(Bindings.service(beanProvider).to(ValueParamProvider.class).id(3128));
+ injectionManager.register(Bindings.service(entityProvider).to(ValueParamProvider.class).id(3129));
+ injectionManager.register(Bindings.service(contextProvider).to(ValueParamProvider.class).id(3130));
// Provide request scoped ContainerRequest without the proxy.
Provider<ContainerRequest> request = () -> {
@@ -134,20 +134,20 @@
return reference.get().request();
};
- registerResolver(injectionManager, asyncProvider, Suspended.class, request);
- registerResolver(injectionManager, cookieProvider, CookieParam.class, request);
- registerResolver(injectionManager, formProvider, FormParam.class, request);
- registerResolver(injectionManager, headerProvider, HeaderParam.class, request);
- registerResolver(injectionManager, matrixProvider, MatrixParam.class, request);
- registerResolver(injectionManager, pathProvider, PathParam.class, request);
- registerResolver(injectionManager, queryProvider, QueryParam.class, request);
- registerResolver(injectionManager, webTargetProvider, Uri.class, request);
- registerResolver(injectionManager, beanProvider, BeanParam.class, request);
+ registerResolver(injectionManager, asyncProvider, Suspended.class, request, 3140);
+ registerResolver(injectionManager, cookieProvider, CookieParam.class, request, 3141);
+ registerResolver(injectionManager, formProvider, FormParam.class, request, 3142);
+ registerResolver(injectionManager, headerProvider, HeaderParam.class, request, 3143);
+ registerResolver(injectionManager, matrixProvider, MatrixParam.class, request, 3144);
+ registerResolver(injectionManager, pathProvider, PathParam.class, request, 3145);
+ registerResolver(injectionManager, queryProvider, QueryParam.class, request, 3146);
+ registerResolver(injectionManager, webTargetProvider, Uri.class, request, 31457);
+ registerResolver(injectionManager, beanProvider, BeanParam.class, request, 3148);
}
private void registerResolver(InjectionManager im, ValueParamProvider vfp, Class<? extends Annotation> annotation,
- Provider<ContainerRequest> request) {
- im.register(Bindings.injectionResolver(new ParamInjectionResolver<>(vfp, annotation, request)));
+ Provider<ContainerRequest> request, long id) {
+ im.register(Bindings.injectionResolver(new ParamInjectionResolver<>(vfp, annotation, request)).id(id));
}
@Override
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/process/RequestProcessingConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/process/RequestProcessingConfigurator.java
index 9194c47..c90ebeb 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/process/RequestProcessingConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/process/RequestProcessingConfigurator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -123,25 +123,28 @@
@Override
protected void configure() {
bindAsContract(RequestProcessingContextReference.class)
- .in(RequestScoped.class);
+ .in(RequestScoped.class).id(3101);
// Bind non-proxiable ContainerRequest injection injection points
bindFactory(ContainerRequestFactory.class)
.to(ContainerRequest.class).to(ContainerRequestContext.class)
.proxy(false)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3102);
// Bind proxiable HttpHeaders, Request and ContainerRequestContext injection injection points
bindFactory(ContainerRequestFactory.class)
.to(HttpHeaders.class).to(Request.class).to(PropertiesDelegate.class)
.proxy(true).proxyForSameScope(false)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3103);
// Bind proxiable UriInfo, ExtendedUriInfo and ResourceInfo injection points
bindFactory(UriRoutingContextFactory.class)
.to(UriInfo.class).to(ExtendedUriInfo.class).to(ResourceInfo.class)
.proxy(true).proxyForSameScope(false)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3104);
// Bind proxiable SecurityContext injection point.
// NOTE:
@@ -152,20 +155,23 @@
bind(SecurityContextInjectee.class)
.to(SecurityContext.class)
.proxy(true).proxyForSameScope(false)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3105);
// Bind proxiable CloseableService injection point.
bindFactory(CloseableServiceFactory.class)
.to(CloseableService.class)
.proxy(true).proxyForSameScope(false)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3106);
// Bind proxiable AsyncContext and AsyncResponse injection points.
// TODO maybe we can get rid of these completely? Or at least for AsyncContext?
bindFactory(AsyncContextFactory.class)
.to(AsyncContext.class)
.to(AsyncResponse.class)
- .in(RequestScoped.class);
+ .in(RequestScoped.class)
+ .id(3107);
}
}
}
diff --git a/core-server/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization b/core-server/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
new file mode 100644
index 0000000..66f8ea4
--- /dev/null
+++ b/core-server/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
@@ -0,0 +1 @@
+org.glassfish.jersey.server.ServerBootstrapPreinitialization
\ No newline at end of file
diff --git a/incubator/cdi-inject-weld/pom.xml b/incubator/cdi-inject-weld/pom.xml
index f13b275..d077afb 100644
--- a/incubator/cdi-inject-weld/pom.xml
+++ b/incubator/cdi-inject-weld/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2017, 2024 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
@@ -94,6 +94,11 @@
<artifactId>jakarta.el-api</artifactId>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-osgi</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/ClassBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/ClassBean.java
index d7bfc8c..68a787e 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/ClassBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/ClassBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -28,6 +28,8 @@
import jakarta.enterprise.inject.spi.InjectionTarget;
import jakarta.ws.rs.RuntimeType;
+import org.glassfish.jersey.inject.weld.internal.inject.InitializableInstanceBinding;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
import org.glassfish.jersey.internal.inject.ClassBinding;
@@ -60,7 +62,7 @@
*
* @author Petr Bouda
*/
-class ClassBean<T> extends JerseyBean<T> {
+public class ClassBean<T> extends JerseyBean<T> {
private final ClassBinding<T> binding;
private InjectionTarget<T> injectionTarget;
@@ -90,6 +92,12 @@
@Override
@SuppressWarnings("unchecked")
public T create(CreationalContext<T> context) {
+// ClassBinding<T> realBinding = (ClassBinding<T>) getBinding();
+// if (JerseyClientCreationalContext.class.isInstance(context)) {
+// realBinding = ((JerseyClientCreationalContext) context)
+// .getInjectionManager().getInjectionManagerBinding(realBinding);
+// }
+// T service = realBinding.getService();
T instance = injectionTarget.produce(context);
injectionTarget.inject(instance, context);
injectionTarget.postConstruct(instance);
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java
index cf0dd3d..5e1f7d5 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -22,8 +22,12 @@
import org.glassfish.jersey.inject.weld.internal.inject.InitializableInstanceBinding;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
+import org.glassfish.jersey.inject.weld.internal.managed.CdiClientInjectionManager;
+import org.glassfish.jersey.inject.weld.internal.managed.ContextSafe;
+import org.glassfish.jersey.internal.inject.InjectionManager;
import java.lang.annotation.Annotation;
+import java.util.Objects;
/**
* Instance bean to be created in the pre-initialization phase and initialized after Jersey is bootstrap.
@@ -52,6 +56,11 @@
InitializableInstanceBinding<T> realBinding = (InitializableInstanceBinding<T>) getBinding();
if (JerseyClientCreationalContext.class.isInstance(context)) {
realBinding = ((JerseyClientCreationalContext) context).getInjectionManager().getInjectionManagerBinding(realBinding);
+ } else {
+ CdiClientInjectionManager locked = ContextSafe.get();
+ if (locked != null) {
+ realBinding = locked.getInjectionManagerBinding(realBinding);
+ }
}
T service = realBinding.getService();
this.injectionTarget.inject(service, context);
@@ -75,6 +84,6 @@
@Override
public String toString() {
- return "InitializableInstanceBean{" + getBeanClass() + "}";
+ return getBinding().toString();
}
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java
index d42ca44..98fb63d 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,6 +23,8 @@
import org.glassfish.jersey.inject.weld.internal.inject.InitializableSupplierInstanceBinding;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
+import org.glassfish.jersey.inject.weld.internal.managed.CdiClientInjectionManager;
+import org.glassfish.jersey.inject.weld.internal.managed.ContextSafe;
import org.glassfish.jersey.inject.weld.internal.type.ParameterizedTypeImpl;
import org.glassfish.jersey.internal.inject.DisposableSupplier;
import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
@@ -101,6 +103,12 @@
final JerseyClientCreationalContext jerseyContext = (JerseyClientCreationalContext) context;
return jerseyContext.getInjectionManager().getInjectionManagerBinding(binding).getSupplier();
} else {
+ CdiClientInjectionManager locked = ContextSafe.get();
+ if (locked != null) {
+ return locked
+ .getInjectionManagerBinding((InitializableSupplierInstanceBinding<T>) getBinding())
+ .getSupplier();
+ }
return supplier;
}
}
@@ -115,4 +123,9 @@
public Class<? extends Annotation> getScope() {
return getBinding().getScope() == null ? Dependent.class : transformScope(getBinding().getScope());
}
+
+ @Override
+ public String toString() {
+ return getBinding().toString();
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java
index 8f16719..773e779 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -21,7 +21,10 @@
import jakarta.ws.rs.RuntimeType;
import org.glassfish.jersey.inject.weld.internal.inject.InitializableSupplierInstanceBinding;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
+import org.glassfish.jersey.inject.weld.internal.managed.CdiClientInjectionManager;
+import org.glassfish.jersey.inject.weld.internal.managed.ContextSafe;
import org.glassfish.jersey.internal.inject.DisposableSupplier;
import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
@@ -83,7 +86,19 @@
@Override
public Object create(CreationalContext creationalContext) {
- return supplier.get();
+ if (JerseyClientCreationalContext.class.isInstance(creationalContext)) {
+ final InitializableSupplierInstanceBinding binding = (InitializableSupplierInstanceBinding) getBinding();
+ final JerseyClientCreationalContext jerseyContext = (JerseyClientCreationalContext) creationalContext;
+ return jerseyContext.getInjectionManager().getInjectionManagerBinding(binding).getSupplier().get();
+ } else {
+ CdiClientInjectionManager locked = ContextSafe.get();
+ if (locked != null) {
+ return locked
+ .getInjectionManagerBinding((InitializableSupplierInstanceBinding) getBinding())
+ .getSupplier().get();
+ }
+ return supplier.get();
+ }
}
@Override
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
index 66594f9..fa19e81 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -21,6 +21,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import jakarta.enterprise.context.Dependent;
@@ -161,7 +162,7 @@
return binding.getRank();
}
- int defaultValue = 1;
+ int defaultValue = 0;
Class<T> type = binding.getImplementationType();
if (type != null) {
return JerseyPriorities.getPriorityValue(type, defaultValue);
@@ -189,4 +190,17 @@
public String getContractsAsString() {
return Arrays.toString(binding.getContracts().toArray());
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ JerseyBean<?> that = (JerseyBean<?>) o;
+ return Objects.equals(binding, that.binding) && runtimeType == that.runtimeType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(binding, runtimeType);
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/SupplierClassBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/SupplierClassBean.java
index ef4d154..0f71404 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/SupplierClassBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/SupplierClassBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -63,7 +63,7 @@
*
* @author Petr Bouda
*/
-class SupplierClassBean<T> extends JerseyBean<Supplier<T>> {
+public class SupplierClassBean<T> extends JerseyBean<Supplier<T>> {
private final Set<Type> contracts = new HashSet<>();
private final Class<? extends Supplier<T>> supplierClass;
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/data/BindingBeanPair.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/data/BindingBeanPair.java
index 1d0b2c9..c8d66b7 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/data/BindingBeanPair.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/data/BindingBeanPair.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,7 +18,7 @@
import org.glassfish.jersey.inject.weld.internal.bean.JerseyBean;
import org.glassfish.jersey.internal.inject.Binding;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -26,7 +26,7 @@
*/
public class BindingBeanPair {
private final Binding binding;
- private final List<JerseyBean> beans = new LinkedList<JerseyBean>();
+ private final List<JerseyBean> beans = new ArrayList<JerseyBean>();
public BindingBeanPair(Binding binding, JerseyBean... beans) {
this.binding = binding;
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/ClassListBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/ClassListBinding.java
new file mode 100644
index 0000000..e9faa98
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/ClassListBinding.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.internal.inject;
+
+import org.glassfish.jersey.internal.inject.ClassBinding;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+import org.glassfish.jersey.internal.inject.ServiceHolderImpl;
+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.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ClassListBinding<T> {
+ private final Class<T> serviceType;
+ private final List<ClassBinding<T>> services = new ArrayList<>();
+ private final InjectionManager injectionManager;
+ private final LazyValue<List<ServiceHolder<T>>> instances;
+
+ public ClassListBinding(Class<T> serviceType, InjectionManager injectionManager) {
+ this.serviceType = serviceType;
+ this.injectionManager = injectionManager;
+ instances = Values.lazy((Value<List<ServiceHolder<T>>>) () -> services.stream()
+ .map(binding -> new ServiceHolderImpl(
+ create(binding),
+ binding.getService().getClass(),
+ binding.getContracts(),
+ binding.getRank() == null ? 0 : binding.getRank()))
+ .map(sh -> (ServiceHolder<T>) sh).collect(Collectors.toList()));
+ }
+
+ private T create(ClassBinding<T> binding) {
+ T t = injectionManager.create(binding.getService());
+ injectionManager.inject(t);
+ return t;
+ }
+
+ public void init(ClassBinding<?> service) {
+ services.add((ClassBinding<T>) service);
+ }
+
+ public List<T> getServices() {
+ return instances.get().stream().map(sh -> ((ServiceHolder<T>) sh).getInstance()).collect(Collectors.toList());
+ }
+
+ public List<ServiceHolder<T>> getServiceHolders() {
+ return instances.get();
+ }}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableBinding.java
new file mode 100644
index 0000000..d464483
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableBinding.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.internal.inject;
+
+import jakarta.ws.rs.RuntimeType;
+
+public abstract class InitializableBinding<T, U extends MatchableBinding> extends MatchableBinding<T, U> {
+
+ public abstract boolean isInit();
+
+ public abstract RuntimeType getRuntimeType();
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableInstanceBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableInstanceBinding.java
index 61b4a2c..0e41170 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableInstanceBinding.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableInstanceBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,13 +18,13 @@
import org.glassfish.jersey.internal.inject.AliasBinding;
import org.glassfish.jersey.internal.inject.Binding;
-import org.glassfish.jersey.internal.inject.Bindings;
import org.glassfish.jersey.internal.inject.InstanceBinding;
+import jakarta.ws.rs.RuntimeType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Arrays;
-import java.util.Collections;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,19 +34,21 @@
*
* @param <T> Type of the service described by this injection binding.
*/
-public class InitializableInstanceBinding<T> extends MatchableBinding<T, InitializableInstanceBinding<T>> implements Cloneable {
+public class InitializableInstanceBinding<T> extends InitializableBinding<T, InitializableInstanceBinding<T>>
+ implements Cloneable {
protected T service;
- private AtomicBoolean isInit = new AtomicBoolean(false);
+ private final AtomicBoolean isInit = new AtomicBoolean(false);
private Class<T> implementationType;
+ private final RuntimeType runtimeType;
/**
* Creates a service as an instance.
*
* @param service service's instance.
*/
- protected InitializableInstanceBinding(T service) {
- this(service, null);
+ protected InitializableInstanceBinding(T service, RuntimeType runtimeType) {
+ this(service, null, runtimeType);
}
/**
@@ -55,12 +57,13 @@
* @param service service's instance.
* @param contractType service's contractType.
*/
- private InitializableInstanceBinding(T service, Type contractType) {
+ private InitializableInstanceBinding(T service, Type contractType, RuntimeType runtimeType) {
this.service = service;
this.implementationType = service == null ? null : (Class<T>) service.getClass();
if (contractType != null) {
this.to(contractType);
}
+ this.runtimeType = runtimeType;
}
/**
@@ -81,6 +84,7 @@
*
* @return service's type.
*/
+ @Override
public Class<T> getImplementationType() {
return implementationType;
}
@@ -98,6 +102,12 @@
return isInit.get();
}
+ @Override
+ public RuntimeType getRuntimeType() {
+ return runtimeType;
+ }
+
+ @Override
public Matching<InitializableInstanceBinding<T>> matches(Binding other) {
return super.matches(other);
}
@@ -107,8 +117,8 @@
throw new RuntimeException(new CloneNotSupportedException());
}
- public static <T> InitializableInstanceBinding<T> from(InstanceBinding<T> instanceBinding) {
- return new InitializableWrappingInstanceBinding(instanceBinding);
+ public static <T> InitializableInstanceBinding<T> from(InstanceBinding<T> instanceBinding, RuntimeType runtimeType) {
+ return new InitializableWrappingInstanceBinding(instanceBinding, runtimeType);
}
@Override
@@ -116,42 +126,79 @@
return MatchLevel.IMPLEMENTATION;
}
+ @Override
+ public Matching<MatchableBinding> matching(Binding other) {
+ return visitor.matches((InitializableInstanceBinding) this, other);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(service, implementationType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ InitializableInstanceBinding<?> that = (InitializableInstanceBinding<?>) o;
+ return Objects.equals(service, that.service)
+ && Objects.equals(implementationType, that.implementationType);
+ }
+
private static class InitializableWrappingInstanceBinding<T> extends InitializableInstanceBinding<T> {
private final InstanceBinding<T> wrapped;
- public InitializableWrappingInstanceBinding(InstanceBinding<T> binding) {
- super(binding.getService());
+ public InitializableWrappingInstanceBinding(InstanceBinding<T> binding, RuntimeType runtimeType) {
+ super(binding.getService(), runtimeType);
wrapped = binding;
+ postCreate();
}
- private InitializableWrappingInstanceBinding(InitializableWrappingInstanceBinding<T> binding) {
- super(binding.service);
+ private InitializableWrappingInstanceBinding(InitializableWrappingInstanceBinding<T> binding, RuntimeType runtimeType) {
+ super(binding.service, runtimeType);
wrapped = binding.wrapped;
+ postCreate();
}
- @Override
- public Class<T> getImplementationType() {
- return super.getImplementationType();
+ private void postCreate() {
+ wrapped.getContracts().forEach(c -> this.to(c));
+ if (wrapped.getRank() != null) {
+ this.ranked(wrapped.getRank());
+ }
+ this.named(wrapped.getName());
+ this.id(wrapped.getId());
+ this.in(wrapped.getScope());
+ this.forClient(wrapped.isForClient());
}
- @Override
- public T getService() {
- return super.getService();
- }
+// @Override
+// public Class<T> getImplementationType() {
+// return super.getImplementationType();
+// }
+//
+// @Override
+// public T getService() {
+// return super.getService();
+// }
+//
+// @Override
+// public RuntimeType getRuntime() {
+// return super.getRuntime();
+// }
- @Override
- public Class<? extends Annotation> getScope() {
- return wrapped.getScope();
- }
-
- @Override
- public Set<Type> getContracts() {
- return wrapped.getContracts();
- }
-
- @Override
- public Integer getRank() {
- return wrapped.getRank();
- }
+// @Override
+// public Class<? extends Annotation> getScope() {
+// return wrapped.getScope();
+// }
+//
+// @Override
+// public Set<Type> getContracts() {
+// return wrapped.getContracts();
+// }
+//
+// @Override
+// public Integer getRank() {
+// return wrapped.getRank();
+// }
@Override
public Set<AliasBinding> getAliases() {
@@ -175,12 +222,22 @@
@Override
public String toString() {
- return "InitializableWrappingInstanceBinding(" + wrapped.getService().getClass() + ")";
+ return wrapped.toString();
}
+// @Override
+// public boolean isForClient() {
+// return wrapped.isForClient();
+// }
+//
+// @Override
+// public long getId() {
+// return wrapped.getId();
+// }
+
@Override
public InitializableWrappingInstanceBinding clone() {
- return new InitializableWrappingInstanceBinding(this);
+ return new InitializableWrappingInstanceBinding(this, this.getRuntimeType());
}
}
}
\ No newline at end of file
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableSupplierInstanceBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableSupplierInstanceBinding.java
index d99bf59..c4421f7 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableSupplierInstanceBinding.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InitializableSupplierInstanceBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -21,10 +21,12 @@
import org.glassfish.jersey.internal.inject.DisposableSupplier;
import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
+import jakarta.ws.rs.RuntimeType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -32,20 +34,23 @@
* @param <T> Type of the supplied service described by this injection binding.
*/
public class InitializableSupplierInstanceBinding<T>
- extends MatchableBinding<Supplier<T>, InitializableSupplierInstanceBinding<T>>
+ extends InitializableBinding<Supplier<T>, InitializableSupplierInstanceBinding<T>>
implements Cloneable {
private final InitializableSupplier<T> supplier;
+ private final RuntimeType runtimeType;
/**
* Creates a supplier as an instance.
*
- * @param supplier service's instance.
+ * @param supplier service's instance.
+ * @param runtimeType
*/
- public InitializableSupplierInstanceBinding(Supplier<T> supplier) {
+ public InitializableSupplierInstanceBinding(Supplier<T> supplier, RuntimeType runtimeType) {
this.supplier = DisposableSupplier.class.isInstance(supplier)
? new InitializableDisposableSupplier<T>((DisposableSupplier<T>) supplier)
: new InitializableSupplier<T>(supplier);
+ this.runtimeType = runtimeType;
if ("EmptyReferenceFactory".equals(supplier.getClass().getSimpleName())) {
this.supplier.init(supplier);
this.supplier.isReferencingFactory = true;
@@ -65,6 +70,11 @@
return supplier.init.get();
}
+ @Override
+ public RuntimeType getRuntimeType() {
+ return runtimeType;
+ }
+
/**
* Gets supplier's instance.
*
@@ -81,8 +91,8 @@
return supplier.originalSupplier;
}
- public static <T> InitializableSupplierInstanceBinding<T> from(SupplierInstanceBinding<T> binding) {
- return new InitializableSupplierWrappingInstanceBinding(binding);
+ public static <T> InitializableSupplierInstanceBinding<T> from(SupplierInstanceBinding<T> binding, RuntimeType runtimeType) {
+ return new InitializableSupplierWrappingInstanceBinding(binding, runtimeType);
}
@Override
@@ -100,6 +110,9 @@
private Matching<InitializableSupplierInstanceBinding<T>> matches(
Class<?> originalSupplierClass, Class<?> otherSupplierClass, Binding other) {
+ if (getId() != 0) {
+ return matchesById(other);
+ }
final boolean matchesService = originalSupplierClass.equals(otherSupplierClass);
final Matching matching = matchesContracts(other);
if (matching.matchLevel == MatchLevel.FULL_CONTRACT && matchesService) {
@@ -113,6 +126,11 @@
return MatchLevel.SUPPLIER;
}
+ @Override
+ public Matching<MatchableBinding> matching(Binding other) {
+ return visitor.matches((InitializableSupplierInstanceBinding) this, other);
+ }
+
private static class InitializableDisposableSupplier<T> extends InitializableSupplier<T> implements DisposableSupplier<T> {
private InitializableDisposableSupplier(DisposableSupplier<T> originalSupplier) {
super(originalSupplier);
@@ -120,7 +138,9 @@
@Override
public void dispose(T instance) {
- ((DisposableSupplier) supplier).dispose(instance);
+ if (isInit()) {
+ ((DisposableSupplier) supplier).dispose(instance);
+ }
}
}
@@ -158,40 +178,59 @@
private static class InitializableSupplierWrappingInstanceBinding<T> extends InitializableSupplierInstanceBinding<T> {
private final SupplierInstanceBinding wrapped;
- public InitializableSupplierWrappingInstanceBinding(SupplierInstanceBinding binding) {
- super(binding.getSupplier());
+ InitializableSupplierWrappingInstanceBinding(SupplierInstanceBinding binding, RuntimeType runtimeType) {
+ super(binding.getSupplier(), runtimeType);
wrapped = binding;
+ postCreate();
}
- private InitializableSupplierWrappingInstanceBinding(InitializableSupplierWrappingInstanceBinding binding) {
- super(binding.getOriginalSupplier());
+ private InitializableSupplierWrappingInstanceBinding(InitializableSupplierWrappingInstanceBinding binding,
+ RuntimeType runtimeType) {
+ super(binding.getOriginalSupplier(), runtimeType);
wrapped = binding.wrapped;
+ postCreate();
}
- @Override
- public Class getImplementationType() {
- return super.getImplementationType();
+ private void postCreate() {
+ wrapped.getContracts().forEach(c -> this.to((Type) c));
+ if (wrapped.getRank() != null) {
+ this.ranked(wrapped.getRank());
+ }
+ this.named(wrapped.getName());
+ this.id(wrapped.getId());
+ this.in(wrapped.getScope());
+ this.forClient(wrapped.isForClient());
}
- @Override
- public Supplier getSupplier() {
- return super.getSupplier();
- }
+// @Override
+// public Class getImplementationType() {
+// return super.getImplementationType();
+// }
+//
+// @Override
+// public Supplier getSupplier() {
+// return super.getSupplier();
+// }
+//
+// @Override
+// public RuntimeType getRuntime() {
+// return super.getRuntime();
+// }
- @Override
- public Class<? extends Annotation> getScope() {
- return wrapped.getScope();
- }
-
- @Override
- public Set<Type> getContracts() {
- return wrapped.getContracts();
- }
-
- @Override
- public Integer getRank() {
- return wrapped.getRank();
- }
+// @Override
+// public Class<? extends Annotation> getScope() {
+// return wrapped.getScope();
+// }
+//
+// @Override
+// public Set<Type> getContracts() {
+// return wrapped.getContracts();
+// }
+//
+// @Override
+// public Integer getRank() {
+// return wrapped.getRank();
+// }
@Override
public Set<AliasBinding> getAliases() {
@@ -209,19 +248,35 @@
}
@Override
- public String getName() {
- return wrapped.getName();
+ public String toString() {
+ return wrapped.toString();
}
+
+// @Override
+// public String getName() {
+// return wrapped.getName();
+// }
+
+// @Override
+// public long getId() {
+// return wrapped.getId();
+// }
+//
+// @Override
+// public boolean isForClient() {
+// return wrapped.isForClient();
+// }
+
@Override
public InitializableSupplierWrappingInstanceBinding clone() {
- return new InitializableSupplierWrappingInstanceBinding(this);
+ return new InitializableSupplierWrappingInstanceBinding(this, getRuntimeType());
}
- @Override
- public String toString() {
- return "InitializableSupplierWrappingInstanceBinding(" + wrapped.getSupplier() + ")";
- }
+// @Override
+// public String toString() {
+// return "InitializableSupplierWrappingInstanceBinding(" + wrapped.getSupplier() + ")";
+// }
}
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InstanceListBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InstanceListBinding.java
new file mode 100644
index 0000000..201d71a
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/InstanceListBinding.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.internal.inject;
+
+import org.glassfish.jersey.internal.inject.Binding;
+import org.glassfish.jersey.internal.inject.InstanceBinding;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+import org.glassfish.jersey.internal.inject.ServiceHolderImpl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class InstanceListBinding<T> extends MatchableBinding<List<T>, InitializableInstanceBinding<List<T>>>
+ implements Cloneable {
+
+ private final Class<T> serviceType;
+ private final List<InstanceBinding<T>> services = new ArrayList<>();
+
+ /**
+ * Creates a service as an instance.
+ *
+ * @param serviceType service's type.
+ */
+ public InstanceListBinding(Class<T> serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ @Override
+ protected MatchLevel bestMatchLevel() {
+ return MatchLevel.NEVER;
+ }
+
+ @Override
+ public Matching<MatchableBinding> matching(Binding other) {
+ return Matching.noneMatching();
+ }
+
+ public void init(InstanceBinding<?> service) {
+ services.add((InstanceBinding<T>) service);
+ }
+
+ public List<T> getServices() {
+ return services.stream().map(binding -> binding.getService()).collect(Collectors.toList());
+ }
+
+ public List<ServiceHolder<T>> getServiceHolders() {
+ return services.stream().map(binding ->
+ new ServiceHolderImpl<T>(binding.getService(), serviceType, binding.getContracts(),
+ binding.getRank() == null ? 0 : binding.getRank()))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/MatchableBinding.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/MatchableBinding.java
index e6cd0bd..2fc71d3 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/MatchableBinding.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/inject/MatchableBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,6 +17,8 @@
package org.glassfish.jersey.inject.weld.internal.inject;
import org.glassfish.jersey.internal.inject.Binding;
+import org.glassfish.jersey.internal.inject.InstanceBinding;
+import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
import java.lang.reflect.Type;
import java.util.Set;
@@ -29,9 +31,20 @@
*/
public abstract class MatchableBinding<T, D extends MatchableBinding> extends Binding<T, D> {
+ protected static MatchingVisitor visitor = new MatchingVisitor();
protected abstract MatchLevel bestMatchLevel();
+ /**
+ * Visitor version of matches
+ * @param other
+ * @return
+ */
+ public abstract Matching<MatchableBinding> matching(Binding other);
+
protected Matching<D> matches(Binding<?, ?> other) {
+ if (getId() != 0) {
+ return matchesById(other);
+ }
final Matching<D> matching = matchesContracts(other);
if (matching.matchLevel == MatchLevel.FULL_CONTRACT) {
if (getImplementationType().equals(other.getImplementationType())) {
@@ -41,6 +54,14 @@
return matching;
}
+ protected Matching matchesById(Binding<?, ?> other) {
+ if (getId() == other.getId()) {
+ return new Matching<>((D) this, MatchLevel.FULL_CONTRACT);
+ } else {
+ return Matching.noneMatching();
+ }
+ }
+
/**
* Return a Matching object that represents comparison between contracts of this binding and a given binding.
* The result contains a reference to this binding.
@@ -113,6 +134,10 @@
public D getBinding() {
return binding;
}
+
+ public Matching<D> clone() {
+ return new Matching<>(binding, matchLevel);
+ }
}
/**
@@ -123,7 +148,8 @@
PARTIAL_CONTRACT(1),
FULL_CONTRACT(2),
IMPLEMENTATION(3),
- SUPPLIER(4);
+ SUPPLIER(4),
+ NEVER(5);
private final int level;
@@ -131,5 +157,21 @@
this.level = level;
}
}
+
+ protected static class MatchingVisitor<D extends MatchableBinding<?, D>> {
+ public MatchableBinding.Matching<InitializableInstanceBinding<D>> matches(
+ InitializableInstanceBinding<D> binding, Binding other) {
+ return binding.matches((InstanceBinding) other);
+ }
+
+ public MatchableBinding.Matching<InitializableSupplierInstanceBinding<D>> matches(
+ InitializableSupplierInstanceBinding<D> binding, Binding other) {
+ return binding.matches((SupplierInstanceBinding<D>) other);
+ }
+
+ public Matching<MatchableBinding<?, D>> matches(MatchableBinding<?, D> binding, Binding other) {
+ throw new IllegalStateException("Unexpected");
+ }
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyInjectionTarget.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyInjectionTarget.java
index b64513b..35e2d42 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyInjectionTarget.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyInjectionTarget.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -62,7 +62,7 @@
* instances. {@code Delegate} is a original {@code InjectionTarget} which is able to inject other fields/parameters which
* are managed by CDI.
* <p>
- * Implementation is also able create with custom {@code jerseyConstructor} if it is provided. This functionality allows override
+ * Implementation is also able to create with custom {@code jerseyConstructor} if it is provided. This functionality allows override
* default instantiator and use the Jersey-specific one.
*/
public class JerseyInjectionTarget<T> extends BasicInjectionTarget<T> {
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyTwofoldInstantiator.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyTwofoldInstantiator.java
index 01e96c0..ee09f29 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyTwofoldInstantiator.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/injector/JerseyTwofoldInstantiator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,6 +17,7 @@
package org.glassfish.jersey.inject.weld.internal.injector;
import jakarta.enterprise.context.spi.CreationalContext;
+
import org.jboss.weld.injection.ConstructorInjectionPoint;
import org.jboss.weld.injection.producer.AbstractInstantiator;
import org.jboss.weld.manager.BeanManagerImpl;
@@ -59,10 +60,10 @@
@Override
public T newInstance(CreationalContext<T> ctx, BeanManagerImpl manager) {
final ConstructorInjectionPoint<T> cip =
- optionalConstructorInjectionPoint == null || !JerseyClientCreationalContext.class.isInstance(ctx)
+ !hasOptionalConstructorInjectionPoint() || !JerseyClientCreationalContext.class.isInstance(ctx)
? primaryInstantiator.getConstructorInjectionPoint()
: optionalConstructorInjectionPoint;
- return cip.newInstance(manager, ctx);
+ return cip.newInstance(manager, ctx);
}
/**
@@ -72,4 +73,8 @@
public void setOptionalConstructorInjectionPoint(ConstructorInjectionPoint<T> optionalConstructorInjectionPoint) {
this.optionalConstructorInjectionPoint = optionalConstructorInjectionPoint;
}
+
+ public boolean hasOptionalConstructorInjectionPoint() {
+ return optionalConstructorInjectionPoint != null;
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/BinderRegisterExtension.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/BinderRegisterExtension.java
index 60d48e4..7a3b0af 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/BinderRegisterExtension.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/BinderRegisterExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -20,6 +20,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -29,6 +30,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -104,24 +107,35 @@
*/
class BinderRegisterExtension implements Extension {
- private AtomicBoolean registrationDone = new AtomicBoolean(false);
+ private final AtomicBoolean registrationDone = new AtomicBoolean(false);
private Supplier<BeanManager> beanManagerSupplier;
- private Ref<InjectionManager> serverInjectionManager = Refs.emptyRef();
+ private final Ref<InjectionManager> serverInjectionManager = Refs.emptyRef();
- private BootstrapInjectionManager clientBootstrapInjectionManager = new BootstrapInjectionManager(RuntimeType.CLIENT);
- private WrappingInjectionManager serverBootstrapInjectionManager = new WrappingInjectionManager()
+ private final BootstrapInjectionManager clientBootstrapInjectionManager = new BootstrapInjectionManager(RuntimeType.CLIENT);
+ private final WrappingInjectionManager serverBootstrapInjectionManager = new WrappingInjectionManager()
.setInjectionManager(new BootstrapInjectionManager(RuntimeType.SERVER));
- private BootstrapBag bootstrapBag = new BootstrapBag();
+ private final BootstrapBag bootstrapBag = new BootstrapBag();
- private final CachingBinder clientBindings = new CachingBinder(serverInjectionManager);
- private final CachingBinder serverBindings = new CachingBinder(serverInjectionManager) {
+ private final List<InitializableInstanceBinding> skippedClientInstanceBindings = new ArrayList<>();
+ private final List<InitializableSupplierInstanceBinding> skippedClientSupplierInstanceBindings = new ArrayList<>();
+
+ private final CachingBinder clientBindings = new CachingBinder(serverInjectionManager, RuntimeType.CLIENT) {
+// @Override
+// protected void configure() {
+// bind(InitializableInstanceBinding.from(
+// Bindings.service(clientBootstrapInjectionManager).to(InjectionManager.class)));
+// }
+ };
+ private final CachingBinder serverBindings = new CachingBinder(serverInjectionManager, RuntimeType.SERVER) {
@Override
protected void configure() {
install(new ContextInjectionResolverImpl.Binder(beanManagerSupplier));
- bind(InitializableInstanceBinding.from(Bindings.service(serverInjectionManager.get()).to(InjectionManager.class)));
+ bind(InitializableInstanceBinding.from(
+ Bindings.service(serverInjectionManager.get()).to(InjectionManager.class),
+ RuntimeType.SERVER));
}
};
- private final CachingBinder annotatedBeansBinder = new CachingBinder(serverInjectionManager);
+ private final CachingBinder annotatedBeansBinder = new CachingBinder(serverInjectionManager, null);
private final MergedBindings mergedBindings = new MergedBindings(serverBindings, clientBindings);
private final List<InitializableInstanceBinding> initializableInstanceBindings = new LinkedList<>();
@@ -274,15 +288,15 @@
*
* @param abd {@code AfterBeanDiscovery} event.
* @param beanManager current {@code BeanManager}.
- * @link ProcessAnnotatedType} bootstrap phase.
+ * @see ProcessAnnotatedType bootstrap phase.
*/
void registerBeans(@Observes AfterBeanDiscovery abd, BeanManager beanManager) {
- serverInjectionManager.set(new CdiInjectionManager(beanManager, mergedBindings));
+ serverInjectionManager.set(new CdiInjectionManager(beanManager, mergedBindings, RuntimeType.SERVER));
beanManagerSupplier = () -> beanManager; // set bean manager supplier to be called by bindings#configure
CdiInjectionManagerFactoryBase.setBeanManager(beanManager);
- registerApplicationHandler(beanManager);
+// registerApplicationHandler(beanManager);
registrationDone.set(true); //
@@ -316,16 +330,32 @@
final Collection<Binding> bindings = binder.getBindings();
binder.setReadOnly();
+ //check unique id;
+ TreeMap<Long, Binding> treeMap = new TreeMap<>();
+ for (Binding binding : bindings) {
+ if (binding.getId() != 0 && !binding.isForClient()) {
+ if (treeMap.containsKey(binding.getId())) {
+ throw new IllegalStateException("Id " + binding.getId() + " already exists:" + treeMap.get(binding.getId()));
+ }
+ treeMap.put(binding.getId(), binding);
+ }
+ }
+
allBindingsLabel:
for (Binding binding : bindings) {
if (ClassBinding.class.isAssignableFrom(binding.getClass())) {
if (RuntimeType.CLIENT == runtimeType) {
for (Type contract : ((ClassBinding<?>) binding).getContracts()) {
- final List<BindingBeanPair> preregistered = classBindings.get(contract);
- if (preregistered != null && preregistered.size() == 1) {
- BeanHelper.updateBean(
- (ClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
- continue allBindingsLabel;
+ List<BindingBeanPair> preregistered = classBindings.get(contract);
+ if (preregistered != null) {
+ preregistered = preregistered.stream()
+ .filter(pair -> pair.getBeans().get(0).getRutimeType() == RuntimeType.SERVER)
+ .collect(Collectors.toList());
+ if (preregistered.size() == 1 || binding.isForClient()) {
+ BeanHelper.updateBean(
+ (ClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
+ continue allBindingsLabel;
+ }
}
}
}
@@ -337,11 +367,16 @@
} else if (SupplierClassBinding.class.isAssignableFrom(binding.getClass())) {
if (RuntimeType.CLIENT == runtimeType) {
for (Type contract : ((SupplierClassBinding<?>) binding).getContracts()) {
- final List<BindingBeanPair> preregistered = supplierClassBindings.get(contract);
- if (preregistered != null && preregistered.size() == 1) {
- BeanHelper.updateSupplierBean(
- (SupplierClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
- continue allBindingsLabel;
+ List<BindingBeanPair> preregistered = supplierClassBindings.get(contract);
+ if (preregistered != null) {
+ preregistered = preregistered.stream()
+ .filter(pair -> pair.getBeans().get(0).getRutimeType() == RuntimeType.SERVER)
+ .collect(Collectors.toList());
+ if (preregistered.size() == 1 || binding.isForClient()) {
+ BeanHelper.updateSupplierBean(
+ (SupplierClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
+ continue allBindingsLabel;
+ }
}
}
}
@@ -351,17 +386,29 @@
supplierClassBindings.add(contract, pair);
}
} else if (InitializableInstanceBinding.class.isAssignableFrom(binding.getClass())) {
- if (RuntimeType.SERVER == runtimeType
+/*
+ * We do want to register beans such as Configuration just once. There are two of them, one for client and for a server.
+ * But having two of them would fail Weld Validation -> Weld would not know which one to @Inject
+ * The solution is to have JerseyTwoFoldInstantiator that creates a client bean for a client and a server bean for the server.
+ *
+ * But also we do not want to skip registering beans on client that are not in server
+ * or there are multiple of them of the same contract.
+ */
+ if (RuntimeType.SERVER == runtimeType || !binding.isForClient()
|| !matchInitializableInstanceBinding((InitializableInstanceBinding<?>) binding)) {
initializableInstanceBindings.add((InitializableInstanceBinding<?>) binding);
BeanHelper.registerBean(
runtimeType, (InitializableInstanceBinding<?>) binding, abd, injectionResolvers, beanManager);
+ } else {
+ skippedClientInstanceBindings.add((InitializableInstanceBinding) binding);
}
} else if (InitializableSupplierInstanceBinding.class.isInstance(binding)) {
- if (RuntimeType.SERVER == runtimeType
+ if (RuntimeType.SERVER == runtimeType || !binding.isForClient()
|| !matchInitializableSupplierInstanceBinding((InitializableSupplierInstanceBinding) binding)) {
initializableSupplierInstanceBindings.add((InitializableSupplierInstanceBinding) binding);
BeanHelper.registerSupplier(runtimeType, (InitializableSupplierInstanceBinding<?>) binding, abd, beanManager);
+ } else {
+ skippedClientSupplierInstanceBindings.add((InitializableSupplierInstanceBinding) binding);
}
}
}
@@ -525,21 +572,21 @@
/** To be used by the tests only */
- public void register(BeforeBeanDiscovery beforeBeanDiscovery, Binding binding) {
+ void register(BeforeBeanDiscovery beforeBeanDiscovery, Binding binding) {
register(RuntimeType.SERVER, binding);
}
/** To be used by the tests only */
- public void register(BeforeBeanDiscovery beforeBeanDiscovery, Iterable<Binding> bindings) {
+ void register(BeforeBeanDiscovery beforeBeanDiscovery, Iterable<Binding> bindings) {
register(RuntimeType.SERVER, bindings);
}
private void register(RuntimeType runtimeType, Binding binding) {
final AbstractBinder bindings = runtimeType == RuntimeType.CLIENT ? clientBindings : serverBindings;
if (InstanceBinding.class.isInstance(binding)) {
- bindings.bind(InitializableInstanceBinding.from((InstanceBinding) binding));
+ bindings.bind(InitializableInstanceBinding.from((InstanceBinding) binding, runtimeType));
} else if (SupplierInstanceBinding.class.isInstance(binding)) {
- bindings.bind(InitializableSupplierInstanceBinding.from((SupplierInstanceBinding) binding));
+ bindings.bind(InitializableSupplierInstanceBinding.from((SupplierInstanceBinding) binding, runtimeType));
} else {
bindings.bind(binding);
}
@@ -556,10 +603,28 @@
for (BootstrapPreinitialization registrar : ServiceFinder.find(BootstrapPreinitialization.class)) {
registrars.add(registrar);
}
+
+ final List<org.glassfish.jersey.innate.BootstrapPreinitialization> preregistrars = new LinkedList<>();
+ for (org.glassfish.jersey.innate.BootstrapPreinitialization registrar
+ : ServiceFinder.find(org.glassfish.jersey.innate.BootstrapPreinitialization.class)) {
+ preregistrars.add(registrar);
+ }
+
+ for (org.glassfish.jersey.innate.BootstrapPreinitialization registrar
+ : ServiceFinder.find(org.glassfish.jersey.innate.BootstrapPreinitialization.class)) {
+ //registrars.add(registrar);
+ registrar.preregister(RuntimeType.SERVER, serverBootstrapInjectionManager);
+ }
+
for (BootstrapPreinitialization registrar : registrars) {
registrar.register(RuntimeType.SERVER, serverBindings);
}
+ for (org.glassfish.jersey.innate.BootstrapPreinitialization registrar
+ : ServiceFinder.find(org.glassfish.jersey.innate.BootstrapPreinitialization.class)) {
+ registrar.preregister(RuntimeType.CLIENT, clientBootstrapInjectionManager);
+ }
+
for (BootstrapPreinitialization registrar : registrars) {
registrar.register(RuntimeType.CLIENT, clientBindings);
}
@@ -631,9 +696,6 @@
@Override
public <T> T createAndInitialize(Class<T> createMe) {
- if (RequestScope.class == createMe) {
- return (T) new CdiRequestScope();
- }
if (isNotJerseyInternal(createMe)) {
return null;
}
@@ -667,7 +729,10 @@
@Override
public <T> T getInstance(Class<T> contractOrImpl) {
- return createAndInitialize(contractOrImpl);
+ if (RequestScope.class == contractOrImpl) {
+ return (T) new CdiRequestScope();
+ }
+ return null; //createAndInitialize(contractOrImpl);
}
@Override
@@ -705,6 +770,11 @@
public void preDestroy(Object preDestroyMe) {
//noop
}
+
+ @Override
+ public RuntimeType getRuntimeType() {
+ return runtimeType;
+ }
}
/**
@@ -716,9 +786,11 @@
private final Ref<InjectionManager> injectionManager;
private AbstractBinder temporaryBinder = new TemporaryBinder();
private final Collection<Binding> bindings = new LinkedList<>();
+ private final RuntimeType runtimeType;
- private CachingBinder(Ref<InjectionManager> injectionManager) {
+ private CachingBinder(Ref<InjectionManager> injectionManager, RuntimeType runtimeType) {
this.injectionManager = injectionManager;
+ this.runtimeType = runtimeType;
}
@Override
@@ -786,9 +858,9 @@
final Collection<Binding> newBindings = temporaryBinder.getBindings();
for (Binding binding : newBindings) {
if (InstanceBinding.class.isAssignableFrom(binding.getClass())) {
- binding = InitializableInstanceBinding.from((InstanceBinding) binding);
+ binding = InitializableInstanceBinding.from((InstanceBinding) binding, runtimeType);
} else if (SupplierInstanceBinding.class.isAssignableFrom(binding.getClass())) {
- binding = InitializableSupplierInstanceBinding.from((SupplierInstanceBinding) binding);
+ binding = InitializableSupplierInstanceBinding.from((SupplierInstanceBinding) binding, runtimeType);
}
bindings.add(binding);
}
@@ -812,16 +884,55 @@
}
}
- private static class MergedBindings implements Binder {
+ /* package */ static class MergedBindings implements Binder {
private final AbstractBinder first;
private final AbstractBinder second;
-
+ private final Collection<ClassBinding> classBindings = new ArrayList<>();
+ private final Collection<InitializableInstanceBinding> instanceBindings = new ArrayList<>();
+ private final Collection<SupplierClassBinding> supplierClassBindings = new ArrayList<>();
+ private final Collection<InitializableSupplierInstanceBinding> supplierInstanceBindings = new ArrayList<>();
private MergedBindings(AbstractBinder first, AbstractBinder second) {
this.first = first;
this.second = second;
}
+// private void initBindings(Collection<Binding> bindings) {
+// for (Binding binding : bindings) {
+// if (InstanceBinding.class.isInstance(binding)) {
+// instanceBindings.add((InitializableInstanceBinding) binding);
+// } else if (ClassBinding.class.isInstance(binding)) {
+// classBindings.add((ClassBinding) binding);
+// } else if (SupplierInstanceBinding.class.isInstance(binding)) {
+// supplierInstanceBindings.add((InitializableSupplierInstanceBinding) binding);
+// } else if (SupplierClassBinding.class.isInstance(binding)) {
+// supplierClassBindings.add((SupplierClassBinding) binding);
+// }
+// }
+// }
+//
+// public <T extends Binding<T,?>> Collection<T> getBindings(Class<T> clazz) {
+// if (InstanceBinding.class.equals(clazz)) {
+// return (Collection<T>) (Collection<? extends Binding>) instanceBindings;
+// } else if (ClassBinding.class.equals(clazz)) {
+// return (Collection<T>) (Collection<? extends Binding>) classBindings;
+// } else if (SupplierInstanceBinding.class.isInstance(clazz)) {
+// return (Collection<T>) (Collection<? extends Binding>) supplierInstanceBindings;
+// } else if (SupplierClassBinding.class.equals(clazz)) {
+// return (Collection<T>) (Collection<? extends Binding>) supplierClassBindings;
+// }
+// return Collections.emptyList();
+// }
+
+ public Collection<Binding> getServerBindings() {
+ return first.getBindings();
+ }
+
+ public Collection<Binding> getClientBindings() {
+ return second.getBindings();
+ }
+
+ @Override
public Collection<Binding> getBindings() {
final Collection<Binding> firstBindings = first.getBindings();
final Collection<Binding> secondBindings = second.getBindings();
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiClientInjectionManager.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiClientInjectionManager.java
index a1c500f..2c6d247 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiClientInjectionManager.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiClientInjectionManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,71 +19,88 @@
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.enterprise.inject.spi.InjectionTarget;
import jakarta.ws.rs.RuntimeType;
+import org.glassfish.jersey.inject.weld.internal.bean.ClassBean;
import org.glassfish.jersey.inject.weld.internal.bean.JerseyBean;
+import org.glassfish.jersey.inject.weld.internal.bean.SupplierClassBean;
+import org.glassfish.jersey.inject.weld.internal.inject.InitializableBinding;
import org.glassfish.jersey.inject.weld.internal.inject.InitializableInstanceBinding;
import org.glassfish.jersey.inject.weld.internal.inject.InitializableSupplierInstanceBinding;
import org.glassfish.jersey.inject.weld.internal.inject.MatchableBinding;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
-import org.glassfish.jersey.internal.inject.Binder;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
import org.glassfish.jersey.internal.inject.Binding;
import org.glassfish.jersey.internal.inject.Bindings;
+import org.glassfish.jersey.internal.inject.ClassBinding;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InstanceBinding;
import org.glassfish.jersey.internal.inject.SupplierClassBinding;
import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
import org.jboss.weld.contexts.CreationalContextImpl;
-import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* Each Client Runtime has a unique CdiClientInjectionManager, which passes proper {@link Binding} to the Weld.
*/
-public class CdiClientInjectionManager extends CdiInjectionManager {
+public final class CdiClientInjectionManager extends CdiInjectionManager {
private Map<InitializableInstanceBinding, InitializableInstanceBinding> clientInstanceBindings = new IdentityHashMap<>();
private Map<InitializableSupplierInstanceBinding, InitializableSupplierInstanceBinding> clientSupplierInstanceBindings
= new IdentityHashMap<>();
private Map<SupplierClassBinding, SupplierClassBinding> clientSupplierClassBinding = new IdentityHashMap<>();
+ private Map<ClassBinding, ClassBinding> clientClassBinding = new IdentityHashMap<>();
- public CdiClientInjectionManager(BeanManager beanManager, Binder bindings) {
- super(beanManager, bindings);
+ CdiClientInjectionManager(BeanManager beanManager, BinderRegisterExtension.MergedBindings bindings) {
+ super(beanManager, bindings, RuntimeType.CLIENT);
}
@Override
public void register(Binding binding) {
if (InstanceBinding.class.isInstance(binding)) {
- final Collection<Binding> preBindings = getBindings().getBindings();
- MatchableBinding.Matching<InitializableInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
- for (Binding preBinding : preBindings) {
- if (InitializableInstanceBinding.class.isInstance(preBinding)) {
- matching = matching.better(((InitializableInstanceBinding) preBinding).matches((InstanceBinding) binding));
- if (matching.isBest()) {
- break;
- }
- }
- }
+// final Collection<Binding> preBindings = getBindings().getBindings();
+// MatchableBinding.Matching<InitializableInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
+// for (Binding preBinding : preBindings) {
+// if (InitializableInstanceBinding.class.isInstance(preBinding)) {
+// matching = matching.better(((InitializableInstanceBinding) preBinding).matches((InstanceBinding) binding));
+// if (matching.isBest()) {
+// break;
+// }
+// }
+// }
+ MatchableBinding.Matching<InitializableInstanceBinding> matching;
+// MatchableBinding.Matching<InitializableInstanceBinding> matching =
+// findPrebinding(InitializableInstanceBinding.class, binding /*, RuntimeType.CLIENT*/);
+// if (matching.matches()) {
+// matching.getBinding().init(((InstanceBinding) binding).getService());
+// return;
+// }
+ matching = findPrebinding(InitializableInstanceBinding.class, binding/*, RuntimeType.SERVER*/);
if (matching.matches()) {
final InitializableInstanceBinding clone = matching.getBinding().clone();
clone.init(((InstanceBinding) binding).getService());
clientInstanceBindings.put(matching.getBinding(), clone);
} else {
- throw new IllegalStateException("Not initialized " + ((InstanceBinding<?>) binding).getService());
- }
- } else if (SupplierInstanceBinding.class.isInstance(binding)) {
- final Collection<Binding> preBindings = getBindings().getBindings();
- MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
- for (Binding preBinding : preBindings) {
- if (InitializableSupplierInstanceBinding.class.isInstance(preBinding)) {
- matching = matching.better(((InitializableSupplierInstanceBinding) preBinding).matchesContracts(binding));
- if (matching.isBest()) {
- break;
- }
+ if (!userBindings.init((InstanceBinding<?>) binding)) {
+ throw new IllegalStateException("Not initialized " + ((InstanceBinding<?>) binding).getService());
}
}
+ } else if (SupplierInstanceBinding.class.isInstance(binding)) {
+// final Collection<Binding> preBindings = getBindings().getBindings();
+// MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
+// for (Binding preBinding : preBindings) {
+// if (InitializableSupplierInstanceBinding.class.isInstance(preBinding)) {
+// matching = matching.better(((InitializableSupplierInstanceBinding) preBinding).matchesContracts(binding));
+// if (matching.isBest()) {
+// break;
+// }
+// }
+// }
+ MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching =
+ findPrebinding(InitializableSupplierInstanceBinding.class, binding);
if (matching.matches()) {
final InitializableSupplierInstanceBinding clone = matching.getBinding().clone();
clone.init(((SupplierInstanceBinding) binding).getSupplier());
@@ -108,6 +125,15 @@
// } else {
// throw new IllegalStateException("Not initialized " + ((SupplierInstanceBinding<?>) binding).getSupplier());
// }
+ } else if (ClassBinding.class.isInstance(binding)) {
+ ClassBinding prebinding = findClassBinding(binding.getImplementationType());
+ if (prebinding == null) {
+ //User registered provider
+ if (!userBindings.init((ClassBinding<?>) binding)) {
+ throw new IllegalStateException("Unexpected");
+ }
+ clientClassBinding.put(prebinding, (ClassBinding) binding);
+ }
}
}
@@ -123,7 +149,22 @@
public SupplierClassBinding getInjectionManagerBinding(SupplierClassBinding binding) {
SupplierClassBinding clientBinding = clientSupplierClassBinding.get(binding);
- return clientBinding;
+ return clientBinding != null ? clientBinding : binding;
+ }
+
+ public ClassBinding getInjectionManagerBinding(ClassBinding binding) {
+ ClassBinding clientBinding = clientClassBinding.get(binding);
+ return clientBinding != null ? clientBinding : binding;
+ }
+
+ @Override
+ protected void lockContext() {
+ ContextSafe.lockContext(this);
+ }
+
+ @Override
+ protected void unlockContext() {
+ ContextSafe.unlock(this);
}
@Override
@@ -145,7 +186,40 @@
@Override
protected boolean isRuntimeTypeBean(Bean<?> bean) {
- return !JerseyBean.class.isInstance(bean) || ((JerseyBean) bean).getRutimeType() == RuntimeType.CLIENT;
+ return !JerseyBean.class.isInstance(bean)
+ || ((JerseyBean) bean).getRutimeType() == RuntimeType.CLIENT
+ || clientInstanceBindings.containsKey(((JerseyBean<?>) bean).getBinding())
+ || clientSupplierInstanceBindings.containsKey(((JerseyBean<?>) bean).getBinding())
+ || isTwoFoldInstantiator((JerseyBean) bean);
}
+ private static boolean isTwoFoldInstantiator(JerseyBean bean) {
+ InjectionTarget injectionTarget = null;
+ if (ClassBean.class.isInstance(bean)) {
+ injectionTarget = ((ClassBean) bean).getInjectionTarget();
+ } else if (SupplierClassBean.class.isInstance(bean)) {
+ injectionTarget = ((SupplierClassBean) bean).getInjectionTarget();
+ }
+
+ if (injectionTarget != null) {
+ if (JerseyInjectionTarget.class.isInstance(injectionTarget)) {
+ JerseyInjectionTarget jerseyInjectionTarget = (JerseyInjectionTarget) injectionTarget;
+ return jerseyInjectionTarget.getTwofoldInstantiator().hasOptionalConstructorInjectionPoint();
+ }
+ }
+ return false;
+ }
+
+ private boolean isInit(JerseyBean bean) {
+ if (InitializableBinding.class.isInstance(bean.getBinding())) {
+ return ((InitializableBinding) bean.getBinding()).isInit();
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public RuntimeType getRuntimeType() {
+ return RuntimeType.CLIENT;
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiInjectionManager.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiInjectionManager.java
index e5759ea..91c0d1e 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiInjectionManager.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/CdiInjectionManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -47,24 +47,27 @@
import org.glassfish.jersey.internal.inject.InstanceBinding;
import org.glassfish.jersey.internal.inject.ServiceHolder;
import org.glassfish.jersey.internal.inject.ServiceHolderImpl;
+import org.glassfish.jersey.internal.inject.SupplierClassBinding;
import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
/**
* Implementation of {@link InjectionManager} used on the server side.
*/
@Singleton
-public class CdiInjectionManager implements InjectionManager {
+class CdiInjectionManager implements InjectionManager {
private final BeanManager beanManager;
- private final Binder bindings;
+ private final BinderRegisterExtension.MergedBindings bindings;
private boolean isCompleted = false;
Set<Class<?>> managedBeans;
+ protected final ProviderBindings userBindings;
// Keeps all binders and bindings added to the InjectionManager during the bootstrap.
- public CdiInjectionManager(BeanManager beanManager, Binder bindings) {
+ CdiInjectionManager(BeanManager beanManager, BinderRegisterExtension.MergedBindings bindings, RuntimeType runtimeType) {
this.beanManager = beanManager;
this.bindings = bindings;
+ userBindings = new ProviderBindings(runtimeType, this);
}
@Override
@@ -73,33 +76,37 @@
return;
}
if (InstanceBinding.class.isInstance(binding)) {
- final Collection<Binding> preBindings = bindings.getBindings();
- MatchableBinding.Matching<InitializableInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
- for (Binding preBinding : preBindings) {
- if (InitializableInstanceBinding.class.isInstance(preBinding)) {
- matching = matching.better(((InitializableInstanceBinding) preBinding).matches((InstanceBinding) binding));
- if (matching.isBest()) {
- break;
- }
- }
- }
+// final Collection<Binding> preBindings = bindings.getBindings();
+// MatchableBinding.Matching<InitializableInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
+// for (Binding preBinding : preBindings) {
+// if (InitializableInstanceBinding.class.isInstance(preBinding)) {
+// matching = matching.better(((InitializableInstanceBinding) preBinding).matches((InstanceBinding) binding));
+// if (matching.isBest()) {
+// break;
+// }
+// }
+// }
+ MatchableBinding.Matching<InitializableInstanceBinding> matching
+ = findPrebinding(InitializableInstanceBinding.class, binding);
if (matching.matches()) {
matching.getBinding().init(((InstanceBinding) binding).getService());
- } else if (findClassBinding(binding.getImplementationType()) == null) {
- throw new IllegalStateException("Not initialized " + ((InstanceBinding<?>) binding).getService());
+ } else /*if (findClassBinding(binding.getImplementationType()) == null) */{
+ throw new IllegalStateException("Could not initialize " + ((InstanceBinding<?>) binding).getService());
}
} else if (SupplierInstanceBinding.class.isInstance(binding)) {
- final Collection<Binding> preBindings = bindings.getBindings();
- MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
- for (Binding preBinding : preBindings) {
- if (InitializableSupplierInstanceBinding.class.isInstance(preBinding)) {
- matching = matching.better(
- ((InitializableSupplierInstanceBinding) preBinding).matches((SupplierInstanceBinding) binding));
- if (matching.isBest()) {
- break;
- }
- }
- }
+// final Collection<Binding> preBindings = bindings.getBindings();
+// MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching = MatchableBinding.Matching.noneMatching();
+// for (Binding preBinding : preBindings) {
+// if (InitializableSupplierInstanceBinding.class.isInstance(preBinding)) {
+// matching = matching.better(
+// ((InitializableSupplierInstanceBinding) preBinding).matches((SupplierInstanceBinding) binding));
+// if (matching.isBest()) {
+// break;
+// }
+// }
+// }
+ MatchableBinding.Matching<InitializableSupplierInstanceBinding> matching =
+ findPrebinding(InitializableSupplierInstanceBinding.class, binding);
if (matching.matches()) {
matching.getBinding().init(((SupplierInstanceBinding) binding).getSupplier());
} else {
@@ -123,9 +130,31 @@
}
}
- private <T> ClassBinding<T> findClassBinding(Class<T> implementationType) {
+ protected <MB extends MatchableBinding> MatchableBinding.Matching<MB>
+ findPrebinding(Class<MB> matchebleBindingClass, Binding binderBinding) {
+ final Collection<Binding> preBindings;
+// if (runtimeType == RuntimeType.SERVER) {
+// preBindings = bindings.getServerBindings();
+// } else if (runtimeType == RuntimeType.CLIENT) {
+// preBindings = bindings.getClientBindings();
+// } else {
+ preBindings = bindings.getBindings();
+// }
+ MatchableBinding.Matching<MB> matching = MatchableBinding.Matching.noneMatching();
+ for (Binding preBinding : preBindings) {
+ if (matchebleBindingClass.isInstance(preBinding)) {
+ matching = matching.better(((MB) preBinding).matching(binderBinding));
+ if (matching.isBest()
+ || (matching.matches() && binderBinding.isForClient())) {
+ break;
+ }
+ }
+ }
+ return matching;
+ }
+
+ protected <T> ClassBinding<T> findClassBinding(Class<T> implementationType) {
final Collection<Binding> preBindings = bindings.getBindings();
- boolean found = false;
for (Binding preBinding : preBindings) {
if (ClassBinding.class.isInstance(preBinding)
&& ((ClassBinding) preBinding).getImplementationType().equals(implementationType)) {
@@ -135,6 +164,17 @@
return null;
}
+ protected <T> SupplierClassBinding<T> findSupplierClassBinding(Class<T> implementationType) {
+ final Collection<Binding> preBindings = bindings.getBindings();
+ for (Binding preBinding : preBindings) {
+ if (SupplierClassBinding.class.isInstance(preBinding)
+ && ((SupplierClassBinding) preBinding).getImplementationType().equals(implementationType)) {
+ return (SupplierClassBinding<T>) preBinding;
+ }
+ }
+ return null;
+ }
+
private boolean isManagedClass(Binding binding) {
return managedBeans != null
&& binding.getImplementationType() != null
@@ -168,13 +208,13 @@
@Override
public <T> T create(Class<T> createMe) {
- Unmanaged.UnmanagedInstance<T> unmanaged = new Unmanaged<>(createMe).newInstance();
+ Unmanaged.UnmanagedInstance<T> unmanaged = new Unmanaged<>(beanManager, createMe).newInstance();
return unmanaged.produce().get();
}
@Override
public <T> T createAndInitialize(Class<T> createMe) {
- Unmanaged.UnmanagedInstance<T> unmanaged = new Unmanaged<>(createMe).newInstance();
+ Unmanaged.UnmanagedInstance<T> unmanaged = new Unmanaged<>(beanManager, createMe).newInstance();
return unmanaged.produce()
.inject()
.postConstruct()
@@ -192,15 +232,18 @@
}
CreationalContext<?> ctx = createCreationalContext(bean);
+ lockContext();
T reference = (T) beanManager.getReference(bean, contractOrImpl, ctx);
+ unlockContext();
- int rank = 1;
+ int rank = 0;
if (bean instanceof JerseyBean) {
rank = ((JerseyBean) bean).getRank();
}
result.add(new ServiceHolderImpl<>(reference, (Class<T>) bean.getBeanClass(), bean.getTypes(), rank));
}
+ result.addAll(userBindings.getServiceHolders(contractOrImpl));
return result;
}
@@ -220,7 +263,7 @@
}
@SuppressWarnings("unchecked")
- protected <T> T getInstanceInternal(Type contractOrImpl, Annotation... qualifiers) {
+ protected <T> T getInstanceInternal(Type contractOrImpl, Annotation... qualifiers) {
// if (contractOrImpl.getTypeName().contains("HelloResource")) {
// T t = (T) CDI.current().select((Class) contractOrImpl, qualifiers).get();
// try {
@@ -242,11 +285,22 @@
final Iterator<?> beansIterator = beans.iterator();
Bean<?> bean = (Bean<?>) beansIterator.next();
- while (beansIterator.hasNext() && !JerseyBean.class.isInstance(bean) && !isRuntimeTypeBean(bean)) {
- bean = (Bean<?>) beansIterator.next(); // prefer Jersey binding
+ boolean isRuntimeType = false;
+ while (!(isRuntimeType = isRuntimeTypeBean(bean))) {
+ if (beansIterator.hasNext()) {
+ bean = (Bean<?>) beansIterator.next(); // prefer Jersey binding
+ } else {
+ break;
+ }
+ }
+ if (!isRuntimeType) {
+ throw new IllegalStateException("Bean for type " + contractOrImpl + " not found");
}
CreationalContext<T> ctx = createCreationalContext((Bean<T>) bean);
- return (T) beanManager.getReference(bean, contractOrImpl, ctx);
+ lockContext();
+ T t = (T) beanManager.getReference(bean, contractOrImpl, ctx);
+ unlockContext();
+ return t;
}
@Override
@@ -286,10 +340,16 @@
public <T> List<T> getAllInstances(Type contractOrImpl) {
List<T> result = new ArrayList<>();
for (Bean<?> bean : beanManager.getBeans(contractOrImpl)) {
+ if (!isRuntimeTypeBean(bean)) {
+ continue;
+ }
CreationalContext<?> ctx = createCreationalContext(bean);
+ lockContext();
Object reference = beanManager.getReference(bean, contractOrImpl, ctx);
+ unlockContext();
result.add((T) reference);
}
+ result.addAll(userBindings.getServices(contractOrImpl));
return result;
}
@@ -304,6 +364,12 @@
injectionTarget.inject(instance, creationalContext);
}
+ protected void lockContext() {
+ }
+
+ protected void unlockContext() {
+ }
+
@Override
public void preDestroy(Object preDestroyMe) {
}
@@ -338,7 +404,7 @@
return false;
}
- protected Binder getBindings() {
+ protected BinderRegisterExtension.MergedBindings getBindings() {
return bindings;
}
@@ -361,7 +427,8 @@
* @return true iff the given bean is not a Jersey Bean or the Jersey Bean is of the proper {@code RuntimeType}.
*/
protected boolean isRuntimeTypeBean(Bean<?> bean) {
- return !JerseyBean.class.isInstance(bean) || ((JerseyBean) bean).getRutimeType() == RuntimeType.SERVER;
+ return !JerseyBean.class.isInstance(bean)
+ || ((JerseyBean) bean).getRutimeType() == RuntimeType.SERVER;
}
@Override
@@ -375,4 +442,9 @@
// TODO: Used only in legacy CDI integration.
throw new UnsupportedOperationException();
}
+
+ @Override
+ public RuntimeType getRuntimeType() {
+ return RuntimeType.SERVER;
+ }
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ClientBootstrapPreinitialization.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ClientBootstrapPreinitialization.java
index c748f6c..215e836 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ClientBootstrapPreinitialization.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ClientBootstrapPreinitialization.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -16,19 +16,9 @@
package org.glassfish.jersey.inject.weld.internal.managed;
-import jakarta.inject.Inject;
-import jakarta.inject.Provider;
import jakarta.ws.rs.RuntimeType;
-import jakarta.ws.rs.client.ClientBuilder;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientRequest;
-import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.inject.weld.spi.BootstrapPreinitialization;
-import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.internal.inject.AbstractBinder;
-import org.glassfish.jersey.internal.inject.ReferencingFactory;
-import org.glassfish.jersey.internal.util.collection.Ref;
import java.util.function.Supplier;
@@ -44,8 +34,8 @@
return;
}
- ClientConfig config = new ClientConfig();
- JerseyClient client = (JerseyClient) ClientBuilder.newClient(config);
- client.getConfiguration().getClientExecutor();
+// ClientConfig config = new ClientConfig();
+// JerseyClient client = (JerseyClient) ClientBuilder.newClient(config);
+// client.getConfiguration().getClientExecutor();
}
}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ContextSafe.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ContextSafe.java
new file mode 100644
index 0000000..1350b0f
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ContextSafe.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.internal.managed;
+
+public final class ContextSafe {
+
+ private static final ThreadLocal<CdiClientInjectionManager> CURRENT_CONTEXT = new ThreadLocal<>();
+
+ public static void lockContext(CdiClientInjectionManager current) {
+ CURRENT_CONTEXT.set(current);
+ }
+
+ public static CdiClientInjectionManager get() {
+ return CURRENT_CONTEXT.get();
+ }
+
+ public static void unlock(CdiClientInjectionManager locked) {
+ CdiClientInjectionManager ctx = CURRENT_CONTEXT.get();
+ if (ctx != locked) {
+ throw new IllegalStateException("The CreationalContext safe has been compromised");
+ }
+ CURRENT_CONTEXT.remove();
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderBindings.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderBindings.java
new file mode 100644
index 0000000..16b39d0
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderBindings.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.internal.managed;
+
+import org.glassfish.jersey.inject.weld.internal.inject.ClassListBinding;
+import org.glassfish.jersey.inject.weld.internal.inject.InstanceListBinding;
+import org.glassfish.jersey.internal.inject.ClassBinding;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.InstanceBinding;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.client.RxInvokerProvider;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.ReaderInterceptor;
+import jakarta.ws.rs.ext.WriterInterceptor;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class ProviderBindings {
+ private final Map<Type, InstanceListBinding<?>> userInstanceBindings = new HashMap<>();
+ private final Map<Type, ClassListBinding<?>> userClassBindings = new HashMap<>();
+ private final InjectionManager injectionManager;
+
+ ProviderBindings(RuntimeType runtimeType, InjectionManager injectionManager) {
+ this.injectionManager = injectionManager;
+
+ if (runtimeType == RuntimeType.CLIENT) {
+ init(ClientRequestFilter.class);
+ init(ClientResponseFilter.class);
+ init(RxInvokerProvider.class);
+ } else if (runtimeType == RuntimeType.SERVER) {
+ init(ContainerResponseFilter.class);
+ init(ContainerRequestFilter.class);
+ init(DynamicFeature.class);
+ }
+ init(ParamConverterProvider.class);
+ init(WriterInterceptor.class);
+ init(ReaderInterceptor.class);
+ init(MessageBodyReader.class);
+ init(MessageBodyWriter.class);
+ }
+
+ private <T> void init(Class<T> contract) {
+ userInstanceBindings.put(contract, new InstanceListBinding<T>(contract));
+ userClassBindings.put(contract, new ClassListBinding<T>(contract, injectionManager));
+ }
+
+ boolean init(InstanceBinding<?> userBinding) {
+ boolean init = false;
+ for (Type contract : userBinding.getContracts()) {
+ InstanceListBinding<?> binding = userInstanceBindings.get(contract);
+ if (binding != null) {
+ init = true;
+ binding.init(userBinding);
+ break;
+ }
+ }
+ return init;
+ }
+
+ boolean init(ClassBinding<?> userBinding) {
+ boolean init = false;
+ for (Type contract : userBinding.getContracts()) {
+ ClassListBinding<?> binding = userClassBindings.get(contract);
+ if (binding != null) {
+ init = true;
+ binding.init(userBinding);
+ break;
+ }
+ }
+ return init;
+ }
+
+ <T> List<ServiceHolder<T>> getServiceHolders(Type contract) {
+ List<ServiceHolder<T>> list = new ArrayList<>();
+
+ InstanceListBinding<T> instanceBinding = (InstanceListBinding<T>) userInstanceBindings.get(contract);
+ if (instanceBinding != null) {
+ list.addAll(instanceBinding.getServiceHolders());
+ }
+
+ ClassListBinding<T> classBinding = (ClassListBinding<T>) userClassBindings.get(contract);
+ if (classBinding != null) {
+ list.addAll(classBinding.getServiceHolders());
+ }
+
+ return list;
+ }
+
+ <T> List<T> getServices(Type contract) {
+ List<T> list = new ArrayList<>();
+
+ InstanceListBinding<T> instanceBinding = (InstanceListBinding<T>) userInstanceBindings.get(contract);
+ if (instanceBinding != null) {
+ list.addAll(instanceBinding.getServices());
+ }
+
+ ClassListBinding<T> classBinding = (ClassListBinding<T>) userClassBindings.get(contract);
+ if (classBinding != null) {
+ list.addAll(classBinding.getServices());
+ }
+
+ return list;
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
index 826c52f..4cc7b98 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
@@ -1,6 +1,6 @@
/*
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 Contributors to the Eclipse Foundation
- * 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
@@ -51,9 +51,6 @@
import org.glassfish.jersey.model.internal.CommonConfig;
import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.process.internal.RequestScoped;
-import org.glassfish.jersey.server.wadl.WadlFeature;
-import org.glassfish.jersey.server.wadl.processor.OptionsMethodProcessor;
-import org.glassfish.jersey.server.wadl.processor.WadlModelProcessor;
import org.glassfish.jersey.servlet.WebConfig;
import org.glassfish.jersey.servlet.spi.AsyncContextDelegateProvider;
import org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider;
@@ -558,7 +555,7 @@
// binder.bind(ChunkedResponseWriter.class).to(MessageBodyWriter.class).in(Singleton.class);
// binder.bind(JsonWithPaddingInterceptor.class).to(WriterInterceptor.class).in(Singleton.class);
- if (runtimeType == RuntimeType.SERVER) {
+ if (runtimeType == null /*RuntimeType.SERVER*/) {
// new ApplicationHandler(new ResourceConfig());
//grizzly
@@ -597,29 +594,29 @@
final ServletConfig servletConfig = webConfig.getServletConfig();
binder.bindFactory(() -> servletConfig).to(ServletConfig.class).in(Singleton.class);
- // WADL TODO put to a proper module
- try {
- new WadlFeature().configure(new PreinitializationFeatureContext(binder) {
- @Override
- public FeatureContext register(Class<?> componentClass) {
- if (WadlModelProcessor.class.isAssignableFrom(componentClass)) {
- super.register(WadlModelProcessor.OptionsHandler.class);
- }
- super.register(componentClass);
- return this;
- }
- });
- } catch (Exception e) {
-
- }
- try {
- Class[] classes = OptionsMethodProcessor.class.getDeclaredClasses();
- for (Class clz : classes) {
- binder.bindAsContract(clz);
- }
- } catch (Exception e) {
-
- }
+// // WADL TODO put to a proper module
+// try {
+// new WadlFeature().configure(new PreinitializationFeatureContext(binder) {
+// @Override
+// public FeatureContext register(Class<?> componentClass) {
+// if (WadlModelProcessor.class.isAssignableFrom(componentClass)) {
+// super.register(WadlModelProcessor.OptionsHandler.class);
+// }
+// super.register(componentClass);
+// return this;
+// }
+// });
+// } catch (Exception e) {
+//
+// }
+// try {
+// Class[] classes = OptionsMethodProcessor.class.getDeclaredClasses();
+// for (Class clz : classes) {
+// binder.bindAsContract(clz);
+// }
+// } catch (Exception e) {
+//
+// }
}
//
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/managed/CdiInjectionManagerFactory.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/managed/CdiInjectionManagerFactory.java
index ad7ac01..12d20bc 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/managed/CdiInjectionManagerFactory.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/managed/CdiInjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,6 +19,7 @@
import jakarta.annotation.Priority;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Configuration;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
@@ -34,11 +35,16 @@
public class CdiInjectionManagerFactory extends CdiInjectionManagerFactoryBase implements InjectionManagerFactory {
@Override
- // TODO deprecate this in favor of #create(Object parent, RuntimeType runtimeType)
+ @Deprecated
public InjectionManager create(Object parent) {
return create(parent, getRuntimeType());
}
+ @Override
+ public InjectionManager create(Object parent, Configuration configuration) {
+ return create(parent, configuration.getRuntimeType());
+ }
+
/**
* Create injectionManager for {@link RuntimeType#CLIENT or get the existing injection manager for the server}
* @param parent Parent injection manager. Not used in this InjectionManagerFactory.
@@ -62,7 +68,7 @@
}
}
- // TODO refactor to call InjectionManagerFactory#create(Object, RuntimeType);
+ @Deprecated
private static RuntimeType getRuntimeType() {
Exception e = new RuntimeException();
for (StackTraceElement element : e.getStackTrace()) {
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/ClientTestParent.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/ClientTestParent.java
new file mode 100644
index 0000000..beb75bd
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/ClientTestParent.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024 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.inject.weld;
+
+import org.glassfish.jersey.internal.inject.Injections;
+import org.junit.jupiter.api.BeforeEach;
+
+import jakarta.ws.rs.RuntimeType;
+
+public class ClientTestParent extends TestParent {
+ @BeforeEach
+ public void init() {
+ injectionManager = Injections.createInjectionManager(RuntimeType.CLIENT);
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/TestParent.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/TestParent.java
new file mode 100644
index 0000000..b89a179
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/TestParent.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021, 2024 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.inject.weld;
+
+import jakarta.enterprise.inject.se.SeContainer;
+import jakarta.enterprise.inject.se.SeContainerInitializer;
+
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.Injections;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+
+import java.util.List;
+
+public class TestParent {
+ protected static SeContainer container;
+ protected InjectionManager injectionManager;
+
+ @BeforeAll
+ public static void setup() {
+ SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
+ container = containerInitializer.initialize();
+ }
+
+ @BeforeEach
+ public void init() {
+ injectionManager = Injections.createInjectionManager();
+ }
+
+ @AfterAll
+ public static void tearDown() throws Exception {
+ container.close();
+ }
+
+ protected <T> void assertOneInstance(Class<T> type, String implementationName) {
+ Assertions.assertEquals(1, injectionManager.getAllInstances(type).size());
+ Assertions.assertEquals(1, injectionManager.getAllServiceHolders(type).size());
+ T provider = injectionManager.getInstance(type);
+ Assertions.assertNotNull(provider);
+ Assertions.assertTrue(provider.getClass().getName().contains(implementationName),
+ "The provider name was " + provider.getClass().getName() + " but expected was " + implementationName);
+ }
+
+ protected <T> void assertMultiple(Class<T> type, int minCount, String... implementationNames) {
+ assertMultiple(injectionManager, type, minCount, implementationNames);
+ }
+
+ public static <T> void assertMultiple(
+ InjectionManager injectionManager, Class<T> type, int minCount, String... implementationNames) {
+ List<T> instances = injectionManager.getAllInstances(type);
+ Assertions.assertTrue(instances.size() >= minCount, type.getSimpleName() + " instances " + instances.size());
+ for (String implName : implementationNames) {
+ Assertions.assertTrue(instances.stream().anyMatch(i -> i.getClass().getSimpleName().equals(implName)),
+ implName + " was not found among the instances");
+ }
+
+ List<ServiceHolder<T>> holders = injectionManager.getAllServiceHolders(type);
+ Assertions.assertTrue(holders.size() >= minCount, type.getSimpleName() + " service holders " + instances.size());
+ for (String implName : implementationNames) {
+ Assertions.assertTrue(holders.stream().anyMatch(h -> h.getInstance().getClass().getSimpleName().equals(implName)),
+ implName + " was not found among the service holders");
+ }
+ }
+
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientBindingsTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientBindingsTest.java
new file mode 100644
index 0000000..4b618d8
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientBindingsTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.binder.client;
+
+import org.glassfish.jersey.client.ClientBootstrapBag;
+import org.glassfish.jersey.client.ClientBootstrapPreinitialization;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.inject.ParameterUpdaterProvider;
+import org.glassfish.jersey.client.internal.inject.ParameterUpdaterConfigurator;
+import org.glassfish.jersey.inject.weld.ClientTestParent;
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.internal.ContextResolverFactory;
+import org.glassfish.jersey.internal.ExceptionMapperFactory;
+import org.glassfish.jersey.internal.JaxrsProviders;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+import org.glassfish.jersey.internal.spi.AutoDiscoverable;
+import org.glassfish.jersey.message.MessageBodyWorkers;
+import org.glassfish.jersey.message.internal.MessageBodyFactory;
+import org.glassfish.jersey.spi.ContextResolvers;
+import org.glassfish.jersey.spi.ExceptionMappers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Providers;
+import java.util.List;
+
+public class ClientBindingsTest extends ClientTestParent {
+ @Test
+ void testConfigurationInjection() {
+ injectionManager.completeRegistration();
+ new ClientBootstrapPreinitialization().preregister(RuntimeType.CLIENT, injectionManager);
+ assertOneInstance(Configuration.class, "ClientConfig$State");
+ }
+
+ @Test
+ void testParamConverterProvider() {
+ injectionManager.completeRegistration();
+ // new ParamConverterConfigurator().init(injectionManager, (BootstrapBag) null); requires Configuration
+ new ClientBootstrapPreinitialization().preregister(RuntimeType.CLIENT, injectionManager);
+ assertOneInstance(ParamConverterProvider.class, "AggregatedProvider");
+ }
+
+ @Test
+ void testParameterUpdaterProvider() {
+ injectionManager.completeRegistration();
+ new ParameterUpdaterConfigurator().init(injectionManager, new ClientBootstrapBag());
+ assertOneInstance(ParameterUpdaterProvider.class, "ParameterUpdaterFactory");
+ }
+
+ @Test
+ void testContextResolvers() {
+ injectionManager.completeRegistration();
+
+ ClientBootstrapBag cbb = new ClientBootstrapBag();
+ cbb.setConfiguration(new ClientConfig());
+ new ContextResolverFactory.ContextResolversConfigurator().init(injectionManager, cbb);
+ assertOneInstance(ContextResolvers.class, "ContextResolverFactory");
+ }
+
+ @Test
+ void testExceptionMappers() {
+ injectionManager.completeRegistration();
+
+ ClientBootstrapBag cbb = new ClientBootstrapBag();
+ cbb.setConfiguration(new ClientConfig());
+ new ExceptionMapperFactory.ExceptionMappersConfigurator().init(injectionManager, cbb);
+ assertOneInstance(ExceptionMappers.class, "ExceptionMapperFactory");
+ }
+
+ @Test
+ void testProviders() {
+ injectionManager.completeRegistration();
+ new JaxrsProviders.ProvidersConfigurator().init(injectionManager, (BootstrapBag) null);
+ assertOneInstance(Providers.class, "JaxrsProviders");
+ }
+
+ @Test
+ void testAutoDiscoverable() {
+ injectionManager.completeRegistration();
+ // new AutoDiscoverableConfigurator(RuntimeType.CLIENT).init(injectionManager, new ClientBootstrapBag()); config
+ new ClientBootstrapPreinitialization().preregister(RuntimeType.CLIENT, injectionManager);
+ assertMultiple(AutoDiscoverable.class, 2, "LoggingFeatureAutoDiscoverable");
+ }
+
+ @Test
+ void testMessageBodyWorkers() {
+ injectionManager.completeRegistration();
+ new ClientBootstrapPreinitialization().preregister(RuntimeType.CLIENT, injectionManager);
+ assertOneInstance(MessageBodyWorkers.class, "MessageBodyFactory");
+ }
+
+ @Test
+ void clientOnlyInstancesTest() {
+ injectionManager.completeRegistration();
+ List<ClientOnlyPreinitialization.ClientOnlyInterface> instances =
+ injectionManager.getAllInstances(ClientOnlyPreinitialization.ClientOnlyInterface.class);
+ Assertions.assertEquals(2, instances.size());
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassA.class)));
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassB.class)));
+ }
+
+ @Test
+ void clientOnlyServiceHoldersTest() {
+ injectionManager.completeRegistration();
+ List<ServiceHolder<ClientOnlyPreinitialization.ClientOnlyInterface>> instances =
+ injectionManager.getAllServiceHolders(ClientOnlyPreinitialization.ClientOnlyInterface.class);
+ Assertions.assertEquals(2, instances.size());
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getInstance().getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassA.class)));
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getInstance().getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassB.class)));
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientOnlyPreinitialization.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientOnlyPreinitialization.java
new file mode 100644
index 0000000..0660a4c
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/ClientOnlyPreinitialization.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.binder.client;
+
+import org.glassfish.jersey.innate.BootstrapPreinitialization;
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+
+import jakarta.ws.rs.RuntimeType;
+
+public class ClientOnlyPreinitialization implements BootstrapPreinitialization {
+ public static interface ClientOnlyInterface {
+
+ }
+ public static class ClientOnlyClassA implements ClientOnlyInterface {
+
+ }
+ public static class ClientOnlyClassB implements ClientOnlyInterface {
+
+ }
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager injectionManager) {
+ injectionManager.register(new AbstractBinder() {
+ @Override
+ protected void configure() {
+ bind(ClientOnlyClassA.class).to(ClientOnlyInterface.class);
+ bind(ClientOnlyClassB.class).to(ClientOnlyInterface.class);
+ }
+ });
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/CustomProviderTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/CustomProviderTest.java
new file mode 100644
index 0000000..4d63204
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/CustomProviderTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.binder.client;
+
+import org.glassfish.jersey.inject.weld.ClientTestParent;
+import org.glassfish.jersey.inject.weld.TestParent;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.InjectionManagerSupplier;
+import org.glassfish.jersey.message.internal.ReaderWriter;
+import org.glassfish.jersey.process.internal.RequestScoped;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Entity;
+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.core.Response;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+
+public class CustomProviderTest extends ClientTestParent {
+
+ private static final String URI = "http://somewhere.nevermind:60000";
+
+ public static class POJO {
+ private final String value;
+
+ public POJO(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+ }
+
+ public static class POJOProvider implements MessageBodyReader<POJO>, MessageBodyWriter<POJO> {
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return type == POJO.class;
+ }
+
+ @Override
+ public POJO readFrom(Class<POJO> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ return new POJO(ReaderWriter.readFromAsString(entityStream, mediaType));
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return type == POJO.class;
+ }
+
+ @Override
+ public void writeTo(POJO pojo, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+ throws IOException, WebApplicationException {
+ entityStream.write(pojo.toString().getBytes(StandardCharsets.UTF_8));
+ }
+ }
+
+ @Test
+ void testCustomRequestFilter() {
+ Response r = ClientBuilder.newClient()
+ .register(new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ InjectionManager im = ((InjectionManagerSupplier) requestContext).getInjectionManager();
+ assertMultiple(im, ClientRequestFilter.class, 1, this.getClass().getSimpleName());
+ requestContext.abortWith(Response.ok().build());
+ }})
+ .target(URI).request()
+ .get();
+ r.close();
+ }
+
+ @Test
+ void testCustomMessageBodyReader() {
+ Response r = ClientBuilder.newClient()
+ .register(new POJOProvider())
+ .register(new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ InjectionManager im = ((InjectionManagerSupplier) requestContext).getInjectionManager();
+ assertMultiple(im, MessageBodyReader.class, 1, POJOProvider.class.getSimpleName());
+ requestContext.abortWith(Response.ok().build());
+ }})
+ .target(URI).request()
+ .get();
+ r.close();
+ }
+
+ @Test
+ void testCustomMessageBodyReaderClass() {
+ Response r = ClientBuilder.newClient()
+ .register(POJOProvider.class)
+ .register(new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ InjectionManager im = ((InjectionManagerSupplier) requestContext).getInjectionManager();
+ assertMultiple(im, MessageBodyReader.class, 1, POJOProvider.class.getSimpleName());
+ requestContext.abortWith(Response.ok().build());
+ }})
+ .target(URI).request()
+ .get();
+ r.close();
+ //post(Entity.entity(new POJO("hello"),MediaType.TEXT_PLAIN_TYPE));
+ }
+
+ static class InjectingClientRequestFilter implements ClientRequestFilter {
+ @Inject
+ Configuration configuration;
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ Assertions.assertNotNull(configuration);
+ Assertions.assertTrue(configuration.getClass().getName().contains("ClientConfig$State"));
+ requestContext.abortWith(Response.ok().build());
+ }
+ }
+
+ @Test
+ void testCustomFilterProviderIsInjectable() {
+ try (Response r = ClientBuilder.newClient().register(InjectingClientRequestFilter.class)
+ .target(URI).request().get()) {
+ Assertions.assertEquals(200, r.getStatus());
+ }
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/TestClientRequestFilter.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/TestClientRequestFilter.java
new file mode 100644
index 0000000..f6b4000
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/client/TestClientRequestFilter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023, 2024 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.inject.weld.binder.client;
+
+import org.glassfish.jersey.inject.weld.TestParent;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.InjectionManagerSupplier;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.Provider;
+import java.io.IOException;
+
+@Provider
+//@ApplicationScoped
+public class TestClientRequestFilter implements ClientRequestFilter {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ InjectionManager im = ((InjectionManagerSupplier) requestContext).getInjectionManager();
+ TestParent.assertMultiple(im, ClientRequestFilter.class, 1, CustomProviderTest.POJOProvider.class.getName());
+ requestContext.abortWith(Response.ok().build());
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/common/CoreCommonBindingsTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/common/CoreCommonBindingsTest.java
new file mode 100644
index 0000000..66a4b18
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/common/CoreCommonBindingsTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023, 2024 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.inject.weld.binder.common;
+
+import org.glassfish.jersey.inject.weld.ClientTestParent;
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.message.MessageBodyWorkers;
+import org.glassfish.jersey.message.internal.MessageBodyFactory;
+import org.glassfish.jersey.message.internal.MessagingBinders;
+import org.glassfish.jersey.spi.HeaderDelegateProvider;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import java.util.Collections;
+import java.util.List;
+
+public class CoreCommonBindingsTest extends ClientTestParent {
+
+ @Test
+ public void testProviders() {
+ injectionManager.completeRegistration();
+ injectionManager.register(new MessagingBinders.HeaderDelegateProviders(RuntimeType.CLIENT));
+ assertMultiple(HeaderDelegateProvider.class, 10, "DateProvider");
+ }
+
+ @Test
+ public void testMessageBodyProviders() {
+ injectionManager.completeRegistration();
+ injectionManager.register(new MessagingBinders.MessageBodyProviders(Collections.emptyMap(), RuntimeType.CLIENT));
+ assertMultiple(MessageBodyReader.class, 10, "StringMessageProvider");
+ assertMultiple(MessageBodyWriter.class, 10, "StringMessageProvider");
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ModelProcessorBindingsTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ModelProcessorBindingsTest.java
new file mode 100644
index 0000000..126148b
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ModelProcessorBindingsTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2024 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.inject.weld.binder.server;
+
+import org.glassfish.jersey.inject.weld.TestParent;
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.Bindings;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerConfig;
+import org.glassfish.jersey.server.internal.JerseyResourceContext;
+import org.glassfish.jersey.server.model.ModelProcessor;
+import org.glassfish.jersey.server.wadl.WadlApplicationContext;
+import org.glassfish.jersey.server.wadl.internal.WadlApplicationContextImpl;
+import org.glassfish.jersey.server.wadl.processor.OptionsMethodProcessor;
+import org.glassfish.jersey.server.wadl.processor.WadlModelProcessor;
+import org.junit.jupiter.api.Test;
+
+import jakarta.inject.Singleton;
+import javax.security.auth.login.Configuration;
+import jakarta.ws.rs.container.ResourceContext;
+
+public class ModelProcessorBindingsTest extends TestParent {
+
+ @Test
+ public void testWadlProcessor() {
+ injectionManager.completeRegistration();
+ injectionManager.register(Bindings.service(new OptionsMethodProcessor()).to(ModelProcessor.class));
+// injectionManager.register(new AbstractBinder() {
+// @Override
+// protected void configure() {
+// bind(new WadlModelProcessor()).to(ModelProcessor.class);
+// }
+// });
+ assertMultiple(ModelProcessor.class, 2, WadlModelProcessor.class.getSimpleName(),
+ OptionsMethodProcessor.class.getSimpleName());
+ }
+
+ @Test
+ public void testWadlContext() {
+ injectionManager.register(new AbstractBinder() {
+ @Override
+ protected void configure() {
+ bind(new ResourceConfig()).to(ServerConfig.class).to(Configuration.class).id(1000);
+ bind(new JerseyResourceContext(null, null, null)).to(ResourceContext.class).id(3112);
+ bind(WadlApplicationContextImpl.class).to(WadlApplicationContext.class).in(Singleton.class);
+ }
+ });
+ injectionManager.completeRegistration();
+ assertOneInstance(WadlApplicationContext.class, WadlApplicationContextImpl.class.getSimpleName());
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ServerBindingsTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ServerBindingsTest.java
new file mode 100644
index 0000000..a6a6849
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/binder/server/ServerBindingsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023, 2024 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.inject.weld.binder.server;
+
+import org.glassfish.jersey.inject.weld.TestParent;
+import org.glassfish.jersey.inject.weld.binder.client.ClientOnlyPreinitialization;
+import org.glassfish.jersey.internal.inject.ServiceHolder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+public class ServerBindingsTest extends TestParent {
+ @Test
+ void clientOnlyInstancesTest() {
+ injectionManager.completeRegistration();
+ List<ClientOnlyPreinitialization.ClientOnlyInterface> instances =
+ injectionManager.getAllInstances(ClientOnlyPreinitialization.ClientOnlyInterface.class);
+ Assertions.assertEquals(2, instances.size());
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassA.class)));
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassB.class)));
+ }
+
+ @Test
+ void clientOnlyServiceHoldersTest() {
+ injectionManager.completeRegistration();
+ List<ServiceHolder<ClientOnlyPreinitialization.ClientOnlyInterface>> instances =
+ injectionManager.getAllServiceHolders(ClientOnlyPreinitialization.ClientOnlyInterface.class);
+ Assertions.assertEquals(2, instances.size());
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getInstance().getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassA.class)));
+ Assertions.assertTrue(instances.stream()
+ .anyMatch(p -> p.getInstance().getClass().equals(ClientOnlyPreinitialization.ClientOnlyClassB.class)));
+ }
+}
\ No newline at end of file
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/injector/CachedConstructorAnalyzerTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/injector/CachedConstructorAnalyzerTest.java
index 85bfe56..1b0f4f7 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/injector/CachedConstructorAnalyzerTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/injector/CachedConstructorAnalyzerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,7 +23,6 @@
import jakarta.enterprise.inject.InjectionException;
import jakarta.ws.rs.MatrixParam;
-import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Context;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ClientInstanceInjectionTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ClientInstanceInjectionTest.java
index afb04b8..d7dbfbc 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ClientInstanceInjectionTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ClientInstanceInjectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -21,6 +21,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.RuntimeType;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.inject.weld.managed.CdiInjectionManagerFactory;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.junit.jupiter.api.Assertions;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/DisposableSupplierTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/DisposableSupplierTest.java
index ee96847..7efa92e 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/DisposableSupplierTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/DisposableSupplierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -27,6 +27,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.core.GenericType;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.inject.weld.internal.bean.BeanHelper;
import org.glassfish.jersey.internal.inject.DisposableSupplier;
import org.glassfish.jersey.process.internal.RequestScope;
@@ -346,7 +347,7 @@
/**
* PerLookup fields are not disposed therefore they should never be used as a DisposedSupplier because the field stay in
- * {@link org.glassfish.jersey.inject.weld.bean.SupplierClassBean} forever.
+ * {@link org.glassfish.jersey.inject.weld.internal.bean.SupplierClassBean} forever.
*/
@Test
public void testDisposeComposedObjectWithPerLookupFields() {
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/InjectionManagerTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/InjectionManagerTest.java
index 7be66d9..f3f6dda 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/InjectionManagerTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/InjectionManagerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -20,6 +20,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.RuntimeType;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.inject.weld.managed.CdiInjectionManagerFactory;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.junit.jupiter.api.Assertions;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderInjectionTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderInjectionTest.java
index 42aadeb..d43f11c 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderInjectionTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ProviderInjectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -26,6 +26,7 @@
import jakarta.inject.Provider;
import jakarta.ws.rs.core.Context;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.hamcrest.core.StringStartsWith;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierClassBindingTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierClassBindingTest.java
index 7db2804..e8e9cab 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierClassBindingTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierClassBindingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -27,6 +27,7 @@
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.hamcrest.core.StringStartsWith;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierInstanceBindingTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierInstanceBindingTest.java
index 9c247a9..fe758f8 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierInstanceBindingTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/SupplierInstanceBindingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -28,6 +28,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.core.GenericType;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.hamcrest.core.StringStartsWith;
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestParent.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestParent.java
index e3013fe..e69de29 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestParent.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestParent.java
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.inject.weld.internal.managed;
-
-import jakarta.enterprise.inject.se.SeContainer;
-import jakarta.enterprise.inject.se.SeContainerInitializer;
-import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.internal.inject.Injections;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.BeforeAll;
-
-public class TestParent {
- protected static SeContainer container;
- protected InjectionManager injectionManager;
-
-
- @BeforeAll
- public static void setup() {
- SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
- container = containerInitializer.initialize();
- }
-
- @BeforeEach
- public void init() {
- injectionManager = Injections.createInjectionManager();
- }
-
- @AfterAll
- public static void tearDown() throws Exception {
- container.close();
- }
-
-}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestPreinitialization.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestPreinitialization.java
index b7806c1..6978e2f 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestPreinitialization.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/TestPreinitialization.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 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
@@ -22,10 +22,11 @@
import org.glassfish.jersey.inject.weld.spi.BootstrapPreinitialization;
import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.PerThread;
import org.glassfish.jersey.process.internal.RequestScoped;
-public class TestPreinitialization implements BootstrapPreinitialization {
+public class TestPreinitialization implements BootstrapPreinitialization, org.glassfish.jersey.innate.BootstrapPreinitialization {
@Override
public void register(RuntimeType runtimeType, AbstractBinder binder) {
if (RuntimeType.CLIENT == runtimeType) {
@@ -33,6 +34,7 @@
{
binder.bindFactory(ClientInstanceInjectionTest.InjectableClientServerSupplierClient.class)
.to(ClientInstanceInjectionTest.InjectableClientServer.class);
+ binder.bindAsContract(ClientInstanceInjectionTest.InjectedBean.class);
}
return;
}
@@ -113,4 +115,8 @@
.to(ClientInstanceInjectionTest.InjectableClientServer.class);
}
}
+
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager registrator) {
+ }
}
diff --git a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ThreadScopeTest.java b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ThreadScopeTest.java
index 144c333..4df5aa0 100644
--- a/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ThreadScopeTest.java
+++ b/incubator/cdi-inject-weld/src/test/java/org/glassfish/jersey/inject/weld/internal/managed/ThreadScopeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -25,6 +25,7 @@
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import org.glassfish.jersey.inject.weld.TestParent;
import org.glassfish.jersey.internal.inject.PerThread;
import org.glassfish.jersey.process.internal.RequestScope;
diff --git a/incubator/cdi-inject-weld/src/test/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization b/incubator/cdi-inject-weld/src/test/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
new file mode 100644
index 0000000..f47d280
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/test/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
@@ -0,0 +1,2 @@
+org.glassfish.jersey.inject.weld.binder.client.ClientOnlyPreinitialization
+org.glassfish.jersey.inject.weld.internal.managed.TestPreinitialization
\ No newline at end of file
diff --git a/incubator/injectless-client/src/main/java/org/glassfish/jersey/inject/injectless/NonInjectionManagerFactory.java b/incubator/injectless-client/src/main/java/org/glassfish/jersey/inject/injectless/NonInjectionManagerFactory.java
index 61e6455..b9033f2 100644
--- a/incubator/injectless-client/src/main/java/org/glassfish/jersey/inject/injectless/NonInjectionManagerFactory.java
+++ b/incubator/injectless-client/src/main/java/org/glassfish/jersey/inject/injectless/NonInjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024 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
@@ -22,6 +22,7 @@
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.ws.rs.ConstrainedTo;
+import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.RuntimeType;
@@ -44,4 +45,9 @@
public InjectionManager create(Object parent) {
return new NonInjectionManager(false);
}
+
+ @Override
+ public InjectionManager create(Object parent, Configuration configuration) {
+ return create(parent); // RuntimeType is always client
+ }
}
diff --git a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/CdiSeInjectionManagerFactory.java b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/CdiSeInjectionManagerFactory.java
index e1c79a0..128e40f 100644
--- a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/CdiSeInjectionManagerFactory.java
+++ b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/CdiSeInjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,6 +17,7 @@
package org.glassfish.jersey.inject.cdi.se;
import jakarta.annotation.Priority;
+import jakarta.ws.rs.core.Configuration;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InjectionManagerFactory;
@@ -33,4 +34,9 @@
public InjectionManager create(Object parent) {
return new CdiSeInjectionManager();
}
+
+ @Override
+ public InjectionManager create(Object parent, Configuration configuration) {
+ return create(parent); // no configuration used at the moment
+ }
}
diff --git a/inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/Hk2InjectionManagerFactory.java b/inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/Hk2InjectionManagerFactory.java
index ce30dd1..9a8dcf0 100644
--- a/inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/Hk2InjectionManagerFactory.java
+++ b/inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/Hk2InjectionManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,6 +19,7 @@
import java.security.AccessController;
import jakarta.annotation.Priority;
+import jakarta.ws.rs.core.Configuration;
import org.glassfish.jersey.internal.inject.Bindings;
import org.glassfish.jersey.internal.inject.InjectionManager;
@@ -73,6 +74,11 @@
return initInjectionManager(getStrategy().createInjectionManager(parent));
}
+ @Override
+ public InjectionManager create(Object parent, Configuration configuration) {
+ return create(parent); // ignore configuration for HK2
+ }
+
/**
* Check HK2 Strategy property {@link #HK2_INJECTION_MANAGER_STRATEGY} and returns {@code true} if the current HK2 Strategy is
* "immediate".
diff --git a/media/sse/src/main/java/org/glassfish/jersey/media/sse/internal/SseBootstrapPreinitialization.java b/media/sse/src/main/java/org/glassfish/jersey/media/sse/internal/SseBootstrapPreinitialization.java
new file mode 100644
index 0000000..19970b2
--- /dev/null
+++ b/media/sse/src/main/java/org/glassfish/jersey/media/sse/internal/SseBootstrapPreinitialization.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024 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.media.sse.internal;
+
+import org.glassfish.jersey.innate.BootstrapPreinitialization;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+
+import jakarta.ws.rs.RuntimeType;
+
+public class SseBootstrapPreinitialization implements BootstrapPreinitialization {
+ @Override
+ public void preregister(RuntimeType runtimeType, InjectionManager injectionManager) {
+ if (runtimeType == RuntimeType.SERVER) {
+ injectionManager.register(new SseBinder());
+ }
+ }
+}
diff --git a/media/sse/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization b/media/sse/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
new file mode 100644
index 0000000..d41c8b7
--- /dev/null
+++ b/media/sse/src/main/resources/META-INF/services/org.glassfish.jersey.innate.BootstrapPreinitialization
@@ -0,0 +1 @@
+org.glassfish.jersey.media.sse.internal.SseBootstrapPreinitialization
\ No newline at end of file
diff --git a/test-framework/core/src/main/java/org/glassfish/jersey/test/JerseySingleContainerTest.java b/test-framework/core/src/main/java/org/glassfish/jersey/test/JerseySingleContainerTest.java
new file mode 100644
index 0000000..252bdfd
--- /dev/null
+++ b/test-framework/core/src/main/java/org/glassfish/jersey/test/JerseySingleContainerTest.java
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2010, 2024 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.test;
+
+import org.glassfish.jersey.Beta;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.internal.ServiceFinder;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.test.spi.TestContainer;
+import org.glassfish.jersey.test.spi.TestContainerException;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeEach;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+/**
+ * Parent class for testing JAX-RS and Jersey-based applications using Jersey test framework.
+ * <p>
+ * At construction this class will obtain a {@link TestContainerFactory
+ * test container factory} implementation.
+ * </p>
+ * <p>
+ * Before each test method in an extending class is run the test container factory is used to obtain
+ * a configured {@link TestContainer test container}.
+ * Then the {@link TestContainer#start()} method is invoked on the configured test container. After each test method
+ * has run, the {@link TestContainer#stop()} method is invoked on the test container. Stopped test container
+ * generally shouldn't be again started for another test, rather a new test container should be created.
+ * Every test method in the {@code JerseyTest} subclass can invoke the {@link #client()} to obtain a JAX-RS
+ * {@link Client}, from which {@link WebTarget} instances can be created
+ * to send arbitrary requests.
+ * Also, one of the {@code target} methods ({@link #target()} or {@link #target(String)}) may be invoked to obtain
+ * a JAX-RS {@link WebTarget} instances from which requests can be sent to and responses
+ * received from the Web application under test.
+ * </p>
+ * <p>
+ * If a test container factory is not explicitly declared using the appropriate constructor
+ * (see {@link #JerseySingleContainerTest(TestContainerFactory)}) or by overriding the {@link #getTestContainerFactory()} method,
+ * then a default test container factory will be obtained as follows:
+ * <ol>
+ * <li>
+ * If a system property <tt>{@value TestProperties#CONTAINER_FACTORY}</tt> is set
+ * and the value is a fully qualified class name of a class that extends from {@code TestContainerFactory}
+ * then the test container factory used by default will be an instance of that class.
+ * A {@link TestContainerException} will be thrown if the class cannot be loaded or instantiated.
+ * </li>
+ * <li>
+ * Otherwise, {@code META-INF/services} locations on the class path will be scanned for implementation providers
+ * of {@code TestContainerFactory} SPI. If a single implementation is found, it will be used. If multiple implementations
+ * are found, the default <tt>{@value TestProperties#CONTAINER_FACTORY}</tt> implementation
+ * will be selected if present, otherwise the first found implementation will be selected and a warning message will be logged.
+ * </li>
+ * <li>
+ * If no {@code TestContainerFactory} has been selected in the steps above, Jersey test framework will try to
+ * instantiate the default test container factory implementation (
+ * <tt>{@value TestProperties#DEFAULT_CONTAINER_FACTORY}</tt>) directly.
+ * A {@link TestContainerException} will be thrown if this class cannot be loaded or instantiated.
+ * </li>
+ * </ol>
+ * </p>
+ * <p>
+ * The test container is configured by a {@link DeploymentContext} that is either provided
+ * by subclass or automatically created by {@code JerseyTest} based on the provided JAX-RS / Jersey {@code Application}
+ * class or instance to be tested. A {@link TestContainerException} will be thrown if the configured test container
+ * factory cannot support the deployment context type.
+ * Two deployment context are provided:
+ * <ol>
+ * <li>A basic deployment context, of type {@link DeploymentContext}, compatible with all test containers that are not
+ * based on Servlet deployment model.</li>
+ * <li>A Servlet-based deployment context, of type {@link ServletDeploymentContext}, compatible with Servlet-based test
+ * containers.</li>
+ * </ol>
+ * </p>
+ *
+ * @author Paul Sandoz
+ * @author Srinivas Bhimisetty
+ * @author Pavel Bucek
+ * @author Michal Gajdos
+ * @author Marek Potociar
+ */
+@Beta
+public abstract class JerseySingleContainerTest {
+
+ private static final ThreadLocal<JerseySingleContainerTest> INSTANCE = new ThreadLocal<>();
+
+ private static final Logger LOGGER = Logger.getLogger(JerseySingleContainerTest.class.getName());
+
+ /**
+ * Holds the test container factory class to be used for running the tests by default
+ * (if testContainerFactory has not been set).
+ * This static field is initialized in {@link #getDefaultTestContainerFactory()} method
+ * and is reused by any instances of {@code JerseyTest} that are subsequently run.
+ * This is done to optimize the number of TestContainerFactory service provider look-ups
+ * and class loading.
+ */
+ private static Class<? extends TestContainerFactory> defaultTestContainerFactoryClass;
+
+ /**
+ * Configured deployment context for the tested application.
+ */
+ private final DeploymentContext context;
+
+ /**
+ * The test container factory which creates an instance of the test container
+ * on which the tests would be run.
+ */
+ private TestContainerFactory testContainerFactory;
+
+ /**
+ * The test container on which the tests would be run.
+ */
+ private TestContainer testContainer;
+
+ private final AtomicReference<Client> client = new AtomicReference<>(null);
+
+ /**
+ * JerseyTest property bag that can be used to configure the test behavior.
+ * These properties can be overridden with a system property.
+ */
+ private final Map<String, String> propertyMap = new HashMap<>();
+
+ /**
+ * JerseyTest forced property bag that can be used to configure the test behavior.
+ * These property cannot be overridden with a system property.
+ */
+ private final Map<String, String> forcedPropertyMap = new HashMap<>();
+
+ private JerseyTestLogHandler logHandler;
+ private final Map<Logger, Level> logLevelMap = new IdentityHashMap<>();
+ private final AtomicInteger activeThreadCount = new AtomicInteger(0);
+
+ /**
+ * Initialize JerseyTest instance.
+ * <p>
+ * This constructor can be used from an extending subclass.
+ * <p>
+ * When this constructor is used, the extending concrete subclass must implement one of the
+ * {@link #configure()} or {@link #configureDeployment()} methods to provide the tested application
+ * configuration and deployment context.
+ * </p>
+ */
+ public JerseySingleContainerTest() {
+ // Note: this must be the first call in the constructor to allow setting config
+ // properties (especially around logging) in the configure() or configureDeployment()
+ // method overridden in subclass, otherwise the properties set in the subclass would
+ // not be set soon enough
+ this.context = configureDeployment();
+ this.testContainerFactory = getTestContainerFactory();
+ }
+
+ /**
+ * Initialize JerseyTest instance and specify the test container factory to be used by this test.
+ * <p>
+ * This constructor can be used from an extending subclass.
+ * <p>
+ * When this constructor is used, the extending concrete subclass must implement one of the
+ * {@link #configure()} or {@link #configureDeployment()} methods to provide the tested application
+ * configuration and deployment context.
+ * </p>
+ *
+ * @param testContainerFactory the test container factory to use for testing.
+ */
+ public JerseySingleContainerTest(final TestContainerFactory testContainerFactory) {
+ // Note: this must be the first call in the constructor to allow setting config
+ // properties (especially around logging) in the configure() or configureDeployment()
+ // method overridden in subclass, otherwise the properties set in the subclass would
+ // not be set soon enough
+ this.context = configureDeployment();
+ this.testContainerFactory = testContainerFactory;
+ }
+
+ /**
+ * Initialize JerseyTest instance.
+ * <p>
+ * This constructor can be used from an extending subclass.
+ * <p>
+ * When this constructor is used, the extending concrete subclass must implement one of the
+ * {@link #configure()} or {@link #configureDeployment()} methods are ignored.
+ * </p>
+ * <p>
+ * Please note that when this constructor is used, recording of startup logs as well as configuring
+ * other {@code JerseyTest} properties and features may not work properly. While using this constructor
+ * should generally be avoided, in certain scenarios it may be necessary to use this constructor.
+ * (E.g. when running parameterized tests in which application is created based on test parameters
+ * passed in by JUnit framework via test constructor - in such case it is not possible to propagate
+ * the necessary information to one of the overridden {@code JerseyTest.configure...} methods).
+ * </p>
+ *
+ * @param jaxrsApplication tested application.
+ */
+ public JerseySingleContainerTest(final Application jaxrsApplication) {
+ this.context = DeploymentContext.newInstance(jaxrsApplication);
+ this.testContainerFactory = getTestContainerFactory();
+ }
+
+ /**
+ * Return currently used test container to run the tests in. This method can be overridden.
+ *
+ * @return a test container instance or {@code null} if the container is not set.
+ */
+ /* package */ TestContainer getTestContainer() {
+ return testContainer;
+ }
+
+ /**
+ * Returns old test container used to run the tests in and set a new one. This method can be overridden.
+ *
+ * @param testContainer a test container instance or {@code null} it the current test container should be released.
+ * @return old test container instance.
+ */
+ /* package */ TestContainer setTestContainer(final TestContainer testContainer) {
+ final TestContainer old = this.testContainer;
+ this.testContainer = testContainer;
+ return old;
+ }
+
+ private TestContainer createTestContainer(final DeploymentContext context) {
+ return getTestContainerFactory().create(getBaseUri(), context);
+ }
+
+ /**
+ * Programmatically enable a feature with a given name.
+ * Enabling of the feature may be overridden via a system property.
+ *
+ * @param featureName name of the enabled feature.
+ */
+ protected final void enable(final String featureName) {
+ // TODO: perhaps we could reuse the resource config for the test properties?
+ propertyMap.put(featureName, Boolean.TRUE.toString());
+ }
+
+ /**
+ * Programmatically disable a feature with a given name.
+ * Disabling of the feature may be overridden via a system property.
+ *
+ * @param featureName name of the disabled feature.
+ */
+ protected final void disable(final String featureName) {
+ propertyMap.put(featureName, Boolean.FALSE.toString());
+ }
+
+ /**
+ * Programmatically force-enable a feature with a given name.
+ * Force-enabling of the feature cannot be overridden via a system property.
+ * Use with care!
+ *
+ * @param featureName name of the force-enabled feature.
+ */
+ protected final void forceEnable(final String featureName) {
+ forcedPropertyMap.put(featureName, Boolean.TRUE.toString());
+ }
+
+ /**
+ * Programmatically force-disable a feature with a given name.
+ * Force-disabling of the feature cannot be overridden via a system property.
+ * Use with care!
+ *
+ * @param featureName name of the force-disabled feature.
+ */
+ protected final void forceDisable(final String featureName) {
+ forcedPropertyMap.put(featureName, Boolean.FALSE.toString());
+ }
+
+ /**
+ * Programmatically set a value of a property with a given name.
+ * The property value may be overridden via a system property.
+ *
+ * @param propertyName name of the property.
+ * @param value property value.
+ */
+ protected final void set(final String propertyName, final Object value) {
+ set(propertyName, value.toString());
+ }
+
+ /**
+ * Programmatically set a value of a property with a given name.
+ * The property value may be overridden via a system property.
+ *
+ * @param propertyName name of the property.
+ * @param value property value.
+ */
+ protected final void set(final String propertyName, final String value) {
+ propertyMap.put(propertyName, value);
+ }
+
+ /**
+ * Programmatically force-set a value of a property with a given name.
+ * The force-set property value cannot be overridden via a system property.
+ *
+ * @param propertyName name of the property.
+ * @param value property value.
+ */
+ protected final void forceSet(final String propertyName, final String value) {
+ forcedPropertyMap.put(propertyName, value);
+ }
+
+ /**
+ * Check if the Jersey test boolean property (flag) has been set to {@code true}.
+ *
+ * @param propertyName name of the Jersey test boolean property.
+ * @return {@code true} if the test property has been enabled, {@code false} otherwise.
+ */
+ protected final boolean isEnabled(final String propertyName) {
+ return Boolean.valueOf(getProperty(propertyName));
+ }
+
+ private String getProperty(final String propertyName) {
+ if (forcedPropertyMap.containsKey(propertyName)) {
+ return forcedPropertyMap.get(propertyName);
+ }
+
+ final Properties systemProperties = AccessController.doPrivileged(PropertiesHelper.getSystemProperties());
+ if (systemProperties.containsKey(propertyName)) {
+ return systemProperties.getProperty(propertyName);
+ }
+
+ if (propertyMap.containsKey(propertyName)) {
+ return propertyMap.get(propertyName);
+ }
+
+ return null;
+ }
+
+ private static String getSystemProperty(final String propertyName) {
+ final Properties systemProperties = AccessController.doPrivileged(PropertiesHelper.getSystemProperties());
+ return systemProperties.getProperty(propertyName);
+ }
+
+ /**
+ * Create the tested JAX-RS /Jersey application.
+ * <p>
+ * This method may be overridden by subclasses to provide the configured JAX-RS /Jersey application to be tested.
+ * The method may be also used to configure {@code JerseyTest} instance properties.
+ * <p>
+ * Unless {@link #configureDeployment()} method is overridden in the subclass, the {@code configure()} method is invoked
+ * by {@code configureDeployment()} to create default deployment context for the tested application. As such, the method
+ * is invoked in the scope of one of the {@code JerseyTest} constructors.
+ * Default implementation of this method throws {@link UnsupportedOperationException}, so that construction of
+ * {@code JerseyTest} instance fails unless one of the {@code configure()} or {@code configureDeployment()} methods is
+ * overridden in the subclass.
+ * </p>
+ * <p>
+ * Note that since the method is invoked from {@code JerseyTest} constructor, the overriding implementation of the method
+ * must not depend on any subclass fields as those will not be initialized yet when the method is invoked.
+ * </p>
+ * <p>
+ * Also note that in case the {@link #JerseySingleContainerTest(Application)} constructor is used, the method is never
+ * invoked.
+ * </p>
+ *
+ * @return tested JAX-RS /Jersey application.
+ */
+ protected Application configure() {
+ throw new UnsupportedOperationException("The configure method must be implemented by the extending class");
+ }
+
+ /**
+ * Create and configure deployment context for the tested application.
+ * <p>
+ * This method may be overridden by subclasses to provide custom test container deployment context for the tested
+ * application. The method may be also used to configure {@code JerseyTest} instance properties.
+ * <p>
+ * The method is invoked from {@code JerseyTest} constructors to provide deployment context for the tested application.
+ * Default implementation of this method creates
+ * {@link DeploymentContext#newInstance(Application) new deployment context}
+ * using JAX-RS application instance obtained by calling the {@link #configure()} method.
+ * </p>
+ * <p>
+ * Note that since the method is invoked from {@code JerseyTest} constructor, the overriding implementation of the method
+ * must not depend on any subclass fields as those will not be initialized yet when the method is invoked.
+ * </p>
+ * <p>
+ * Also note that in case the {@link #JerseySingleContainerTest(Application)} constructor is used, the method is never
+ * invoked.
+ * </p>
+ *
+ * @return configured deployment context for the tested application.
+ * @since 2.8
+ */
+ protected DeploymentContext configureDeployment() {
+ DeploymentContext.Builder contextBuilder = DeploymentContext.builder(configure());
+ if (getSslContext().isPresent() && getSslParameters().isPresent()) {
+ contextBuilder.ssl(getSslContext().get(), getSslParameters().get());
+ }
+ return contextBuilder.build();
+ }
+
+ /**
+ * Return an instance of {@link TestContainerFactory} class.
+ * <p>
+ * <p>
+ * This method is used only once during {@code JerseyTest} instance construction to retrieve the factory responsible
+ * for providing {@link TestContainer} that will be used to deploy the tested application.
+ * </p>
+ * <p>
+ * A default implementation first searches for the {@code TestContainerFactory} set via
+ * {@link #JerseySingleContainerTest(TestContainerFactory) constructor}, then it looks for a
+ * {@code TestContainerFactory} implementation class name set via
+ * <tt>{@value TestProperties#CONTAINER_FACTORY}</tt> system property with a fallback to
+ * searching for {@code TestContainerFactory} service providers on the class path. At last, if no
+ * {@code TestContainerFactory} has been found, the method attempts to create new default
+ * {@code TestContainerFactory} implementation instance
+ * (<tt>{@value TestProperties#DEFAULT_CONTAINER_FACTORY}</tt>).
+ * </p>
+ * <p>
+ * Alternatively, this method may be overridden to directly provide a custom {@code TestContainerFactory} instance.
+ * Note that since the method is invoked from {@code JerseyTest} constructor, the overriding implementation of the method
+ * must not depend on any subclass fields as those will not be initialized yet when the method is invoked.
+ * </p>
+ *
+ * @return an instance of {@link TestContainerFactory} class.
+ * @throws TestContainerException if the initialization of {@link TestContainerFactory} instance is not successful.
+ */
+ protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
+ if (testContainerFactory == null) {
+ testContainerFactory = getDefaultTestContainerFactory();
+ }
+ return testContainerFactory;
+ }
+
+ /**
+ * Return an optional instance of {@link SSLContext} class.
+ * <p>
+ * <p>
+ * This method is used only once during {@code JerseyTest} instance construction to retrieve the ssl configuration.
+ * By default the ssl configuration is absent, to enable it please override this method and {@link JerseySingleContainerTest#getSslParameters()}
+ * </p>
+ * </p>
+ * @return an optional instance of {@link SSLContext} class.
+ */
+ protected Optional<SSLContext> getSslContext() {
+ return Optional.empty();
+ }
+
+ /**
+ * Return an optional instance of {@link SSLParameters} class.
+ * <p>
+ * <p>
+ * This method is used only once during {@code JerseyTest} instance construction to retrieve the ssl configuration.
+ * By default the ssl configuration is absent, to enable it please override this method and {@link JerseySingleContainerTest#getSslContext()} ()}
+ * </p>
+ * </p>
+ * @return an optional instance of {@link SSLContext} class.
+ */
+ protected Optional<SSLParameters> getSslParameters() {
+ return Optional.empty();
+ }
+
+ private static synchronized TestContainerFactory getDefaultTestContainerFactory() {
+
+ if (defaultTestContainerFactoryClass == null) {
+ final String factoryClassName = getSystemProperty(TestProperties.CONTAINER_FACTORY);
+ if (factoryClassName != null) {
+ LOGGER.log(Level.CONFIG,
+ "Loading test container factory '{0}' specified in the '{1}' system property.",
+ new Object[] {factoryClassName, TestProperties.CONTAINER_FACTORY});
+
+ defaultTestContainerFactoryClass = loadFactoryClass(factoryClassName);
+ } else {
+ final TestContainerFactory[] factories = ServiceFinder.find(TestContainerFactory.class).toArray();
+ if (factories.length > 0) {
+ // if there is only one factory instance, just return it
+ if (factories.length == 1) {
+ // cache the class for future reuse
+ defaultTestContainerFactoryClass = factories[0].getClass();
+ LOGGER.log(
+ Level.CONFIG,
+ "Using the single found TestContainerFactory service provider '{0}'",
+ defaultTestContainerFactoryClass.getName());
+ return factories[0];
+ }
+
+ // if default factory is present, use it.
+ for (final TestContainerFactory tcf : factories) {
+ if (TestProperties.DEFAULT_CONTAINER_FACTORY.equals(tcf.getClass().getName())) {
+ // cache the class for future reuse
+ defaultTestContainerFactoryClass = tcf.getClass();
+ LOGGER.log(
+ Level.CONFIG,
+ "Found multiple TestContainerFactory service providers, using the default found '{0}'",
+ TestProperties.DEFAULT_CONTAINER_FACTORY);
+ return tcf;
+ }
+ }
+
+ // default factory is not in the list - log warning and return the first found factory instance
+ // cache the class for future reuse
+ defaultTestContainerFactoryClass = factories[0].getClass();
+ LOGGER.log(
+ Level.WARNING,
+ "Found multiple TestContainerFactory service providers, using the first found '{0}'",
+ defaultTestContainerFactoryClass.getName());
+ return factories[0];
+ }
+
+ LOGGER.log(
+ Level.CONFIG,
+ "No TestContainerFactory configured, trying to load and instantiate the default implementation '{0}'",
+ TestProperties.DEFAULT_CONTAINER_FACTORY);
+ defaultTestContainerFactoryClass = loadFactoryClass(TestProperties.DEFAULT_CONTAINER_FACTORY);
+ }
+ }
+
+ try {
+ return defaultTestContainerFactoryClass.newInstance();
+ } catch (final Exception ex) {
+ throw new TestContainerException(String.format(
+ "Could not instantiate test container factory '%s'", defaultTestContainerFactoryClass.getName()), ex);
+ }
+ }
+
+ private static Class<? extends TestContainerFactory> loadFactoryClass(final String factoryClassName) {
+ Class<? extends TestContainerFactory> factoryClass;
+ final Class<Object> loadedClass = AccessController.doPrivileged(ReflectionHelper.classForNamePA(factoryClassName, null));
+ if (loadedClass == null) {
+ throw new TestContainerException(String.format(
+ "Test container factory class '%s' cannot be loaded", factoryClassName));
+ }
+ try {
+ return loadedClass.asSubclass(TestContainerFactory.class);
+ } catch (final ClassCastException ex) {
+ throw new TestContainerException(String.format(
+ "Class '%s' does not implement TestContainerFactory SPI.", factoryClassName), ex);
+ }
+ }
+
+ /**
+ * Create a JAX-RS web target whose URI refers to the {@link #getBaseUri() base URI} the tested
+ * JAX-RS / Jersey application is deployed at, plus the path specified in the {@code path} argument.
+ * <p>
+ * This method is an equivalent of calling <tt>client().target(getBaseUri())</tt>.
+ * </p>
+ *
+ * @return the created JAX-RS web target.
+ */
+ public final WebTarget target() {
+ return client().target(getTestContainer().getBaseUri());
+ }
+
+ /**
+ * Create a JAX-RS web target whose URI refers to the {@link #getBaseUri() base URI} the tested
+ * JAX-RS / Jersey application is deployed at, plus the path specified in the {@code path} argument.
+ * <p>
+ * This method is an equivalent of calling {@code target().path(path)}.
+ * </p>
+ *
+ * @param path relative path (from tested application base URI) this web target should point to.
+ * @return the created JAX-RS web target.
+ */
+ public final WebTarget target(final String path) {
+ return target().path(path);
+ }
+
+ /**
+ * Get the JAX-RS test client that is {@link #configureClient(ClientConfig) pre-configured}
+ * for this test.
+ *
+ * @return the configured test client.
+ */
+ public final Client client() {
+ return getClient();
+ }
+
+ /**
+ * Set up the test by creating a test container instance, {@link TestContainer#start() starting} it and by creating a new
+ * {@link #configureClient(ClientConfig) pre-configured} test client.
+ * The test container is obtained from the {@link #getTestContainerFactory() test container factory}.
+ *
+ * @throws TestContainerException if the default test container factory cannot be obtained,
+ * or the test application deployment context is not supported
+ * by the test container factory.
+ * @throws Exception if an exception is thrown during setting up the test environment.
+ */
+ @BeforeEach
+ public void setUp() throws Exception {
+ synchronized (this) {
+ if (INSTANCE.get() == null) {
+ registerLogHandlerIfEnabled();
+ final TestContainer testContainer = createTestContainer(context);
+
+ // Set current instance of test container and start it.
+ setTestContainer(testContainer);
+ testContainer.start();
+
+ // Create and set new client.
+ setClient(getClient(testContainer.getClientConfig()));
+ INSTANCE.set(this);
+ }
+ }
+ }
+
+ /**
+ * Tear down the test by {@link TestContainer#stop() stopping} the test container obtained from the
+ * {@link #getTestContainerFactory() test container factory} and by {@link Client#close() closing}
+ * and discarding the {@link #configureClient(ClientConfig) pre-configured} test client
+ * that was {@link #setUp() set up} for the test.
+ *
+ * @throws Exception if an exception is thrown during tearing down the test environment.
+ */
+ public void tearDown() throws Exception {
+ if (isLogRecordingEnabled()) {
+ unregisterLogHandler();
+ }
+
+ try {
+ TestContainer oldContainer = setTestContainer(null);
+ if (oldContainer != null) {
+ oldContainer.stop();
+ }
+ } finally {
+ closeIfNotNull(setClient(null));
+ }
+ }
+
+ @AfterAll
+ public static void tearDownAll() throws Exception {
+ INSTANCE.get().tearDown();
+ }
+
+ /**
+ * Get the JAX-RS test client that is {@link #configureClient(ClientConfig) pre-configured}
+ * for this test. This method can be overridden.
+ *
+ * @return the configured test client.
+ */
+ protected Client getClient() {
+ return client.get();
+ }
+
+ /**
+ * Get the old JAX-RS test client and set a new one. This method can be overridden.
+ *
+ * @param client the configured test client.
+ * @return old configured test client.
+ */
+ protected Client setClient(final Client client) {
+ return this.client.getAndSet(client);
+ }
+
+ /**
+ * Create an instance of test {@link Client} using the client configuration provided by the configured
+ * {@link TestContainer}.
+ * <p>
+ * If the {@code TestContainer} does not provide any client configuration (passed {@code clientConfig} is {@code null}),
+ * the default implementation of this method first creates an empty new {@link ClientConfig}
+ * instance. The client configuration (provided by test container or created) is then passed to
+ * {@link #configureClient(ClientConfig)} which can be overridden in the {@code JerseyTest}
+ * subclass to provide custom client configuration. At last, new JAX-RS {@link Client} instance is created based on the
+ * resulting client configuration.
+ * </p>
+ *
+ * @param clientConfig test client default configuration. May be {@code null}.
+ * @return A Client instance.
+ */
+ private Client getClient(ClientConfig clientConfig) {
+ if (clientConfig == null) {
+ clientConfig = new ClientConfig();
+ }
+
+ //check if logging is required
+ if (isEnabled(TestProperties.LOG_TRAFFIC)) {
+ clientConfig.register(new LoggingFeature(LOGGER, isEnabled(TestProperties.DUMP_ENTITY)
+ ? LoggingFeature.Verbosity.PAYLOAD_ANY
+ : LoggingFeature.Verbosity.HEADERS_ONLY));
+
+ }
+
+ configureClient(clientConfig);
+
+ return ClientBuilder.newClient(clientConfig);
+ }
+
+ /**
+ * Configure the test client.
+ * <p>
+ * The method can be overridden by {@code JerseyTest} subclasses to conveniently configure the test client instance
+ * used by Jersey test framework (either returned from {@link #client()} method or used to create
+ * {@link WebTarget} instances returned from one of the {@code target} methods
+ * ({@link #target()} or {@link #target(String)}).
+ * <p>
+ * Prior to every test method run, a new client instance is configured and created using the client configuration
+ * provided by the {@link TestContainer} as well as any internal {@code JerseyTest}
+ * client configuration settings.
+ * </p>
+ * <p>
+ * Before the actual client instance creation, Jersey test framework invokes this method in order to allow the subclasses
+ * to further customize created client instance.
+ * </p>
+ * <p>
+ * After each test method is run, the existing client instance is {@link Client#close() closed}
+ * and discarded.
+ * </p>
+ * <p>
+ * Default implementation of the method is "no-op".
+ * </p>
+ *
+ * @param config Jersey test client configuration that can be modified before the client is created.
+ */
+ protected void configureClient(final ClientConfig config) {
+ // do nothing
+ }
+
+ /**
+ * Returns the base URI of the tested application.
+ *
+ * @return the base URI of the tested application.
+ */
+ // TODO make final
+ protected URI getBaseUri() {
+ final TestContainer container = getTestContainer();
+
+ if (container != null) {
+ // called from outside of JerseyTest constructor
+ return container.getBaseUri();
+ }
+
+ // called from within JerseyTest constructor
+ return UriBuilder.fromUri("http://localhost/").port(getPort()).build();
+ }
+
+ /**
+ * Get the port to be used for test application deployments.
+ *
+ * @return The HTTP port of the URI
+ */
+ protected final int getPort() {
+ final TestContainer container = getTestContainer();
+
+ if (container != null) {
+ // called from outside of JerseyTest constructor
+ return container.getBaseUri().getPort();
+ }
+
+ // called from within JerseyTest constructor
+ final String value = getProperty(TestProperties.CONTAINER_PORT);
+ if (value != null) {
+
+ try {
+ final int i = Integer.parseInt(value);
+ if (i < 0) {
+ throw new NumberFormatException("Value not positive.");
+ }
+ return i;
+ } catch (final NumberFormatException e) {
+ LOGGER.log(Level.CONFIG,
+ "Value of " + TestProperties.CONTAINER_PORT
+ + " property is not a valid positive integer [" + value + "]."
+ + " Reverting to default [" + TestProperties.DEFAULT_CONTAINER_PORT + "].",
+ e
+ );
+ }
+ }
+ return TestProperties.DEFAULT_CONTAINER_PORT;
+ }
+
+ /**
+ * Get stored {@link LogRecord log records} if enabled by setting {@link TestProperties#RECORD_LOG_LEVEL} or an empty list.
+ *
+ * @return list of log records or an empty list.
+ */
+ protected final List<LogRecord> getLoggedRecords() {
+ return getLogHandler().getRecords();
+ }
+
+ /**
+ * Get last stored {@link LogRecord log record} if enabled by setting {@link TestProperties#RECORD_LOG_LEVEL}
+ * or {@code null}.
+ *
+ * @return last stored {@link LogRecord log record} or {@code null}.
+ */
+ protected final LogRecord getLastLoggedRecord() {
+ final List<LogRecord> loggedRecords = getLoggedRecords();
+ return loggedRecords.isEmpty() ? null : loggedRecords.get(loggedRecords.size() - 1);
+ }
+
+ /**
+ * Retrieves a list of root loggers.
+ *
+ * @return list of root loggers.
+ */
+ private Set<Logger> getRootLoggers() {
+ final LogManager logManager = LogManager.getLogManager();
+ final Enumeration<String> loggerNames = logManager.getLoggerNames();
+
+ final Set<Logger> rootLoggers = new HashSet<>();
+
+ while (loggerNames.hasMoreElements()) {
+ Logger logger = logManager.getLogger(loggerNames.nextElement());
+ if (logger != null) {
+ while (logger.getParent() != null) {
+ logger = logger.getParent();
+ }
+ rootLoggers.add(logger);
+ }
+ }
+
+ return rootLoggers;
+ }
+
+ /**
+ * Register {@link Handler log handler} to the list of root loggers
+ * if log recording is enabled.
+ */
+ private void registerLogHandlerIfEnabled() {
+ if (isLogRecordingEnabled()) {
+ registerLogHandler();
+ }
+ }
+
+ /**
+ * Register {@link Handler log handler} to the list of root loggers.
+ */
+ private void registerLogHandler() {
+ final String recordLogLevel = getProperty(TestProperties.RECORD_LOG_LEVEL);
+ final int recordLogLevelInt = Integer.valueOf(recordLogLevel);
+ final Level level = Level.parse(recordLogLevel);
+
+ logLevelMap.clear();
+
+ for (final Logger root : getRootLoggers()) {
+ logLevelMap.put(root, root.getLevel());
+
+ if (root.getLevel().intValue() > recordLogLevelInt) {
+ root.setLevel(level);
+ }
+
+ root.addHandler(getLogHandler());
+ }
+ }
+
+ /**
+ * Un-register {@link Handler log handler} from the list of root loggers.
+ */
+ private void unregisterLogHandler() {
+ for (final Logger root : getRootLoggers()) {
+ root.setLevel(logLevelMap.get(root));
+ root.removeHandler(getLogHandler());
+ }
+ logHandler = null;
+ }
+
+ /**
+ * Return {@code true} if log recoding is enabled.
+ *
+ * @return {@code true} if log recoding is enabled, {@code false} otherwise.
+ */
+ private boolean isLogRecordingEnabled() {
+ return getProperty(TestProperties.RECORD_LOG_LEVEL) != null;
+ }
+
+ /**
+ * Retrieves {@link Handler log handler} capable of storing {@link LogRecord logged records}.
+ *
+ * @return log handler.
+ */
+ private JerseyTestLogHandler getLogHandler() {
+ if (logHandler == null) {
+ logHandler = new JerseyTestLogHandler();
+ }
+ return logHandler;
+ }
+
+ /**
+ * Returns {@link TestProperties#ASYNC_TIMEOUT_MULTIPLIER} or {@code 1} if the property is not defined.
+ *
+ * @return Multiplier of the async timeout for async test.
+ */
+ protected int getAsyncTimeoutMultiplier() {
+ final String property = getProperty(TestProperties.ASYNC_TIMEOUT_MULTIPLIER);
+ Integer multi = 1;
+ if (property != null) {
+ multi = Integer.valueOf(property);
+ if (multi <= 0) {
+ throw new NumberFormatException(
+ "Property " + TestProperties.ASYNC_TIMEOUT_MULTIPLIER + " must be a number greater than 0.");
+ }
+ }
+ return multi;
+
+ }
+
+ /**
+ * Utility method that safely closes a response without throwing an exception.
+ *
+ * @param responses responses to close. Each response may be {@code null}.
+ * @since 2.5
+ */
+ public final void close(final Response... responses) {
+ if (responses == null || responses.length == 0) {
+ return;
+ }
+
+ for (final Response response : responses) {
+ if (response == null) {
+ continue;
+ }
+ try {
+ response.close();
+ } catch (final Throwable t) {
+ LOGGER.log(Level.WARNING, "Error closing a response.", t);
+ }
+ }
+ }
+
+ /**
+ * Utility method that safely closes a client instance without throwing an exception.
+ *
+ * @param clients client instances to close. Each instance may be {@code null}.
+ * @since 2.5
+ */
+ public static void closeIfNotNull(final Client... clients) {
+ if (clients == null || clients.length == 0) {
+ return;
+ }
+
+ for (final Client c : clients) {
+ if (c == null) {
+ continue;
+ }
+ try {
+ c.close();
+ } catch (final Throwable t) {
+ LOGGER.log(Level.WARNING, "Error closing a client instance.", t);
+ }
+
+ }
+ }
+
+ /**
+ * Custom logging handler used to store log records produces during an invocation of a test.
+ */
+ private class JerseyTestLogHandler extends Handler {
+
+ private final int logLevel;
+ private final List<LogRecord> records;
+
+ private JerseyTestLogHandler() {
+ this.logLevel = Integer.parseInt(getProperty(TestProperties.RECORD_LOG_LEVEL));
+ this.records = new ArrayList<>();
+ }
+
+ @Override
+ public void publish(final LogRecord record) {
+ final String loggerName = record.getLoggerName();
+
+ if (record.getLevel().intValue() >= logLevel
+ && loggerName.startsWith("org.glassfish.jersey")
+ && !loggerName.startsWith("org.glassfish.jersey.test")) {
+ records.add(record);
+ }
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+
+ public List<LogRecord> getRecords() {
+ return records;
+ }
+ }
+}
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
index 12b2a54..456ef30 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024 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
@@ -16,6 +16,7 @@
package org.glassfish.jersey.tests.e2e.common;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Application;
@@ -42,7 +43,7 @@
public class TestRuntimeDelegate extends AbstractRuntimeDelegate {
public TestRuntimeDelegate() {
- super(new MessagingBinders.HeaderDelegateProviders().getHeaderDelegateProviders());
+ super(new MessagingBinders.HeaderDelegateProviders(RuntimeType.SERVER).getHeaderDelegateProviders());
}
@Override
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/internal/ContextResolverFactoryTest.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/internal/ContextResolverFactoryTest.java
index bd07da2..bda770f 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/internal/ContextResolverFactoryTest.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/internal/ContextResolverFactoryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,6 +19,7 @@
import java.util.Collections;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
@@ -30,6 +31,8 @@
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.Injections;
import org.glassfish.jersey.internal.inject.ProviderBinder;
+import org.glassfish.jersey.model.internal.CommonConfig;
+import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.tests.e2e.common.TestRuntimeDelegate;
import org.junit.jupiter.api.BeforeEach;
@@ -115,6 +118,7 @@
injectionManager.register(new Binder());
BootstrapBag bootstrapBag = new BootstrapBag();
+ bootstrapBag.setConfiguration(new CommonConfig(RuntimeType.SERVER, ComponentBag.INCLUDE_ALL));
ContextResolverFactory.ContextResolversConfigurator configurator =
new ContextResolverFactory.ContextResolversConfigurator();
configurator.init(injectionManager, bootstrapBag);
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/process/internal/ExecutorProvidersTest.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/process/internal/ExecutorProvidersTest.java
index 040aeb2..bf9de7b 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/process/internal/ExecutorProvidersTest.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/process/internal/ExecutorProvidersTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024 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
@@ -28,6 +28,7 @@
import jakarta.inject.Named;
import jakarta.inject.Qualifier;
import jakarta.inject.Singleton;
+import jakarta.ws.rs.RuntimeType;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.InjectionManager;
@@ -208,7 +209,7 @@
@BeforeEach
public void setup() {
injectionManager = Injections.createInjectionManager(this);
- ExecutorProviders.registerExecutorBindings(injectionManager);
+ ExecutorProviders.registerExecutorBindings(injectionManager, RuntimeType.SERVER);
injectionManager.completeRegistration();
}
diff --git a/tests/integration/cdi-integration/cdi-inject-weld-test/pom.xml b/tests/integration/cdi-integration/cdi-inject-weld-test/pom.xml
new file mode 100644
index 0000000..00a3b58
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-inject-weld-test/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2024 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.cdi</groupId>
+ <artifactId>cdi-integration-project</artifactId>
+ <version>4.0.99-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>cdi-inject-weld-test</artifactId>
+ <packaging>jar</packaging>
+ <name>jersey-tests-cdi-inject-weld</name>
+
+ <description>Jersey CDI Inject-Weld Tests</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.enterprise</groupId>
+ <artifactId>jakarta.enterprise.cdi-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-sse</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.incubator</groupId>
+ <artifactId>jersey-cdi-inject-weld</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>${skip.tests}</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/java/org/glassfish/jersey/tests/cdi/inject/weld/SseTest.java b/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/java/org/glassfish/jersey/tests/cdi/inject/weld/SseTest.java
new file mode 100644
index 0000000..d47f35f
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/java/org/glassfish/jersey/tests/cdi/inject/weld/SseTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2024 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.cdi.inject.weld;
+
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.Injections;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseySingleContainerTest;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import jakarta.enterprise.inject.se.SeContainer;
+import jakarta.enterprise.inject.se.SeContainerInitializer;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.sse.Sse;
+import jakarta.ws.rs.sse.SseEventSink;
+import jakarta.ws.rs.sse.SseEventSource;
+
+public class SseTest extends JerseySingleContainerTest {
+ protected static SeContainer container;
+ protected InjectionManager injectionManager;
+
+ @BeforeAll
+ public static void setup() {
+ SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
+ container = containerInitializer.initialize();
+ }
+
+ @AfterAll
+ public static void weldTearDown() throws Exception {
+ container.close();
+ }
+
+ @Path("/sse")
+ public static class SseResource {
+ @GET
+ @Produces(MediaType.SERVER_SENT_EVENTS)
+ public void eventStream(@Context SseEventSink eventSink, @Context Sse sse) {
+ try (SseEventSink sink = eventSink) {
+ eventSink.send(sse.newEvent("event1"));
+ eventSink.send(sse.newEvent("event2"));
+ eventSink.send(sse.newEvent("event3"));
+ }
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig(SseResource.class);
+ }
+
+ @Test
+ public void sseBinderTest() {
+ injectionManager = Injections.createInjectionManager();
+ injectionManager.completeRegistration();
+
+ Sse sse = injectionManager.getInstance(Sse.class);
+ Assertions.assertEquals("org.glassfish.jersey.media.sse.internal.JerseySse", sse.getClass().getName());
+
+ injectionManager.shutdown();
+ }
+
+ @Test
+ public void sseTest() {
+ WebTarget target = target("sse");
+ try (SseEventSource source = SseEventSource.target(target).build()) {
+ source.register(System.out::println);
+ source.open();
+ Thread.sleep(500); // Consume events for just 500 ms
+ } catch (InterruptedException e) {
+ }
+ }
+}
diff --git a/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/resources/META-INF/beans.xml b/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..c175b60
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-inject-weld-test/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2024 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="https://jakarta.ee/xml/ns/jakartaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
+ version="4.0" bean-discovery-mode="all">
+</beans>
diff --git a/tests/integration/cdi-integration/pom.xml b/tests/integration/cdi-integration/pom.xml
index bc23bb7..24a511e 100644
--- a/tests/integration/cdi-integration/pom.xml
+++ b/tests/integration/cdi-integration/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2019, 2024 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
@@ -37,6 +37,7 @@
<module>cdi-client-on-server</module>
<module>cdi-ejb-test-webapp</module>
<module>cdi-iface-with-non-jaxrs-impl-test-webapp</module>
+ <module>cdi-inject-weld-test</module>
<module>cdi-manually-bound</module>
<module>cdi-log-check</module>
<module>cdi-multimodule</module>
diff --git a/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java b/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java
index 974404c..6a0290f 100644
--- a/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java
+++ b/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Markus KARG. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -26,6 +26,7 @@
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Configuration;
import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.internal.ServiceFinder.ServiceIteratorProvider;
import org.glassfish.jersey.internal.guava.Iterators;
@@ -78,10 +79,16 @@
}
}
: service == InjectionManagerFactory.class ? new InjectionManagerFactory() {
+
@Override
public final InjectionManager create(final Object parent) {
return mockInjectionManager;
}
+
+ @Override
+ public InjectionManager create(Object parent, Configuration configuration) {
+ return mockInjectionManager;
+ }
}
: null));
}