org.glassfish.jersey.client.ClientExecutorProvidersConfigurator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaxrs-ri Show documentation
Show all versions of jaxrs-ri Show documentation
A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle
(jaxrs-ri.jar).
Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and
contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external
RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source
bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external
RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI
sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from
the command line.
/*
* 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
* 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 java.lang.reflect.Method;
import java.security.AccessController;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.jersey.internal.BootstrapBag;
import org.glassfish.jersey.internal.inject.Bindings;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InstanceBinding;
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.jersey.internal.util.collection.Value;
import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.process.internal.AbstractExecutorProvidersConfigurator;
import org.glassfish.jersey.spi.ExecutorServiceProvider;
import org.glassfish.jersey.spi.ScheduledExecutorServiceProvider;
import jakarta.ws.rs.core.Configuration;
/**
* Configurator which initializes and register {@link ExecutorServiceProvider} and
* {@link ScheduledExecutorServiceProvider}.
*
* @author Petr Bouda
*/
class ClientExecutorProvidersConfigurator extends AbstractExecutorProvidersConfigurator {
private static final Logger LOGGER = Logger.getLogger(ClientExecutorProvidersConfigurator.class.getName());
private static final ExecutorService MANAGED_EXECUTOR_SERVICE = lookupManagedExecutorService();
private final ComponentBag componentBag;
private final JerseyClient client;
private final ExecutorService customExecutorService;
private final ScheduledExecutorService customScheduledExecutorService;
ClientExecutorProvidersConfigurator(ComponentBag componentBag, JerseyClient client,
ExecutorService customExecutorService,
ScheduledExecutorService customScheduledExecutorService) {
this.componentBag = componentBag;
this.client = client;
this.customExecutorService = customExecutorService;
this.customScheduledExecutorService = customScheduledExecutorService;
}
@Override
public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
final Configuration configuration = bootstrapBag.getConfiguration();
Map runtimeProperties = configuration.getProperties();
ExecutorServiceProvider defaultAsyncExecutorProvider;
ScheduledExecutorServiceProvider defaultScheduledExecutorProvider;
final ExecutorService clientExecutorService = client.getExecutorService() == null
// custom executor service can be also set via managed client config class, in that case, it ends up in the
// customExecutorService field (similar for scheduled version)
? customExecutorService
: client.getExecutorService();
// if there is a users provided executor service, use it
if (clientExecutorService != null) {
defaultAsyncExecutorProvider = new ClientExecutorServiceProvider(clientExecutorService);
// otherwise, check for ClientProperties.ASYNC_THREADPOOL_SIZE - if that is set, Jersey will create the
// ExecutorService to be used. If not and running on Java EE container, ManagedExecutorService will be used.
// Final fallback is DefaultClientAsyncExecutorProvider with defined default.
} else {
// Default async request executors support
Integer asyncThreadPoolSize = ClientProperties
.getValue(runtimeProperties, ClientProperties.ASYNC_THREADPOOL_SIZE, Integer.class);
if (asyncThreadPoolSize != null) {
// TODO: Do we need to register DEFAULT Executor and ScheduledExecutor to InjectionManager?
asyncThreadPoolSize = (asyncThreadPoolSize < 0) ? 0 : asyncThreadPoolSize;
InstanceBinding asyncThreadPoolSizeBinding = Bindings
.service(asyncThreadPoolSize)
.named("ClientAsyncThreadPoolSize");
injectionManager.register(asyncThreadPoolSizeBinding);
defaultAsyncExecutorProvider = new DefaultClientAsyncExecutorProvider(asyncThreadPoolSize, configuration);
} else {
if (MANAGED_EXECUTOR_SERVICE != null) {
defaultAsyncExecutorProvider = new ClientExecutorServiceProvider(MANAGED_EXECUTOR_SERVICE);
} else {
defaultAsyncExecutorProvider = new DefaultClientAsyncExecutorProvider(0, configuration);
}
}
}
InstanceBinding executorBinding = Bindings
.service(defaultAsyncExecutorProvider)
.to(ExecutorServiceProvider.class);
injectionManager.register(executorBinding);
final ScheduledExecutorService clientScheduledExecutorService = client.getScheduledExecutorService() == null
// scheduled executor service set from {@link ClientConfig}.
? customScheduledExecutorService
: client.getScheduledExecutorService();
if (clientScheduledExecutorService != null) {
defaultScheduledExecutorProvider =
new ClientScheduledExecutorServiceProvider(Values.of(clientScheduledExecutorService));
} else {
ScheduledExecutorService scheduledExecutorService = lookupManagedScheduledExecutorService();
defaultScheduledExecutorProvider =
scheduledExecutorService == null
// default client background scheduler disposes the executor service when client is closed.
// we don't need to do that for user provided (via ClientBuilder) or managed executor service.
? new DefaultClientBackgroundSchedulerProvider()
: new ClientScheduledExecutorServiceProvider(Values.of(scheduledExecutorService));
}
InstanceBinding schedulerBinding = Bindings
.service(defaultScheduledExecutorProvider)
.to(ScheduledExecutorServiceProvider.class);
injectionManager.register(schedulerBinding);
registerExecutors(injectionManager, componentBag, defaultAsyncExecutorProvider,
defaultScheduledExecutorProvider, bootstrapBag.getManagedObjectsFinalizer());
}
private static ExecutorService lookupManagedExecutorService() {
// Get the default ManagedExecutorService, if available
try {
// Android and some other environments don't have InitialContext class available.
final Class> aClass =
AccessController.doPrivileged(ReflectionHelper.classForNamePA("javax.naming.InitialContext"));
final Object initialContext = aClass.newInstance();
final Method lookupMethod = aClass.getMethod("lookup", String.class);
return (ExecutorService) lookupMethod.invoke(initialContext, "java:comp/DefaultManagedExecutorService");
} catch (Exception e) {
// ignore
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, e.getMessage(), e);
}
} catch (LinkageError error) {
// ignore - JDK8 compact2 profile - http://openjdk.java.net/jeps/161
}
return null;
}
private ScheduledExecutorService lookupManagedScheduledExecutorService() {
try {
// Android and some other environments don't have InitialContext class available.
final Class> aClass =
AccessController.doPrivileged(ReflectionHelper.classForNamePA("javax.naming.InitialContext"));
final Object initialContext = aClass.newInstance();
final Method lookupMethod = aClass.getMethod("lookup", String.class);
return (ScheduledExecutorService) lookupMethod
.invoke(initialContext, "java:comp/DefaultManagedScheduledExecutorService");
} catch (Exception e) {
// ignore
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, e.getMessage(), e);
}
} catch (LinkageError error) {
// ignore - JDK8 compact2 profile - http://openjdk.java.net/jeps/161
}
return null;
}
@ClientAsyncExecutor
public static class ClientExecutorServiceProvider implements ExecutorServiceProvider {
private final ExecutorService executorService;
ClientExecutorServiceProvider(ExecutorService executorService) {
this.executorService = executorService;
}
@Override
public ExecutorService getExecutorService() {
return executorService;
}
@Override
public void dispose(ExecutorService executorService) {
}
}
@ClientBackgroundScheduler
public static class ClientScheduledExecutorServiceProvider implements ScheduledExecutorServiceProvider {
private final Value executorService;
ClientScheduledExecutorServiceProvider(Value executorService) {
this.executorService = executorService;
}
@Override
public ScheduledExecutorService getExecutorService() {
return executorService.get();
}
@Override
public void dispose(ExecutorService executorService) {
}
}
}