Skip to content

Commit

Permalink
0002607: SymmetricDS wrapper fails to log when sym_service.conf is
Browse files Browse the repository at this point in the history
misconfigured.
  • Loading branch information
mmichalek committed May 23, 2016
1 parent 38f0acb commit da490da
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 82 deletions.
Expand Up @@ -141,7 +141,7 @@ public ArrayList<String> getCommand(boolean isConsole) {
String version = System.getProperty("java.version");
boolean expandWildcard = version != null && version.startsWith("1.5");

ArrayList<String> cp = prop.get("wrapper.java.classpath");
List<String> cp = getListProperty(prop, "wrapper.java.classpath");
StringBuilder sb = new StringBuilder(cp.size());
for (int i = 0; i < cp.size(); i++) {
if (i > 0) {
Expand All @@ -159,9 +159,10 @@ public ArrayList<String> getCommand(boolean isConsole) {
cmdList.add("-cp");
cmdList.add(sb.toString());

cmdList.addAll(prop.get("wrapper.java.additional"));
List<String> javaAdditional = getListProperty(prop, "wrapper.java.additional");
cmdList.addAll(javaAdditional);

ArrayList<String> appParams = prop.get("wrapper.app.parameter");
List<String> appParams = getListProperty(prop, "wrapper.app.parameter");
appParams.remove("--no-log-console");
cmdList.addAll(appParams);

Expand Down Expand Up @@ -239,4 +240,12 @@ private String getProperty(Map<String, ArrayList<String>> prop, String name, Str
}
return value;
}

private List<String> getListProperty(Map<String, ArrayList<String>> prop, String name) {
ArrayList<String> value = prop.get(name);
if (value == null) {
value = new ArrayList<String>(0);
}
return value;
}
}
Expand Up @@ -27,6 +27,8 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.LogManager;
Expand Down Expand Up @@ -127,91 +129,102 @@ protected void execJava(boolean isConsole) {
throw new WrapperException(Constants.RC_FAIL_WRITE_LOG_FILE, 0, "Cannot open log file " + config.getLogFile(), e);
}

int pid = getCurrentPid();
writePidToFile(pid, config.getWrapperPidFile());
logger.log(Level.INFO, "Started wrapper as PID " + pid);

ArrayList<String> cmd = config.getCommand(isConsole);
String cmdString = commandToString(cmd);
boolean usingHeapDump = cmdString.indexOf("-XX:+HeapDumpOnOutOfMemoryError") != -1;
logger.log(Level.INFO, "Working directory is " + System.getProperty("user.dir"));

long startTime = 0;
int startCount = 0;
boolean startProcess = true, restartDetected = false;
int serverPid = 0;

while (keepRunning) {
if (startProcess) {
logger.log(Level.INFO, "Executing " + cmdString);
if (startCount == 0) {
updateStatus(Status.START_PENDING);
}
startTime = System.currentTimeMillis();
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);

try {
child = pb.start();
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to execute: " + e.getMessage());
updateStatus(Status.STOPPED);
throw new WrapperException(Constants.RC_FAIL_EXECUTION, -1, "Failed executing server", e);
}

serverPid = getProcessPid(child);
logger.log(Level.INFO, "Started server as PID " + serverPid);
writePidToFile(serverPid, config.getServerPidFile());

if (startCount == 0) {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
updateStatus(Status.RUNNING);
}
startProcess = false;
startCount++;
} else {
try {
logger.log(Level.INFO, "Watching output of java process");
childReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = null;

while ((line = childReader.readLine()) != null) {
System.out.println(line);
logger.log(Level.INFO, line, "java");
if ((usingHeapDump && line.matches("Heap dump file created.*")) ||
(!usingHeapDump && line.matches("java.lang.OutOfMemoryError.*")) ||
line.matches(".*java.net.BindException.*")) {
logger.log(Level.SEVERE, "Stopping server because its output matches a failure condition");
child.destroy();
childReader.close();
stopProcess(serverPid, "symmetricds");
break;
}
if (line.equalsIgnoreCase("Restarting")) {
restartDetected = true;
}
try {
int pid = getCurrentPid();
writePidToFile(pid, config.getWrapperPidFile());
logger.log(Level.INFO, "Started wrapper as PID " + pid);

ArrayList<String> cmd = config.getCommand(isConsole);
String cmdString = commandToString(cmd);
boolean usingHeapDump = cmdString.indexOf("-XX:+HeapDumpOnOutOfMemoryError") != -1;
logger.log(Level.INFO, "Working directory is " + System.getProperty("user.dir"));

long startTime = 0;
int startCount = 0;
boolean startProcess = true, restartDetected = false;
int serverPid = 0;

while (keepRunning) {
if (startProcess) {
logger.log(Level.INFO, "Executing " + cmdString);
if (startCount == 0) {
updateStatus(Status.START_PENDING);
}
logger.log(Level.INFO, "End of output from java process");
} catch (IOException e) {
logger.log(Level.SEVERE, "Error while reading from process");
}

if (restartDetected) {
logger.log(Level.INFO, "Restart detected");
restartDetected = false;
startProcess = true;
} else if (keepRunning) {
logger.log(Level.SEVERE, "Unexpected exit from server: " + child.exitValue());
long runTime = System.currentTimeMillis() - startTime;
if (System.currentTimeMillis() - startTime < 7000) {
logger.log(Level.SEVERE, "Stopping because server exited too quickly after only " + runTime + " milliseconds");
startTime = System.currentTimeMillis();
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);

try {
child = pb.start();
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to execute: " + e.getMessage());
updateStatus(Status.STOPPED);
throw new WrapperException(Constants.RC_SERVER_EXITED, child.exitValue(), "Unexpected exit from server");
} else {
throw new WrapperException(Constants.RC_FAIL_EXECUTION, -1, "Failed executing server", e);
}

serverPid = getProcessPid(child);
logger.log(Level.INFO, "Started server as PID " + serverPid);
writePidToFile(serverPid, config.getServerPidFile());

if (startCount == 0) {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
updateStatus(Status.RUNNING);
}
startProcess = false;
startCount++;
} else {
try {
logger.log(Level.INFO, "Watching output of java process");
childReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = null;

while ((line = childReader.readLine()) != null) {
System.out.println(line);
logger.log(Level.INFO, line, "java");
if ((usingHeapDump && line.matches("Heap dump file created.*")) ||
(!usingHeapDump && line.matches("java.lang.OutOfMemoryError.*")) ||
line.matches(".*java.net.BindException.*")) {
logger.log(Level.SEVERE, "Stopping server because its output matches a failure condition");
child.destroy();
childReader.close();
stopProcess(serverPid, "symmetricds");
break;
}
if (line.equalsIgnoreCase("Restarting")) {
restartDetected = true;
}
}
logger.log(Level.INFO, "End of output from java process");
} catch (IOException e) {
logger.log(Level.SEVERE, "Error while reading from process");
}

if (restartDetected) {
logger.log(Level.INFO, "Restart detected");
restartDetected = false;
startProcess = true;
} else if (keepRunning) {
logger.log(Level.SEVERE, "Unexpected exit from server: " + child.exitValue());
long runTime = System.currentTimeMillis() - startTime;
if (System.currentTimeMillis() - startTime < 7000) {
logger.log(Level.SEVERE, "Stopping because server exited too quickly after only " + runTime + " milliseconds");
updateStatus(Status.STOPPED);
throw new WrapperException(Constants.RC_SERVER_EXITED, child.exitValue(), "Unexpected exit from server");
} else {
startProcess = true;
}
}
}
}
} catch (Throwable ex) {
// The default logging config doesn't show the stack trace here, so include it in the message.
try {
logger.log(Level.SEVERE, "Exception caught.\r\n" + getStackTrace(ex));
updateStatus(Status.STOPPED);
throw new WrapperException(Constants.RC_SERVER_EXITED, child.exitValue(), "Exception caught.");
} catch (Throwable ex2) {
ex.printStackTrace();
}
}
}

Expand Down Expand Up @@ -372,6 +385,13 @@ protected boolean waitForPid(int pid) {

protected void updateStatus(Status status) {
}

private static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}

class ShutdownHook extends Thread {
public void run() {
Expand Down

0 comments on commit da490da

Please sign in to comment.