diff --git a/jms/.project b/jms/.project
new file mode 100644
index 0000000..fdc55fd
--- /dev/null
+++ b/jms/.project
@@ -0,0 +1,17 @@
+
+
+ chapter6-jms
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/jms/.settings/org.eclipse.core.resources.prefs b/jms/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/jms/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/jms/.settings/org.eclipse.m2e.core.prefs b/jms/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/jms/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/jms/README.md b/jms/README.md
new file mode 100644
index 0000000..1e1baa9
--- /dev/null
+++ b/jms/README.md
@@ -0,0 +1,18 @@
+Chapter 6 - jms
+----------------
+
+This directory holds examples of the JMS component
+
+### 6.3.1 - Sending and receiving JMS messages
+
+To run this example, execute the following command:
+
+ mvn camel:run
+
+This example will keep running until you press Ctrl-C.
+
+### 6.3.2 - Request-reply messaging
+
+To run this example, execute the following command:
+
+ mvn test -Dtest=RequestReplyJmsTest
diff --git a/jms/pom.xml b/jms/pom.xml
new file mode 100644
index 0000000..3a99dc6
--- /dev/null
+++ b/jms/pom.xml
@@ -0,0 +1,378 @@
+
+
+
+ 4.0.0
+com.camelinaction
+ chapter6-jms
+ 2.0.0
+ pom
+ Camel in Action 2
+ 2015
+
+
+
+
+
+ 5.15.7
+ 5.13.8
+ 2.25.0
+ 3.3.5
+ 1.4.68
+ 2.5.0
+ 1.9.0
+ 1.5.18
+ 2.9.9
+ 1.6.1
+ 1.6.0
+ 8.1.17.v20150415
+ 9.4.18.v20190429
+ 4.12
+ 4.2.1
+ 1.2.17
+ 3.3.0
+ 1.9
+ 1.7.25
+ 5.1.6.RELEASE
+ 2.1.4.RELEASE
+ 1.5.21
+ 4.5
+ 3.6.3
+ 2.4.7.Final
+ 2017.11.0
+
+ UTF-8
+ UTF-8
+
+
+
+
+
+
+
+ org.apache.camel
+ camel-parent
+ ${camel-version}
+ import
+ pom
+
+
+
+ org.apache.camel
+ spi-annotations
+ ${camel-version}
+
+
+
+
+ org.apache.activemq
+ activemq-all
+ ${activemq-version}
+
+
+ org.apache.activemq
+ activemq-camel
+ ${activemq-version}
+
+
+ org.apache.activemq
+ activemq-pool
+ ${activemq-version}
+
+
+ org.apache.xbean
+ xbean-spring
+ ${xbean-version}
+
+
+ org.springframework
+ spring
+
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j-version}
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-version}
+
+
+ log4j
+ log4j
+ ${log4j-version}
+
+
+
+
+ junit
+ junit
+ ${junit-version}
+
+
+
+
+ org.jolokia
+ jolokia-core
+ ${jolokia-version}
+
+
+
+
+ org.springframework
+ spring-context
+ ${spring-version}
+
+
+ org.springframework
+ spring-test
+ ${spring-version}
+
+
+ org.springframework
+ spring-core
+ ${spring-version}
+
+
+ org.springframework
+ spring-beans
+ ${spring-version}
+
+
+ org.springframework
+ spring-web
+ ${spring-version}
+
+
+ org.springframework
+ spring-aop
+ ${spring-version}
+
+
+ org.springframework
+ spring-jdbc
+ ${spring-version}
+
+
+ org.springframework
+ spring-orm
+ ${spring-version}
+
+
+ org.springframework
+ spring-jms
+ ${spring-version}
+
+
+ org.springframework
+ spring-context-support
+ ${spring-version}
+
+
+ org.springframework
+ spring-tx
+ ${spring-version}
+
+
+ org.springframework
+ spring-expression
+ ${spring-version}
+
+
+
+
+ org.apache.ftpserver
+ ftpserver-core
+ 1.0.0
+
+
+ org.apache.ftpserver
+ ftplet-api
+ 1.0.0
+
+
+ org.apache.mina
+ mina-core
+ 2.0.9
+
+
+
+
+
+
+ org.apache.camel
+ camel-core
+ ${camel-version}
+
+
+
+ org.apache.camel
+ camel-test-spring
+ ${camel-version}
+ test
+
+
+
+ org.apache.camel
+ camel-jms
+ ${camel-version}
+
+
+
+ org.apache.activemq
+ activemq-all
+ ${activemq-version}
+
+
+
+
+ org.apache.xbean
+ xbean-spring
+ ${xbean-version}
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-version}
+
+
+
+ log4j
+ log4j
+ ${log4j-version}
+
+
+
+ junit
+ junit
+ ${junit-version}
+ test
+
+
+
+
+
+
+
+
+ org.apache.camel
+ camel-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+ 1.8
+ 1.8
+ 512M
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+ 2.9
+
+ true
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 2.4.3
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 2.4.1
+
+
+
+ activemq-data
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-remote-resources-plugin
+ 1.5
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.6
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.18.1
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 2.15
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.6.0
+
+
+ org.apache.camel
+ camel-maven-plugin
+ ${camel-version}
+
+
+ org.apache.camel
+ camel-package-maven-plugin
+ ${camel-version}
+
+
+ io.hawt
+ hawtio-maven-plugin
+ ${hawtio-version}
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ ${maven-bundle-plugin-version}
+
+
+ org.apache.camel
+ camel-api-component-maven-plugin
+ ${camel-version}
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 1.10
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ 1.1.0.Alpha11
+
+
+
+
+
+
+
diff --git a/jms/src/data/message1.xml b/jms/src/data/message1.xml
new file mode 100644
index 0000000..97a8d12
--- /dev/null
+++ b/jms/src/data/message1.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/jms/src/main/java/camelinaction/OrderRouter.java b/jms/src/main/java/camelinaction/OrderRouter.java
new file mode 100644
index 0000000..aa1e483
--- /dev/null
+++ b/jms/src/main/java/camelinaction/OrderRouter.java
@@ -0,0 +1,47 @@
+package camelinaction;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * A set of routes that watches a directory for new orders, reads them, converts the order
+ * file into a JMS Message and then sends it to the JMS incomingOrders queue hosted
+ * on an embedded ActiveMQ broker instance.
+ *
+ * From there a content-based router is used to send the order to either the
+ * xmlOrders or csvOrders queue.
+ */
+public class OrderRouter extends RouteBuilder {
+
+ @Override
+ public void configure() {
+ // load file orders from src/data into the JMS queue
+ from("file:src/data?noop=true").to("jms:incomingOrders");
+
+ // content-based router
+ from("jms:incomingOrders")
+ .choice()
+ .when(header("CamelFileName").endsWith(".xml"))
+ .to("jms:topic:xmlOrders")
+ .when(header("CamelFileName").endsWith(".csv"))
+ .to("jms:topic:csvOrders");
+
+ from("jms:topic:xmlOrders").to("jms:accounting");
+ from("jms:topic:xmlOrders").to("jms:production");
+
+ // test that our route is working
+ from("jms:accounting").process(new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ System.out.println("Accounting received order: "
+ + exchange.getIn().getHeader("CamelFileName"));
+ }
+ });
+ from("jms:production").process(new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ System.out.println("Production received order: "
+ + exchange.getIn().getHeader("CamelFileName"));
+ }
+ });
+ }
+}
diff --git a/jms/src/main/resources/META-INF/spring/camel-context.xml b/jms/src/main/resources/META-INF/spring/camel-context.xml
new file mode 100644
index 0000000..d5a39de
--- /dev/null
+++ b/jms/src/main/resources/META-INF/spring/camel-context.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ camelinaction
+
+
+
diff --git a/jms/src/main/resources/log4j.properties b/jms/src/main/resources/log4j.properties
new file mode 100644
index 0000000..f9234ed
--- /dev/null
+++ b/jms/src/main/resources/log4j.properties
@@ -0,0 +1,15 @@
+#
+# The logging properties used for eclipse testing, We want to see INFO output on the console.
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the next line to debug Camel
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file
diff --git a/jms/src/test/java/camelinaction/RequestReplyJmsTest.java b/jms/src/test/java/camelinaction/RequestReplyJmsTest.java
new file mode 100644
index 0000000..17017ac
--- /dev/null
+++ b/jms/src/test/java/camelinaction/RequestReplyJmsTest.java
@@ -0,0 +1,46 @@
+package camelinaction;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentClientAcknowledge;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class RequestReplyJmsTest extends CamelTestSupport {
+
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext camelContext = super.createCamelContext();
+
+ ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
+ camelContext.addComponent("jms", jmsComponentClientAcknowledge(connectionFactory));
+
+ return camelContext;
+ }
+
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ from("jms:incomingOrders").inOut("jms:validate");
+ from("jms:validate").bean(ValidatorBean.class);
+ }
+ };
+ }
+
+ @Test
+ public void testClientGetsReply() throws Exception {
+ Object requestBody = template.requestBody("jms:incomingOrders", "");
+ assertEquals("Valid", requestBody);
+ }
+
+ @Test
+ public void testInvalidMessage() throws Exception {
+ Object requestBody = template.requestBody("jms:incomingOrders", "");
+ assertEquals("Invalid", requestBody);
+ }
+}
diff --git a/jms/src/test/java/camelinaction/ValidatorBean.java b/jms/src/test/java/camelinaction/ValidatorBean.java
new file mode 100644
index 0000000..1b84235
--- /dev/null
+++ b/jms/src/test/java/camelinaction/ValidatorBean.java
@@ -0,0 +1,17 @@
+package camelinaction;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.language.XPath;
+
+public class ValidatorBean {
+
+ public void validate(@XPath("/order/@name") String partName, Exchange exchange) {
+ // only motors are valid parts in this simple test bean
+ if ("motor".equals(partName)) {
+ exchange.getOut().setBody("Valid");
+ } else {
+ exchange.getOut().setBody("Invalid");
+ }
+ }
+
+}