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);
}
}
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);
}
}
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();
}
}
Aggregations