Search in sources :

Example 1 with ContainerClassLoader

use of com.oracle.bedrock.runtime.java.container.ContainerClassLoader in project oracle-bedrock by coherence-community.

the class ContainerBasedJavaApplicationLauncher method configureRemoteChannel.

/**
 * Configures the internal application container {@link RemoteChannel}.
 *
 * @param containerClassLoader  the {@link ContainerClassLoader}
 * @param pipedOutputStream     the {@link PipedOutputStream}
 * @param pipedInputStream      the {@link PipedInputStream}
 * @param targetClassName       the optional target (main) class name
 */
public static void configureRemoteChannel(ContainerClassLoader containerClassLoader, PipedOutputStream pipedOutputStream, PipedInputStream pipedInputStream, String targetClassName) {
    // remember the current context ClassLoader of the thread
    // (so that we can return it back to normal when we're finished executing)
    ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        // set the context ClassLoader of the Thread to be that of the
        // ContainerClassLoader
        Thread.currentThread().setContextClassLoader(containerClassLoader);
        // and associate the Thread with the Scope in the Container
        Container.associateThreadWith(containerClassLoader.getContainerScope());
        // create the Remote Channel
        Class<?> remoteChannelClass = containerClassLoader.loadClass(PipeBasedRemoteChannel.class.getName());
        Constructor<?> constructor = remoteChannelClass.getConstructor(PipedOutputStream.class, PipedInputStream.class);
        Object remoteChannel = constructor.newInstance(pipedOutputStream, pipedInputStream);
        // open the RemoteChannel
        remoteChannelClass.getMethod("open").invoke(remoteChannel);
        // save the RemoteChannel into the ContainerScope so that we can resolve it from within
        // the application when required
        containerClassLoader.getContainerScope().setRemoteChannel(remoteChannel);
    } catch (ClassNotFoundException e) {
        // skip publisher injection as required classes are not on the classpath
        e.printStackTrace();
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        // afterwards dissociate the Thread from the Scope in the Container
        Container.dissociateThread();
        // and return the current context ClassLoader back to normal
        Thread.currentThread().setContextClassLoader(originalClassLoader);
    }
}
Also used : ContainerClassLoader(com.oracle.bedrock.runtime.java.container.ContainerClassLoader) PipeBasedRemoteChannel(com.oracle.bedrock.runtime.concurrent.PipeBasedRemoteChannel) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with ContainerClassLoader

use of com.oracle.bedrock.runtime.java.container.ContainerClassLoader in project oracle-bedrock by coherence-community.

the class ContainerBasedJavaApplicationLauncher method launch.

// TODO: think about what to do with sanity check
// /**
// * Performs a sanity check on the specified {@link JavaApplicationSchema}.
// * <p>
// * It's particularly important to perform sanity checks on {@link Options}
// * prior to realizing them in a container as some settings may not be appropriate or
// * achievable.
// *
// * @param options           the {@link Options}
// * @param schemaProperties  the system {@link Properties} that have been launched for the
// *                          {@link JavaApplication}
// */
// protected <T extends A, S extends ApplicationSchema<T>> void sanityCheck(Options    options,
// Properties schemaProperties)
// {
// // ensure that if JAVA_NET_PREFER_IPV4_STACK is requested by the schema it has also been
// // established at the  platform level as this is only where it can actually be achieved with Java 7+.
// String schemaPreferIPv4Stack = schemaProperties.getProperty(JavaApplication.JAVA_NET_PREFER_IPV4_STACK);
// 
// schemaPreferIPv4Stack = schemaPreferIPv4Stack == null ? "" : schemaPreferIPv4Stack.trim().toLowerCase();
// 
// String systemPreferIPv4Stack = System.getProperty(JavaApplication.JAVA_NET_PREFER_IPV4_STACK);
// 
// systemPreferIPv4Stack = systemPreferIPv4Stack == null ? "" : systemPreferIPv4Stack.trim().toLowerCase();
// 
// if (systemPreferIPv4Stack.isEmpty() &&!schemaPreferIPv4Stack.isEmpty())
// {
// LOGGER.warning("The schema [" + schema + "] defines the " + JavaApplication.JAVA_NET_PREFER_IPV4_STACK
// + " system property but it is not defined by the current process."
// + "Container-based applications requiring this system property must have it defined at the operating system level."
// + "eg: In your case it should be defined as; -D" + JavaApplication.JAVA_NET_PREFER_IPV4_STACK + "="
// + schemaPreferIPv4Stack);
// }
// else if (!systemPreferIPv4Stack.equals(schemaPreferIPv4Stack))
// {
// LOGGER.warning("The schema [" + schema + "] defines the " + JavaApplication.JAVA_NET_PREFER_IPV4_STACK
// + " system property but it is not defined by the current process in the same manner."
// + "Container-based applications requiring this system property must have it in the same manner at the operating system level."
// + "eg: In your case it should be defined as; -D" + JavaApplication.JAVA_NET_PREFER_IPV4_STACK + "="
// + schemaPreferIPv4Stack);
// }
// 
// // TODO: check that the JavaHome is not set or not different from the current platform setting
// }
@Override
public A launch(Platform platform, MetaClass<A> metaClass, OptionsByType optionsByType) {
    // establish the diagnostics output table
    Table diagnosticsTable = new Table();
    diagnosticsTable.getOptions().add(Table.orderByColumn(0));
    if (platform != null) {
        diagnosticsTable.addRow("Target Platform", platform.getName());
    }
    // ----- establish the launch Options for the Application -----
    // add the platform options
    OptionsByType launchOptions = OptionsByType.of(platform.getOptions().asArray());
    // add the meta-class options
    metaClass.onLaunching(platform, launchOptions);
    // add the launch specific options
    launchOptions.addAll(optionsByType);
    // ----- establish an identity for the application -----
    // add a unique runtime id for expression support
    launchOptions.add(Variable.with("bedrock.runtime.id", UUID.randomUUID()));
    // ----- establish default Profiles for this Platform (and Builder) -----
    // java applications can automatically detect the following profiles
    launchOptions.get(RemoteDebugging.class);
    launchOptions.get(CommercialFeatures.class);
    // auto-detect and add externally defined profiles
    launchOptions.addAll(Profiles.getProfiles());
    for (Profile profile : launchOptions.getInstancesOf(Profile.class)) {
        profile.onLaunching(platform, metaClass, launchOptions);
    }
    // ----- give the MetaClass a last chance to manipulate any options -----
    metaClass.onLaunch(platform, launchOptions);
    // ----- determine the display name for the application -----
    DisplayName displayName = getDisplayName(launchOptions);
    // ----- create and start the application in it's own classloader -----
    try {
        Table systemPropertiesTable = new Table();
        systemPropertiesTable.getOptions().add(Table.orderByColumn(0));
        systemPropertiesTable.getOptions().add(Cell.Separator.of(""));
        // establish the System Properties for the ContainerBasedJavaApplication
        Properties systemProperties = launchOptions.get(SystemProperties.class).resolve(platform, launchOptions);
        for (String propertyName : systemProperties.stringPropertyNames()) {
            String propertyValue = systemProperties.getProperty(propertyName);
            systemPropertiesTable.addRow(propertyName, propertyValue);
        }
        diagnosticsTable.addRow("System Properties", systemPropertiesTable.toString());
        // determine the predefined class path based on the launch options
        ClassPath classPath = launchOptions.get(ClassPath.class);
        Table classPathTable = classPath.getTable();
        classPathTable.getOptions().add(Cell.Separator.of(""));
        diagnosticsTable.addRow("Class Path", classPathTable.toString());
        // establish the ContainerClassLoader for the application
        ContainerClassLoader classLoader = ContainerClassLoader.newInstance(displayName.resolve(launchOptions), classPath, systemProperties);
        // Get the command line arguments
        List<String> argList = launchOptions.get(Arguments.class).resolve(platform, launchOptions);
        // Set the actual arguments used back into the options
        launchOptions.add(Arguments.of(argList));
        // determine the application class that we'll start
        ClassName className = launchOptions.get(ClassName.class);
        if (className == null) {
            throw new IllegalArgumentException("Java Application ClassName not specified");
        }
        String applicationClassName = className.getName();
        // determine the ApplicationController to use to control the process in the container
        // (either an ApplicationController provided as an Option or use the MetaClass if it's appropriate)
        ApplicationController controller = launchOptions.getOrSetDefault(ApplicationController.class, metaClass instanceof ApplicationController ? (ApplicationController) metaClass : null);
        if (controller == null) {
            // when an ApplicationController isn't defined, we default to using the
            // standard approach of executing the "main" method on the
            // specified Application Class
            controller = new StandardController(applicationClassName, argList);
            // as a courtesy let's make sure the application class is accessible via the classloader
            Class<?> applicationClass = classLoader.loadClass(applicationClassName);
        }
        diagnosticsTable.addRow("Application Class", applicationClassName);
        diagnosticsTable.addRow("Application", displayName.resolve(launchOptions));
        String arguments = "";
        for (String argument : argList) {
            arguments += argument + " ";
        }
        if (arguments.length() > 0) {
            diagnosticsTable.addRow("Application Arguments", arguments);
        }
        diagnosticsTable.addRow("Application Launch Time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.log(Level.INFO, "Oracle Bedrock " + Bedrock.getVersion() + ": Starting Application...\n" + "------------------------------------------------------------------------\n" + diagnosticsTable.toString() + "\n" + "------------------------------------------------------------------------\n");
        }
        // establish the ContainerBasedJavaProcess
        ContainerBasedJavaApplicationProcess process = new ContainerBasedJavaApplicationProcess(classLoader, controller, systemProperties);
        // register the defined RemoteEventListeners before the application starts so they can
        // immediately start receiving RemoteEvents
        RemoteEvents remoteEvents = launchOptions.get(RemoteEvents.class);
        remoteEvents.forEach((remoteEventListener, listenerOptions) -> process.addListener(remoteEventListener, listenerOptions));
        // notify the container of the scope to manage
        Container.manage(classLoader.getContainerScope());
        // start the process
        process.start(launchOptions);
        // the environment variables for the ContainerBasedJavaApplication
        // will be the environment variables for the Java Virtual Machine
        Properties environmentVariables = PropertiesBuilder.fromCurrentEnvironmentVariables().realize();
        diagnosticsTable.addRow("Environment Variables", "(based on this Java Virtual Machine)");
        // determine the application class that will represent the running application
        Class<? extends A> applicationClass = metaClass.getImplementationClass(platform, launchOptions);
        A application;
        try {
            // attempt to find a constructor(Platform, JavaApplicationProcess, Options)
            Constructor<? extends A> constructor = ReflectionHelper.getCompatibleConstructor(applicationClass, platform.getClass(), process.getClass(), launchOptions.getClass());
            // create the application
            application = constructor.newInstance(platform, process, launchOptions);
        } catch (Exception e) {
            throw new RuntimeException("Failed to instantiate the Application class specified by the MetaClass:" + metaClass);
        }
        if (JmxFeature.isSupportedBy(application)) {
            application.add(new JmxFeature());
        }
        // ----- notify the MetaClass that the application has been launched -----
        metaClass.onLaunched(platform, application, launchOptions);
        for (Profile profile : launchOptions.getInstancesOf(Profile.class)) {
            profile.onLaunched(platform, application, launchOptions);
        }
        // notify the ApplicationListener-based Options that the application has been launched
        for (ApplicationListener listener : launchOptions.getInstancesOf(ApplicationListener.class)) {
            listener.onLaunched(application);
        }
        return application;
    } catch (Exception e) {
        throw new RuntimeException("Failed to start ContainerBasedJavaProcess", e);
    }
}
Also used : RemoteEvents(com.oracle.bedrock.runtime.java.options.RemoteEvents) JmxFeature(com.oracle.bedrock.runtime.java.features.JmxFeature) Properties(java.util.Properties) SystemProperties(com.oracle.bedrock.runtime.java.options.SystemProperties) Profile(com.oracle.bedrock.runtime.Profile) DisplayName(com.oracle.bedrock.runtime.options.DisplayName) ClassName(com.oracle.bedrock.runtime.java.options.ClassName) ContainerClassLoader(com.oracle.bedrock.runtime.java.container.ContainerClassLoader) Table(com.oracle.bedrock.table.Table) Arguments(com.oracle.bedrock.runtime.options.Arguments) Date(java.util.Date) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) SystemProperties(com.oracle.bedrock.runtime.java.options.SystemProperties) ApplicationListener(com.oracle.bedrock.runtime.ApplicationListener) OptionsByType(com.oracle.bedrock.OptionsByType) SimpleDateFormat(java.text.SimpleDateFormat)

Example 3 with ContainerClassLoader

use of com.oracle.bedrock.runtime.java.container.ContainerClassLoader in project oracle-bedrock by coherence-community.

the class DummyClassPathApp method main.

/**
 * The Main Method.
 *
 * @param args
 */
public static void main(String[] args) {
    try {
        ClassLoader classLoader = DummyClassPathApp.class.getClassLoader();
        ClassPath classPath;
        if (classLoader instanceof ContainerClassLoader) {
            classPath = ((ContainerClassLoader) classLoader).getClassPath();
        } else {
            classPath = ClassPath.ofSystem();
        }
        for (String path : classPath) {
            System.out.println(path);
        }
        Class.forName(args[0]);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : ClassPath(com.oracle.bedrock.runtime.java.ClassPath) ContainerClassLoader(com.oracle.bedrock.runtime.java.container.ContainerClassLoader) ContainerClassLoader(com.oracle.bedrock.runtime.java.container.ContainerClassLoader)

Aggregations

ContainerClassLoader (com.oracle.bedrock.runtime.java.container.ContainerClassLoader)3 IOException (java.io.IOException)2 ExecutionException (java.util.concurrent.ExecutionException)2 OptionsByType (com.oracle.bedrock.OptionsByType)1 ApplicationListener (com.oracle.bedrock.runtime.ApplicationListener)1 Profile (com.oracle.bedrock.runtime.Profile)1 PipeBasedRemoteChannel (com.oracle.bedrock.runtime.concurrent.PipeBasedRemoteChannel)1 ClassPath (com.oracle.bedrock.runtime.java.ClassPath)1 JmxFeature (com.oracle.bedrock.runtime.java.features.JmxFeature)1 ClassName (com.oracle.bedrock.runtime.java.options.ClassName)1 RemoteEvents (com.oracle.bedrock.runtime.java.options.RemoteEvents)1 SystemProperties (com.oracle.bedrock.runtime.java.options.SystemProperties)1 Arguments (com.oracle.bedrock.runtime.options.Arguments)1 DisplayName (com.oracle.bedrock.runtime.options.DisplayName)1 Table (com.oracle.bedrock.table.Table)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 Properties (java.util.Properties)1