Search in sources :

Example 1 with LocalProcessBuilder

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

the class SimpleApplicationLauncher method launch.

@Override
public Application launch(Platform platform, MetaClass<Application> 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()).addAll(optionsByType);
    // add the meta-class options
    metaClass.onLaunching(platform, launchOptions);
    // ----- establish default Profiles for this Platform (and Builder) -----
    // 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 -----
    // ensure there's a display name
    DisplayName displayName = launchOptions.getOrSetDefault(DisplayName.class, DisplayName.of(launchOptions.get(Executable.class).getName()));
    // ---- establish the underlying ProcessBuilder -----
    // determine the Executable
    Executable executable = launchOptions.get(Executable.class);
    if (executable == null) {
        throw new IllegalArgumentException("Failed to define an Executable option");
    }
    // we'll use the native operating system process builder to create
    // and manage the local application process
    LocalProcessBuilder processBuilder = createProcessBuilder(StringHelper.doubleQuoteIfNecessary(executable.getName()));
    // ----- establish the working directory -----
    // set the working directory for the Process
    WorkingDirectory workingDirectory = launchOptions.getOrSetDefault(WorkingDirectory.class, WorkingDirectory.currentDirectory());
    File directory = workingDirectory.resolve(platform, launchOptions);
    // Set the resolved working directory back into the options
    launchOptions.add(WorkingDirectory.at(directory));
    if (directory != null) {
        processBuilder.directory(directory);
        diagnosticsTable.addRow("Working Directory", directory.toString());
    }
    // ----- establish environment variables -----
    EnvironmentVariables environmentVariables = launchOptions.get(EnvironmentVariables.class);
    switch(environmentVariables.getSource()) {
        case Custom:
            processBuilder.environment().clear();
            diagnosticsTable.addRow("Environment Variables", "(cleared)");
            break;
        case ThisApplication:
            processBuilder.environment().clear();
            processBuilder.environment().putAll(System.getenv());
            diagnosticsTable.addRow("Environment Variables", "(based on parent process)");
            break;
        case TargetPlatform:
            diagnosticsTable.addRow("Environment Variables", "(based on platform defaults)");
            break;
    }
    // add the optionally defined environment variables
    Properties variables = environmentVariables.realize(platform, launchOptions.asArray());
    for (String variableName : variables.stringPropertyNames()) {
        processBuilder.environment().put(variableName, variables.getProperty(variableName));
    }
    if (variables.size() > 0) {
        Table table = Tabularize.tabularize(variables);
        diagnosticsTable.addRow("", table.toString());
    }
    // ----- establish the application command line to execute -----
    List<String> command = processBuilder.command();
    // add the arguments to the command for the process
    List<String> arguments = launchOptions.get(Arguments.class).resolve(platform, launchOptions);
    command.addAll(arguments);
    diagnosticsTable.addRow("Application", displayName.resolve(launchOptions));
    diagnosticsTable.addRow("Application Executable ", executable.getName());
    if (arguments.size() > 0) {
        diagnosticsTable.addRow("Application Arguments ", arguments.stream().collect(Collectors.joining(" ")));
    }
    diagnosticsTable.addRow("Application Launch Time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    // set the actual arguments used back into the options
    launchOptions.add(Arguments.of(arguments));
    // should the standard error be redirected to the standard out?
    ErrorStreamRedirection redirection = launchOptions.get(ErrorStreamRedirection.class);
    processBuilder.redirectErrorStream(redirection.isEnabled());
    boolean launchLogging = optionsByType.get(LaunchLogging.class).isEnabled();
    if (launchLogging && LOGGER.isLoggable(Level.INFO)) {
        LOGGER.log(Level.INFO, "Oracle Bedrock " + Bedrock.getVersion() + ": Starting Application...\n" + "------------------------------------------------------------------------\n" + diagnosticsTable.toString() + "\n" + "------------------------------------------------------------------------\n");
    }
    // ----- start the process and establish the application -----
    // create and start the native process
    Process process;
    try {
        process = processBuilder.start(launchOptions);
    } catch (IOException e) {
        throw new RuntimeException("Failed to build the underlying native process for the application", e);
    }
    // determine the application class that will represent the running application
    Class<? extends Application> applicationClass = metaClass.getImplementationClass(platform, launchOptions);
    Application application;
    try {
        // attempt to find a constructor(Platform, LocalApplicationProcess, Options)
        Constructor<? extends Application> constructor = ReflectionHelper.getCompatibleConstructor(applicationClass, platform.getClass(), LocalApplicationProcess.class, OptionsByType.class);
        // create the application
        application = constructor.newInstance(platform, new LocalApplicationProcess(process), launchOptions);
    } catch (Exception e) {
        throw new RuntimeException("Failed to instantiate the Application class specified by the MetaClass:" + metaClass, e);
    }
    // ----- 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 realized
    for (ApplicationListener listener : launchOptions.getInstancesOf(ApplicationListener.class)) {
        listener.onLaunched(application);
    }
    return application;
}
Also used : LocalProcessBuilder(com.oracle.bedrock.runtime.java.LocalProcessBuilder) SimpleLocalProcessBuilder(com.oracle.bedrock.runtime.java.SimpleLocalProcessBuilder) Properties(java.util.Properties) ErrorStreamRedirection(com.oracle.bedrock.runtime.options.ErrorStreamRedirection) EnvironmentVariables(com.oracle.bedrock.runtime.options.EnvironmentVariables) LaunchLogging(com.oracle.bedrock.options.LaunchLogging) DisplayName(com.oracle.bedrock.runtime.options.DisplayName) Executable(com.oracle.bedrock.runtime.options.Executable) WorkingDirectory(com.oracle.bedrock.runtime.options.WorkingDirectory) Table(com.oracle.bedrock.table.Table) Arguments(com.oracle.bedrock.runtime.options.Arguments) IOException(java.io.IOException) Date(java.util.Date) IOException(java.io.IOException) OptionsByType(com.oracle.bedrock.OptionsByType) File(java.io.File) SimpleDateFormat(java.text.SimpleDateFormat)

Aggregations

OptionsByType (com.oracle.bedrock.OptionsByType)1 LaunchLogging (com.oracle.bedrock.options.LaunchLogging)1 LocalProcessBuilder (com.oracle.bedrock.runtime.java.LocalProcessBuilder)1 SimpleLocalProcessBuilder (com.oracle.bedrock.runtime.java.SimpleLocalProcessBuilder)1 Arguments (com.oracle.bedrock.runtime.options.Arguments)1 DisplayName (com.oracle.bedrock.runtime.options.DisplayName)1 EnvironmentVariables (com.oracle.bedrock.runtime.options.EnvironmentVariables)1 ErrorStreamRedirection (com.oracle.bedrock.runtime.options.ErrorStreamRedirection)1 Executable (com.oracle.bedrock.runtime.options.Executable)1 WorkingDirectory (com.oracle.bedrock.runtime.options.WorkingDirectory)1 Table (com.oracle.bedrock.table.Table)1 File (java.io.File)1 IOException (java.io.IOException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 Properties (java.util.Properties)1