in twill-core/src/main/java/org/apache/twill/internal/TwillContainerLauncher.java [83:154]
public TwillContainerController start(RunId runId, int instanceId, Class<?> mainClass, String classPath) {
// Clean up zookeeper path in case this is a retry and there are old messages and state there.
Futures.getUnchecked(ZKOperations.ignoreError(
ZKOperations.recursiveDelete(zkClient, "/" + runId), KeeperException.NoNodeException.class, null));
// Adds all file to be localized to container
launchContext.addResources(runtimeSpec.getLocalFiles());
// Optionally localize secure store.
try {
if (secureStoreLocation != null && secureStoreLocation.exists()) {
launchContext.addResources(new DefaultLocalFile(Constants.Files.CREDENTIALS,
secureStoreLocation.toURI(),
secureStoreLocation.lastModified(),
secureStoreLocation.length(), false, null));
}
} catch (IOException e) {
LOG.warn("Failed to launch container with secure store {}.", secureStoreLocation);
}
// Currently no reporting is supported for runnable containers
launchContext
.addEnvironment(EnvKeys.TWILL_RUN_ID, runId.getId())
.addEnvironment(EnvKeys.TWILL_RUNNABLE_NAME, runtimeSpec.getName())
.addEnvironment(EnvKeys.TWILL_INSTANCE_ID, Integer.toString(instanceId))
.addEnvironment(EnvKeys.TWILL_INSTANCE_COUNT, Integer.toString(instanceCount));
// assemble the command based on jvm options
ImmutableList.Builder<String> commandBuilder = ImmutableList.builder();
String firstCommand;
if (jvmOpts.getDebugOptions().doDebug(runtimeSpec.getName())) {
// for debugging we run a quick Java program to find a free port, then pass that port as the debug port and also
// as a System property to the runnable (Java has no general way to determine the port from within the JVM).
// PORT=$(java FindFreePort) && java -agentlib:jdwp=...,address=\$PORT -Dtwill.debug.port=\$PORT... TwillLauncher
// The $ must be escaped, otherwise it gets expanded (to "") before the command is submitted.
String suspend = jvmOpts.getDebugOptions().doSuspend() ? "y" : "n";
firstCommand = "TWILL_DEBUG_PORT=$($JAVA_HOME/bin/java";
commandBuilder.add("-cp", Constants.Files.LAUNCHER_JAR,
FindFreePort.class.getName() + ")",
"&&", // this will stop if FindFreePort fails
"$JAVA_HOME/bin/java",
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=" + suspend + "," +
"address=\\$TWILL_DEBUG_PORT",
"-Dtwill.debug.port=\\$TWILL_DEBUG_PORT"
);
} else {
firstCommand = "$JAVA_HOME/bin/java";
}
int memory = Resources.computeMaxHeapSize(containerInfo.getMemoryMB(), reservedMemory, Constants.HEAP_MIN_RATIO);
commandBuilder.add("-Djava.io.tmpdir=tmp",
"-Dyarn.container=$" + EnvKeys.YARN_CONTAINER_ID,
"-Dtwill.runnable=$" + EnvKeys.TWILL_APP_NAME + ".$" + EnvKeys.TWILL_RUNNABLE_NAME,
"-cp", Constants.Files.LAUNCHER_JAR + ":" + classPath,
"-Xmx" + memory + "m");
if (jvmOpts.getExtraOptions() != null) {
commandBuilder.add(jvmOpts.getExtraOptions());
}
commandBuilder.add(TwillLauncher.class.getName(),
Constants.Files.CONTAINER_JAR,
mainClass.getName(),
Boolean.TRUE.toString());
List<String> command = commandBuilder.build();
ProcessController<Void> processController = launchContext
.addCommand(firstCommand, command.toArray(new String[command.size()]))
.launch();
TwillContainerControllerImpl controller = new TwillContainerControllerImpl(zkClient, runId, processController);
controller.start();
return controller;
}