final String classPath) throws Exception {
ExecDescriptor exDesc = new ExecDescriptor();
String rioHome = System.getProperty("RIO_HOME");
if(rioHome==null)
throw new ServiceBeanInstantiationException(String.format("Cannot exec service [%s], unknown RIO_HOME system property",
sElem.getName()));
String classPathToUse;
if(classPath==null)
classPathToUse = CommandLineHelper.generateRioStarterClassPath();
else
classPathToUse = classPath;
/* Create a normalized service name, translating " " to "_" and
* appending the instance ID to the name. This will be used for the
* log name and the registry bind name */
String normalizedServiceName = RMIServiceNameHelper.createNormalizedServiceName(sElem);
String serviceBindName = RMIServiceNameHelper.createBindName(sElem);
/* Get the Cybernode's RMI Registry */
int regPort = RegistryUtil.checkRegistry();
String sPort = Integer.toString(regPort);
String logDir = getLogDirectory(config, sElem.getOperationalStringName());
if(!logDir.endsWith(File.separator))
logDir = logDir+File.separator;
logger.info("Logging for {} will be sent to {}", sElem.getName(), logDir);
/* Create command line */
exDesc.setCommandLine(CommandLineHelper.getJava());
/* Create input args */
StringBuilder inputArgsBuilder = new StringBuilder();
inputArgsBuilder.append(CommandLineHelper.getClassPath(classPathToUse));
String jvmOptions = (sElem.getExecDescriptor()==null? null: sElem.getExecDescriptor().getInputArgs());
inputArgsBuilder.append(CommandLineHelper.createInputArgs(normalizedServiceName,
serviceBindName,
sPort,
jvmOptions,
logDir));
inputArgsBuilder.append(CommandLineHelper.getStarterClass()).append(" ");
String serviceBeanExecStarter = CommandLineHelper.getStarterConfig(rioHome);
logger.trace("Using service bean exec starter: {}", serviceBeanExecStarter);
inputArgsBuilder.append(serviceBeanExecStarter);
exDesc.setInputArgs(inputArgsBuilder.toString());
exDesc.setWorkingDirectory(System.getProperty("user.dir"));
/* If we have an exec descriptor, make add any environment settings the
* service has declared */
if(sElem.getExecDescriptor()!=null) {
Map<String, String> env = sElem.getExecDescriptor().getEnvironment();
for(Map.Entry<String, String> entry : env.entrySet()) {
env.put(entry.getKey(), PropertyHelper.expandProperties(entry.getValue()));
}
exDesc.setEnvironment(env);
}
String serviceOut = logDir+normalizedServiceName+".out";
exDesc.setStdErrFileName(serviceOut);
exDesc.setStdOutFileName(serviceOut);
try {
Registry registry = LocateRegistry.getRegistry(regPort);
ForkedServiceBeanListener forkedServiceListener = new ForkedServiceBeanListener(discardManager);
ServiceBeanExecListener listener = forkedServiceListener.getServiceBeanExecListener();
long start = System.currentTimeMillis();
Shell shell = ShellFactory.createShell();
try {
String shellTemplate = (String)config.getEntry(COMPONENT,
"serviceBeanExecShellTemplate",
String.class,
null);
if(shellTemplate!=null)
shell.setShellTemplate(shellTemplate);
} catch (ConfigurationException e) {
logger.warn("Cannot get shell template from configuration, continue with default");
}
logger.info("Invoke {}.exec for {}, working directory {}",
shell.getClass().getName(), ServiceLogUtil.logName(sElem), exDesc.getWorkingDirectory());
manager = shell.exec(exDesc);
forkedServiceListener.setName(serviceBindName);
forkedServiceListener.setRegistryPort(regPort);
long wait = 0;
do {
try {
execHandler = (ServiceBeanExecutor)registry.lookup(serviceBindName);
forkedServiceListener.createFDH(execHandler);
execHandler.setUuid(uuid);
execHandler.setServiceBeanExecListener(listener);
if(installedPlatformCapabilities!=null && installedPlatformCapabilities.length>0)
execHandler.applyPlatformCapabilities(installedPlatformCapabilities);
instance = execHandler.instantiate(sElem, opStringMgr);
long activationTime = System.currentTimeMillis()-start;
logger.info("Forked instance created for [{}], pid=[{}], activation time={} ms",
serviceBindName, manager.getPid(), activationTime);
break;
} catch (NotBoundException e) {
try {
Thread.sleep(1000);
wait++;
} catch (InterruptedException e1) {
logger.warn("Interrupted waiting for ServiceBean [{}] to register into Registry",
serviceBindName);
}
}
} while (wait < forkedServiceWaitTime);
if (wait >= forkedServiceWaitTime) {
logger.warn("Timed out waiting for [{}]. Waited [{}] seconds, configured wait " +
"time is [{}] seconds. Killing spawned process and unregistering from local " +
"registry. Check the service's output log to determine root cause(s)",
serviceBindName, wait, forkedServiceWaitTime);
manager.destroy(true);
throw new ServiceBeanInstantiationException("Failed to fork");
}
} catch (Exception e) {
unregister(regPort, serviceBindName);
logger.info("Terminate process for ServiceBean [{}]", serviceBindName);