Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F3940DAE0 for ; Sat, 27 Oct 2012 17:55:27 +0000 (UTC) Received: (qmail 47591 invoked by uid 500); 27 Oct 2012 17:55:27 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 47561 invoked by uid 500); 27 Oct 2012 17:55:27 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 47554 invoked by uid 99); 27 Oct 2012 17:55:27 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 27 Oct 2012 17:55:27 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,NORMAL_HTTP_TO_IP,WEIRD_PORT X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 27 Oct 2012 17:55:23 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DF5B8238890D; Sat, 27 Oct 2012 17:54:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1402830 - in /camel/branches/camel-2.10.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... Date: Sat, 27 Oct 2012 17:54:38 -0000 To: commits@camel.apache.org From: raulk@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121027175438.DF5B8238890D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: raulk Date: Sat Oct 27 17:54:38 2012 New Revision: 1402830 URL: http://svn.apache.org/viewvc?rev=1402830&view=rev Log: Merged into 2.10.x: CAMEL-5722 Classloader mixup when consumers across bundles share the same camel-jetty port Added: camel/branches/camel-2.10.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.10.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.10.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.10.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.10.x/ (props changed) camel/branches/camel-2.10.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java camel/branches/camel-2.10.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java Propchange: camel/branches/camel-2.10.x/ ------------------------------------------------------------------------------ Merged /camel/trunk:r1400729,1400734 Modified: camel/branches/camel-2.10.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.10.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java?rev=1402830&r1=1402829&r2=1402830&view=diff ============================================================================== --- camel/branches/camel-2.10.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java (original) +++ camel/branches/camel-2.10.x/components/camel-http/src/main/java/org/apache/camel/component/http/CamelServlet.java Sat Oct 27 17:54:38 2012 @@ -86,6 +86,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)); @@ -108,6 +111,8 @@ public class CamelServlet extends HttpSe } catch (Exception e) { log.error("Error processing request", e); throw new ServletException(e); + } finally { + restoreTccl(exchange, oldTccl); } } @@ -147,4 +152,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.10.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.10.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java?rev=1402830&r1=1402829&r2=1402830&view=diff ============================================================================== --- camel/branches/camel-2.10.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java (original) +++ camel/branches/camel-2.10.x/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java Sat Oct 27 17:54:38 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.10.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.10.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java?p2=camel/branches/camel-2.10.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=1402830&rev=1402830&view=diff ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java (original) +++ camel/branches/camel-2.10.x/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/jetty/OSGiJettyCamelContextsClassloaderTest.java Sat Oct 27 17:54:38 2012 @@ -41,13 +41,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 +57,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 Copied: camel/branches/camel-2.10.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.10.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml?p2=camel/branches/camel-2.10.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=1402830&rev=1402830&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.10.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext1.xml Sat Oct 27 17:54:38 2012 @@ -27,7 +27,12 @@ - + + + + + + Copied: camel/branches/camel-2.10.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.10.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml?p2=camel/branches/camel-2.10.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=1402830&rev=1402830&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.10.x/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/jetty/Classloader-CamelContext2.xml Sat Oct 27 17:54:38 2012 @@ -27,7 +27,12 @@ - + + + + + +