You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/02/22 11:54:39 UTC
[1/3] camel git commit: CAMEL-8241: Work around bug in commons-exec
to get camel-exec to work on unix with java 8.
Repository: camel
Updated Branches:
refs/heads/camel-2.14.x 0231cdc24 -> 0462bc13e
refs/heads/master 55cc138ae -> 4283b0598
CAMEL-8241: Work around bug in commons-exec to get camel-exec to work on unix with java 8.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4283b059
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4283b059
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4283b059
Branch: refs/heads/master
Commit: 4283b05984ff7d6ca1dfc7e0103f950a4eb144c6
Parents: 55cc138
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Feb 22 11:54:32 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Feb 22 11:54:32 2015 +0100
----------------------------------------------------------------------
.../java/org/apache/camel/component/exec/ExecProducer.java | 3 ++-
.../camel/component/exec/impl/DefaultExecCommandExecutor.java | 6 ------
2 files changed, 2 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/4283b059/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
index 49e1457..04b3917 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
@@ -45,7 +45,8 @@ public class ExecProducer extends DefaultProducer {
ExecCommandExecutor executor = endpoint.getCommandExecutor();
if (executor == null) {
- executor = new DefaultExecCommandExecutor(exchange);
+ // create a new non-shared executor
+ executor = new DefaultExecCommandExecutor();
}
log.info("Executing {}", execCommand);
http://git-wip-us.apache.org/repos/asf/camel/blob/4283b059/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
index 33cf6a2..4ca391d 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
@@ -51,12 +51,6 @@ public class DefaultExecCommandExecutor implements ExecCommandExecutor {
private static final Logger LOG = LoggerFactory.getLogger(DefaultExecCommandExecutor.class);
- private final Exchange exchange;
-
- public DefaultExecCommandExecutor(Exchange exchange) {
- this.exchange = exchange;
- }
-
public ExecResult execute(ExecCommand command) {
notNull(command, "command");
[3/3] camel git commit: CAMEL-8241: Work around bug in commons-exec
to get camel-exec to work on unix with java 8.
Posted by da...@apache.org.
CAMEL-8241: Work around bug in commons-exec to get camel-exec to work on unix with java 8.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/0462bc13
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/0462bc13
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/0462bc13
Branch: refs/heads/camel-2.14.x
Commit: 0462bc13e297b5a0a11c4b1d8ca0c3a61a09edd0
Parents: bbbb394
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Feb 22 11:54:32 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Feb 22 11:55:29 2015 +0100
----------------------------------------------------------------------
.../java/org/apache/camel/component/exec/ExecProducer.java | 3 ++-
.../camel/component/exec/impl/DefaultExecCommandExecutor.java | 6 ------
2 files changed, 2 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/0462bc13/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
index 49e1457..04b3917 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
@@ -45,7 +45,8 @@ public class ExecProducer extends DefaultProducer {
ExecCommandExecutor executor = endpoint.getCommandExecutor();
if (executor == null) {
- executor = new DefaultExecCommandExecutor(exchange);
+ // create a new non-shared executor
+ executor = new DefaultExecCommandExecutor();
}
log.info("Executing {}", execCommand);
http://git-wip-us.apache.org/repos/asf/camel/blob/0462bc13/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
index 33cf6a2..4ca391d 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
@@ -51,12 +51,6 @@ public class DefaultExecCommandExecutor implements ExecCommandExecutor {
private static final Logger LOG = LoggerFactory.getLogger(DefaultExecCommandExecutor.class);
- private final Exchange exchange;
-
- public DefaultExecCommandExecutor(Exchange exchange) {
- this.exchange = exchange;
- }
-
public ExecResult execute(ExecCommand command) {
notNull(command, "command");
[2/3] camel git commit: CAMEL-8241: Work around bug in commons-exec
to get camel-exec to work on unix with java 8.
Posted by da...@apache.org.
CAMEL-8241: Work around bug in commons-exec to get camel-exec to work on unix with java 8.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/bbbb3942
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/bbbb3942
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/bbbb3942
Branch: refs/heads/camel-2.14.x
Commit: bbbb3942e6ff42b5c0018e0770f3f55e207b527c
Parents: 0231cdc
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Feb 22 11:51:21 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Feb 22 11:55:24 2015 +0100
----------------------------------------------------------------------
.../component/exec/ExecDefaultExecutor.java | 45 +++++++
.../camel/component/exec/ExecEndpoint.java | 1 -
.../camel/component/exec/ExecProducer.java | 9 +-
.../exec/impl/DefaultExecCommandExecutor.java | 29 ++++-
.../camel/component/exec/ExecEndpointTest.java | 3 -
.../component/exec/ExecJava8IssueTest.java | 119 +++++++++++++++++++
6 files changed, 200 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecDefaultExecutor.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecDefaultExecutor.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecDefaultExecutor.java
new file mode 100644
index 0000000..14df04e
--- /dev/null
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecDefaultExecutor.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.exec;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+
+public class ExecDefaultExecutor extends DefaultExecutor {
+
+ private transient Process process;
+
+ public ExecDefaultExecutor() {
+ }
+
+ @Override
+ protected Process launch(CommandLine command, Map<String, String> env, File dir) throws IOException {
+ process = super.launch(command, env, dir);
+ return process;
+ }
+
+ public int getExitValue() {
+ if (process != null && !process.isAlive()) {
+ return process.exitValue();
+ }
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
index 8851328..202ac70 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
@@ -61,7 +61,6 @@ public class ExecEndpoint extends DefaultEndpoint {
super(uri, component);
this.timeout = NO_TIMEOUT;
this.binding = new DefaultExecBinding();
- this.commandExecutor = new DefaultExecCommandExecutor();
}
public Producer createProducer() throws Exception {
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
index aa125d4..49e1457 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecProducer.java
@@ -17,6 +17,7 @@
package org.apache.camel.component.exec;
import org.apache.camel.Exchange;
+import org.apache.camel.component.exec.impl.DefaultExecCommandExecutor;
import org.apache.camel.impl.DefaultProducer;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -42,8 +43,14 @@ public class ExecProducer extends DefaultProducer {
public void process(Exchange exchange) throws Exception {
ExecCommand execCommand = getBinding().readInput(exchange, endpoint);
+ ExecCommandExecutor executor = endpoint.getCommandExecutor();
+ if (executor == null) {
+ executor = new DefaultExecCommandExecutor(exchange);
+ }
+
log.info("Executing {}", execCommand);
- ExecResult result = endpoint.getCommandExecutor().execute(execCommand);
+ ExecResult result = executor.execute(execCommand);
+
ObjectHelper.notNull(result, "The command executor must return a not-null result");
log.info("The command {} had exit value {}", execCommand, result.getExitValue());
if (result.getExitValue() != 0) {
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
index 1de2782..33cf6a2 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
@@ -23,8 +23,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
+import org.apache.camel.Exchange;
import org.apache.camel.component.exec.ExecCommand;
import org.apache.camel.component.exec.ExecCommandExecutor;
+import org.apache.camel.component.exec.ExecDefaultExecutor;
import org.apache.camel.component.exec.ExecEndpoint;
import org.apache.camel.component.exec.ExecException;
import org.apache.camel.component.exec.ExecResult;
@@ -49,6 +51,12 @@ public class DefaultExecCommandExecutor implements ExecCommandExecutor {
private static final Logger LOG = LoggerFactory.getLogger(DefaultExecCommandExecutor.class);
+ private final Exchange exchange;
+
+ public DefaultExecCommandExecutor(Exchange exchange) {
+ this.exchange = exchange;
+ }
+
public ExecResult execute(ExecCommand command) {
notNull(command, "command");
@@ -76,6 +84,25 @@ public class DefaultExecCommandExecutor implements ExecCommandExecutor {
LOG.error("ExecException while executing command: " + command.toString() + " - " + ee.getMessage());
throw new ExecException("Failed to execute command " + command, ee);
} catch (IOException ioe) {
+ // workaround to ignore if the stream was already closes due some race condition in commons-exec
+ String msg = ioe.getMessage();
+ if ("Stream closed".equals(msg)) {
+ LOG.debug("Ignoring Stream closed IOException", ioe);
+ // if the size is zero, we have no output, so construct the result
+ // with null (required by ExecResult)
+ InputStream stdout = out.size() == 0 ? null : new ByteArrayInputStream(out.toByteArray());
+ InputStream stderr = err.size() == 0 ? null : new ByteArrayInputStream(err.toByteArray());
+
+ // use 0 as exit value as the executor didn't return the value
+ int exitValue = 0;
+ if (executor instanceof ExecDefaultExecutor) {
+ // get the exit value from the executor as it captures this to work around the common-exec bug
+ exitValue = ((ExecDefaultExecutor) executor).getExitValue();
+ }
+
+ ExecResult result = new ExecResult(command, stdout, stderr, exitValue);
+ return result;
+ }
// invalid working dir
LOG.error("IOException while executing command: " + command.toString() + " - " + ioe.getMessage());
throw new ExecException("Unable to execute command " + command, ioe);
@@ -86,7 +113,7 @@ public class DefaultExecCommandExecutor implements ExecCommandExecutor {
}
protected DefaultExecutor prepareDefaultExecutor(ExecCommand execCommand) {
- DefaultExecutor executor = new DefaultExecutor();
+ DefaultExecutor executor = new ExecDefaultExecutor();
executor.setExitValues(null);
if (execCommand.getWorkingDir() != null) {
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecEndpointTest.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecEndpointTest.java b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecEndpointTest.java
index 26ec23f..ebd4cfc 100644
--- a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecEndpointTest.java
+++ b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecEndpointTest.java
@@ -74,7 +74,6 @@ public class ExecEndpointTest extends AbstractJUnit4SpringContextTests {
assertEquals(NO_TIMEOUT, e.getTimeout());
assertEquals("test", e.getExecutable());
- assertNotNull(e.getCommandExecutor());
assertNotNull(e.getBinding());
}
@@ -150,7 +149,6 @@ public class ExecEndpointTest extends AbstractJUnit4SpringContextTests {
ExecEndpoint endpoint = createExecEndpoint(UnsafeUriCharactersEncoder.encode(uri));
assertEquals(cmd, endpoint.getExecutable());
assertNull(endpoint.getArgs());
- assertNotNull(endpoint.getCommandExecutor());
assertEquals(dir, endpoint.getWorkingDir());
}
@@ -165,7 +163,6 @@ public class ExecEndpointTest extends AbstractJUnit4SpringContextTests {
assertNull(endpoint.getArgs());
assertNull(endpoint.getWorkingDir());
- assertNotNull(endpoint.getCommandExecutor());
assertEquals(executable, endpoint.getExecutable());
}
http://git-wip-us.apache.org/repos/asf/camel/blob/bbbb3942/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJava8IssueTest.java
----------------------------------------------------------------------
diff --git a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJava8IssueTest.java b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJava8IssueTest.java
new file mode 100644
index 0000000..5fa78d4
--- /dev/null
+++ b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJava8IssueTest.java
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.exec;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.UUID;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.commons.exec.OS;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test to duplicate issues with Camel's exec command in Java 8 on Unix
+ * This issue appears to be caused by a race condition, so this test does not always fail
+ */
+public class ExecJava8IssueTest extends Assert {
+
+ private File tempDir;
+ private final String tempDirName = name();
+ private final String tempFileName = name();
+
+ @Before
+ public void setUp() {
+ tempDir = new File("target", tempDirName);
+ if (!(tempDir.mkdir())) {
+ fail("Couldn't create temp dir for test");
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ FileUtils.deleteDirectory(tempDir);
+ }
+
+ @Test
+ public void test() throws Exception {
+
+ if (!OS.isFamilyUnix()) {
+ System.err.println("The test 'CamelExecTest' does not support the following OS : " + System.getProperty("os.name"));
+ return;
+ }
+
+ String tempFilePath = tempDir.getAbsolutePath() + "/" + tempFileName;
+
+ final File script = File.createTempFile("script", ".sh", tempDir);
+
+ writeScript(script);
+
+ final String exec = "bash?args=" + script.getAbsolutePath() + " " + tempFilePath + "&outFile=" + tempFilePath;
+
+ DefaultCamelContext context = new DefaultCamelContext();
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:source")
+ .to("file:" + tempDir.getAbsolutePath() + "?fileName=" + tempFileName)
+ .to("exec:" + exec)
+ .process(new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ String output = exchange.getIn().getBody(String.class);
+ assertEquals("hello world\n", output);
+ }
+ });
+
+ }
+ });
+
+ context.start();
+
+ ProducerTemplate pt = context.createProducerTemplate();
+ String payload = "hello";
+
+ pt.sendBody("direct:source", payload);
+ }
+
+ /**
+ * Creates a script which will append " world" to a file
+ */
+ private void writeScript(File script) throws IOException {
+ try (FileWriter fw = new FileWriter(script);
+ PrintWriter pw = new PrintWriter(fw)) {
+ String s = "echo \" world\" >> $1";
+ pw.print(s);
+ }
+ }
+
+ /**
+ * Returns a random UUID
+ */
+ private String name() {
+ return UUID.randomUUID().toString();
+ }
+}
\ No newline at end of file