diff --git a/symmetric-assemble/src/asciidoc/appendix/mariadb.ad b/symmetric-assemble/src/asciidoc/appendix/mariadb.ad index c7bb6bf832..f157560867 100644 --- a/symmetric-assemble/src/asciidoc/appendix/mariadb.ad +++ b/symmetric-assemble/src/asciidoc/appendix/mariadb.ad @@ -2,3 +2,22 @@ === MariaDB See MySQL notes. You can use either the MySQL or MariaDB driver for this dialect. + +.Supported Data Types +|=== +|Data Type|Supported? + +|TinyInt, SmallInt, MediumInt, Int, BigInt|Yes +|Decimal, Numeric|Yes +|Float, Double|Yes +|Bit|Yes +|Char, Varchar|Yes +|Binary, VarBinary|Yes +|TinyBlob|No +|Blob, MediumBlob, Longblob|Yes +|TinyText, Text, MediumText, LongText|Yes +|Enum|No +|Set|No +|Date, Time, DateTime, TimeStamp, Year|Yes +|Point, LineString, Polygon, MultiPoint, MultiLinestring, MultiPolygon, GeometryCollection, Geometry| No +|=== \ No newline at end of file diff --git a/symmetric-assemble/src/asciidoc/appendix/mysql.ad b/symmetric-assemble/src/asciidoc/appendix/mysql.ad index a65102ce5b..aa0cdd0958 100644 --- a/symmetric-assemble/src/asciidoc/appendix/mysql.ad +++ b/symmetric-assemble/src/asciidoc/appendix/mysql.ad @@ -39,3 +39,21 @@ If you are using UTF-8 encoding in the database, you might consider using the ch ---- jdbc:mysql://hostname/databasename?tinyInt1isBit=false&characterEncoding=utf8 ---- + +.Supported Data Types +|=== +|Data Type|Supported? + +|TinyInt, SmallInt, Int, MediumInt, BigInt|Yes +|Decimal, Numeric|Yes +|Float, Double|Yes +|Bit|Yes +|Date, DateTime, TimeStamp, Time, Year|Yes +|Char, Varchar|Yes +|Binary, VarBinary|Yes +|TinyBlob, Blob, MediumBlob, BigBlob|Yes +|TinyText, Text, MediumText, BigText|Yes +|Enum|No +|Set|No +|Geometry, Point, LineString, Polygon, GeometryCollection, MultiPoint, MultiLinestring, MultiPolygon|No +|=== \ No newline at end of file diff --git a/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperConfig.java b/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperConfig.java index f0068b4880..743ff9456d 100644 --- a/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperConfig.java +++ b/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperConfig.java @@ -141,7 +141,7 @@ public ArrayList getCommand(boolean isConsole) { String version = System.getProperty("java.version"); boolean expandWildcard = version != null && version.startsWith("1.5"); - ArrayList cp = prop.get("wrapper.java.classpath"); + List cp = getListProperty(prop, "wrapper.java.classpath"); StringBuilder sb = new StringBuilder(cp.size()); for (int i = 0; i < cp.size(); i++) { if (i > 0) { @@ -159,9 +159,10 @@ public ArrayList getCommand(boolean isConsole) { cmdList.add("-cp"); cmdList.add(sb.toString()); - cmdList.addAll(prop.get("wrapper.java.additional")); + List javaAdditional = getListProperty(prop, "wrapper.java.additional"); + cmdList.addAll(javaAdditional); - ArrayList appParams = prop.get("wrapper.app.parameter"); + List appParams = getListProperty(prop, "wrapper.app.parameter"); appParams.remove("--no-log-console"); cmdList.addAll(appParams); @@ -239,4 +240,12 @@ private String getProperty(Map> prop, String name, Str } return value; } + + private List getListProperty(Map> prop, String name) { + ArrayList value = prop.get(name); + if (value == null) { + value = new ArrayList(0); + } + return value; + } } diff --git a/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperService.java b/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperService.java index 9887225d22..d9027a91ac 100644 --- a/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperService.java +++ b/symmetric-wrapper/src/main/java/org/jumpmind/symmetric/wrapper/WrapperService.java @@ -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; @@ -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 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 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(); + } } } @@ -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() {