All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.bedrock.runtime.java.container.Container Maven / Gradle / Ivy

Go to download

Interfaces, classes and resources to construct, inspect and manage runtime processes.

There is a newer version: 7.0.3
Show newest version
/*
 * File: Container.java
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * The contents of this file are subject to the terms and conditions of 
 * the Common Development and Distribution License 1.0 (the "License").
 *
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License by consulting the LICENSE.txt file
 * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL
 *
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file LICENSE.txt.
 *
 * MODIFICATIONS:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 */

package com.oracle.bedrock.runtime.java.container;

import com.oracle.bedrock.annotations.Internal;
import com.oracle.bedrock.runtime.LocalPlatform;
import com.oracle.bedrock.runtime.network.AvailablePortIterator;

import java.io.PrintStream;
import java.util.HashSet;

/**
 * The {@link Container} class provides mechanisms to establish and dismantal
 * "contained" and "isolated" applications, much like a Java Application Server
 * or container would, but mostly for regular Java Applications.
 * 

* Fundamentally this includes providing mechanisms to dynamically load and * associate application {@link Class}es together with their {@link Thread}s * with appropriate {@link Scope}s. *

* Copyright (c) 2013. All Rights Reserved. Oracle Corporation.
* Oracle is a registered trademark of Oracle Corporation and/or its affiliates. * * @author Brian Oliver */ @Internal public class Container { /** * The number of bytes to reserve for i/o buffers used by * pipes between application i/o streams. */ public static final int PIPE_BUFFER_SIZE_BYTES = 16 * 1024; /** * A {@link PlatformScope} that represents the Java Virtual Machine runtime * platform resources. These are the underlying resources on which we * may ultimately delegate requests. We also use this {@link Scope} to * return the Java Virtual Machine runtime back to normal when we want to * stop running in a container-based mode. */ private static PlatformScope platformScope; /** * The {@link DefaultScope} to use when a suitable {@link ContainerScope} * can't be located. This is primarily when a ClassLoader and/or Thread is * not associated with an {@link Scope}. */ private static DefaultScope defaultScope; /** * The {@link ContainerScope} associated with the current {@link Thread}. */ private static InheritableThreadLocal threadScope; /** * The current set of {@link ContainerScope}s being managed by the {@link Container}. */ private static HashSet scopes; /** * Static Initialization. */ static { // establish the ability to track Scopes by thread threadScope = new InheritableThreadLocal(); // create a PlatformScope representing the platform itself platformScope = new PlatformScope(getAvailablePorts()); // establish the scopes set to track scopes being managed scopes = new HashSet(); } /** * Starts the containment of application resources. */ public synchronized static void start() { // are we running as a container? if (System.getProperties() instanceof DelegatingProperties) { // SKIP: we're already running as a container so do nothing! } else { // establish the default scope to use when a thread isn't isolated defaultScope = new DefaultScope(platformScope); // ensure that the JMX MBean Server for the default Scope is the // DelegatingMBeanServerBuilder so that we can isolate MBeanServers defaultScope.getProperties().setProperty(ContainerMBeanServerBuilder.PROPERTY_JMX_MBEAN_SERVER_BUILDER, DelegatingMBeanServerBuilder.class.getCanonicalName()); System.setProperties(new DelegatingProperties(defaultScope.getProperties())); System.setOut(new PrintStream(new DelegatingStdOutOutputStream(platformScope.getStandardOutput()), true)); System.setErr(new PrintStream(new DelegatingStdErrOutputStream(platformScope.getStandardError()), true)); System.setIn(new DelegatingStdInInputStream(platformScope.getStandardInput())); // establish the scopes set to track the scopes being managed scopes = new HashSet(); } } /** * Stops the containment of application resources. */ public synchronized static void stop() { // are we running as a container? if (System.getProperties() instanceof DelegatingProperties) { System.setProperties(platformScope.getProperties()); System.setOut(platformScope.getStandardOutput()); System.setErr(platformScope.getStandardError()); // close and clear the default scope as we are no longer running in a container defaultScope.close(); defaultScope = null; } else { // SKIP: we're not running as a container so do nothing! } } /** * Adds the specified {@link ContainerScope} to the {@link Container} for managing. *

* Should the {@link Container} not be {@link #start()}ed, it will automatically be started. * * @param scope the {@link ContainerScope} to manage */ public synchronized static void manage(ContainerScope scope) { // add the scope we're now managing if (scopes.add(scope)) { // ensure that the container is started start(); } } /** * Removes the specified {@link ContainerScope} from being managed. *

* Should the {@link ContainerScope} being unmanaged be the last known * managed {@link ContainerScope}, the {@link Container} will automatically be {@link #stop()}ed. * * @param scope the {@link ContainerScope} to unmanage */ public synchronized static void unmanage(ContainerScope scope) { if (scopes.remove(scope)) { stop(); } } /** * Determines the {@link ContainerScope} of the calling {@link Thread}. * Should the calling {@link Thread} is not be associated with a * {@link ContainerScope} null is returned. *

* There is no need for the {@link Container} to have been started for this * method to return the correct {@link ContainerScope} of the calling {@link Thread}. * * @return the {@link ContainerScope} or null */ public static ContainerScope getContainerScope() { // attempt to determine the scope based on the calling Thread ContainerScope scope = threadScope.get(); if (scope == null) { // as it's not associated with the calling thread, try to find // the scope using the class loader of the thread ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); while (scope == null && classLoader != null) { if (classLoader instanceof ContainerScopeClassLoader) { scope = ((ContainerScopeClassLoader) classLoader).getContainerScope(); } else { classLoader = classLoader.getParent(); } } } return scope; } /** * Obtains a {@link PlatformScope} that represents the underlying Java * Virtual Machine Platform itself. * * @return an {@link PlatformScope} for the Java Virtual Machine platform */ public static PlatformScope getPlatformScope() { return platformScope; } /** * Obtains a {@link DefaultScope} to use when running in container-mode * but a {@link ContainerScope} can't be determined when calling * {@link #getContainerScope()}. * * @return the {@link DefaultScope} or null if not running * in container-mode. */ public static DefaultScope getDefaultScope() { return defaultScope; } /** * Associates the specified {@link ContainerScope} with the calling {@link Thread} * (if not already associated). * * @param scope the {@link ContainerScope} for the calling {@link Thread} * * @throws IllegalStateException if the current calling {@link Thread} is * already associated with a {@link ContainerScope} */ public static void associateThreadWith(ContainerScope scope) { if (scope == null) { // SKIP: do nothing if we attempt to associate with a null scope } else { Scope existingScope = threadScope.get(); if (existingScope == null) { threadScope.set(scope); } else { throw new IllegalStateException(String.format("Attempted to associateThreadWith(%s) on Thread [%s] when it is already associated with ContainerScope(%s)", scope.getName(), Thread.currentThread(), existingScope.getName())); } } } /** * Dissociates the {@link ContainerScope} currently associated with the calling * {@link Thread}. *

* After calling this method, the calling {@link Thread} will no longer be * directly associated with a {@link Scope}, except perhaps via its context * {@link ClassLoader}. */ public static void dissociateThread() { if (threadScope.get() == null) { // SKIP: do nothing if the current thread is not isolated } else { threadScope.remove(); } } /** * Obtains the {@link AvailablePortIterator} for the {@link Container}. * * @return the {@link AvailablePortIterator} * * @deprecated use LocalPlatform.INSTANCE.getAvailablePorts() */ @Deprecated public static AvailablePortIterator getAvailablePorts() { return LocalPlatform.get().getAvailablePorts(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy