You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ra...@apache.org on 2012/10/27 20:20:14 UTC
svn commit: r1402833 - in /camel/branches/camel-2.9.x: ./
components/camel-http/src/main/java/org/apache/camel/component/http/
components/camel-jetty/src/main/java/org/apache/camel/component/jetty/
tests/camel-itest-osgi/src/test/java/org/apache/camel/...
Author: raulk
Date: Sat Oct 27 18:20:13 2012
New Revision: 1402833
URL: http://svn.apache.org/viewvc?rev=1402833&view=rev
Log:
Merged into 2.9.x: CAMEL-5722 Classloader mixup when consumers across bundles share the same camel-jetty port
Added:
camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/JettyClassloaderCheckProcessor.java
- copied unchanged from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/JettyClassloaderCheckProcessor.java
camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java
- copied, changed from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java
camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml
- copied, changed from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml
camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml
- copied, changed from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml
Modified:
camel/branches/camel-2.9.x/ (props changed)
camel/branches/camel-2.9.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java
camel/branches/camel-2.9.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
Propchange: camel/branches/camel-2.9.x/
------------------------------------------------------------------------------
Merged /camel/trunk:r1400729,1400734
Modified: camel/branches/camel-2.9.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java?rev=1402833&r1=1402832&r2=1402833&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java (original)
+++ camel/branches/camel-2.9.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java Sat Oct 27 18:20:13 2012
@@ -85,6 +85,9 @@ public class CamelServlet extends HttpSe
exchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.TRUE);
}
+ // we override the classloader before building the HttpMessage just in case the binding
+ // does some class resolution
+ ClassLoader oldTccl = overrideTccl(exchange);
HttpHelper.setCharsetFromContentType(request.getContentType(), exchange);
exchange.setIn(new HttpMessage(exchange, request, response));
@@ -107,6 +110,8 @@ public class CamelServlet extends HttpSe
} catch (Exception e) {
log.error("Error processing request", e);
throw new ServletException(e);
+ } finally {
+ restoreTccl(exchange, oldTccl);
}
}
@@ -146,4 +151,43 @@ public class CamelServlet extends HttpSe
this.servletName = servletName;
}
+ /**
+ * Override the Thread Context ClassLoader if need be.
+ * @param exchange
+ * @return old classloader if overridden; otherwise returns null
+ */
+ protected ClassLoader overrideTccl(final Exchange exchange) {
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader appCtxCl = exchange.getContext().getApplicationContextClassLoader();
+ if (oldClassLoader == null || appCtxCl == null) {
+ return null;
+ }
+
+ if (!oldClassLoader.equals(appCtxCl)) {
+ Thread.currentThread().setContextClassLoader(appCtxCl);
+ if (log.isTraceEnabled()) {
+ log.trace("Overrode TCCL for exchangeId {} to {} on thread {}",
+ new Object[] {exchange.getExchangeId(), appCtxCl, Thread.currentThread().getName()});
+ }
+ return oldClassLoader;
+ }
+ return null;
+ }
+
+ /**
+ * Restore the Thread Context ClassLoader if the Old TCCL is not null.
+ * @param exchange
+ * @param oldTccl
+ */
+ protected void restoreTccl(final Exchange exchange, ClassLoader oldTccl) {
+ if (oldTccl == null) {
+ return;
+ }
+ Thread.currentThread().setContextClassLoader(oldTccl);
+ if (log.isTraceEnabled()) {
+ log.trace("Restored TCCL for exchangeId {} to {} on thread {}",
+ new String[] {exchange.getExchangeId(), oldTccl.toString(), Thread.currentThread().getName()});
+ }
+ }
+
}
Modified: camel/branches/camel-2.9.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java?rev=1402833&r1=1402832&r2=1402833&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java (original)
+++ camel/branches/camel-2.9.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java Sat Oct 27 18:20:13 2012
@@ -108,8 +108,11 @@ public class CamelContinuationServlet ex
// must suspend before we process the exchange
continuation.suspend();
+ ClassLoader oldTccl = overrideTccl(exchange);
+
log.trace("Processing request for exchangeId: {}", exchange.getExchangeId());
// use the asynchronous API to process the exchange
+
consumer.getAsyncProcessor().process(exchange, new AsyncCallback() {
public void done(boolean doneSync) {
// check if the exchange id is already expired
@@ -125,6 +128,10 @@ public class CamelContinuationServlet ex
}
});
+ if (oldTccl != null) {
+ restoreTccl(exchange, oldTccl);
+ }
+
// return to let Jetty continuation to work as it will resubmit and invoke the service
// method again when its resumed
return;
Copied: camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java (from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java)
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java?p2=camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java&p1=camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java&r1=1400729&r2=1402833&rev=1402833&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java (original)
+++ camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java Sat Oct 27 18:20:13 2012
@@ -26,6 +26,7 @@ import org.ops4j.pax.swissbox.tinybundle
import static org.ops4j.pax.exam.CoreOptions.provision;
import static org.ops4j.pax.exam.OptionUtils.combine;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.newBundle;
/**
@@ -41,13 +42,13 @@ public class OSGiJettyCamelContextsClass
// Wait a while to let all the service started
Thread.sleep(3000);
// test context 1
- String endpointURI1 = "http://localhost:9010/camel-context-1/";
+ String endpointURI1 = "http://localhost:9010/camel-context-1/continuation/";
String response1 = template.requestBody(endpointURI1, "Hello World", String.class);
System.out.println("Response from Context 1: " + response1);
assertEquals("Camel Context 1 classloaders unequal", "true", response1.split(" --- ")[0]);
// test context 2
- String endpointURI2 = "http://localhost:9010/camel-context-2/";
+ String endpointURI2 = "http://localhost:9010/camel-context-2/continuation/";
String response2 = template.requestBody(endpointURI2, "Hello World", String.class);
System.out.println("Response from Context 2: " + response2);
assertEquals("Camel Context 2 classloaders unequal", "true", response2.split(" --- ")[0]);
@@ -57,6 +58,25 @@ public class OSGiJettyCamelContextsClass
assertTrue(response1.matches(".*CamelContextBundle1.*CamelContextBundle1.*"));
assertTrue(response2.matches(".*CamelContextBundle2.*CamelContextBundle2.*"));
+ // Wait a while to let all the service started
+ Thread.sleep(3000);
+ // test context 1
+ endpointURI1 = "http://localhost:9010/camel-context-1/noContinuation/";
+ response1 = template.requestBody(endpointURI1, "Hello World", String.class);
+ System.out.println("Response from Context 1: " + response1);
+ assertEquals("Camel Context 1 classloaders unequal", "true", response1.split(" --- ")[0]);
+
+ // test context 2
+ endpointURI2 = "http://localhost:9010/camel-context-2/noContinuation/";
+ response2 = template.requestBody(endpointURI2, "Hello World", String.class);
+ System.out.println("Response from Context 2: " + response2);
+ assertEquals("Camel Context 2 classloaders unequal", "true", response2.split(" --- ")[0]);
+
+ // contexts's both classloaders toString() representation must contain the bundle symbolic ID
+ // definition of "both classloaders": the Camel Context classloader and the Thread classloader during processing
+ assertTrue(response1.matches(".*CamelContextBundle1.*CamelContextBundle1.*"));
+ assertTrue(response2.matches(".*CamelContextBundle2.*CamelContextBundle2.*"));
+
}
@Configuration
@@ -64,7 +84,7 @@ public class OSGiJettyCamelContextsClass
Option[] options = combine(
getDefaultCamelKarafOptions(),
// using the features to install the other camel components
- loadCamelFeatures("camel-jetty"),
+ scanFeatures(getCamelKarafFeatureUrl(), "camel-jetty"),
//set up the camel context bundle1
provision(newBundle().add("META-INF/spring/Classloader-CamelContext1.xml", OSGiJettyCamelContextsClassloaderTest.class.getResource("Classloader-CamelContext1.xml"))
.add(JettyClassloaderCheckProcessor.class)
Copied: camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml (from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml)
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml?p2=camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml&p1=camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml&r1=1400729&r2=1402833&rev=1402833&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml (original)
+++ camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml Sat Oct 27 18:20:13 2012
@@ -27,7 +27,12 @@
<camelContext id="camelContext1" xmlns="http://camel.apache.org/schema/spring">
<camel:route>
- <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-1/"/>
+ <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-1/continuation/?useContinuation=true"/>
+ <camel:process ref="jettyProcessor"/>
+ </camel:route>
+
+ <camel:route>
+ <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-1/noContinuation/?useContinuation=false"/>
<camel:process ref="jettyProcessor"/>
</camel:route>
</camelContext>
Copied: camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml (from r1400729, camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml)
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml?p2=camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml&p1=camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml&r1=1400729&r2=1402833&rev=1402833&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml (original)
+++ camel/branches/camel-2.9.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml Sat Oct 27 18:20:13 2012
@@ -27,7 +27,12 @@
<camelContext id="camelContext2" xmlns="http://camel.apache.org/schema/spring">
<camel:route>
- <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-2/"/>
+ <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-2/continuation/?useContinuation=true"/>
+ <camel:process ref="jettyProcessor"/>
+ </camel:route>
+
+ <camel:route>
+ <camel:from uri="jetty:http://0.0.0.0:9010/camel-context-2/noContinuation/?useContinuation=false"/>
<camel:process ref="jettyProcessor"/>
</camel:route>
</camelContext>