You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by Raul Kripalani <ra...@evosent.com> on 2013/11/20 01:31:46 UTC

CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Hey guys,

To solve CAMEL-6694, I'm having to enhance the constructors of the
CamelLogger and CamelLogProcessor to pass in either:

-  the ClassLoader of the Camel context (obtained with
CamelContext#getApplicationClassLoader)       - or -

- the Camel context itself, letting the constructors call
CamelContext#getApplicationClassLoader.

This API change will percolate up to several other classes, such as:

DeadLetterChannelBuilder
DefaultErrorHandlerBuilder
LoggingErrorHandlerBuilder
LoggingExceptionHandler
etc.

I really dislike this solution, but I don't think there's another way to
get hold of the CamelContext. Or is there? Some clever trick I'm unaware of?

If there's no other way out, we should postpone this change until Camel
3.0, where we're allowed to introduce API changes. Agree?

P.S.: I've enhanced the ObjectHelper with a new method <T> T
runWithClassLoader(ClassLoader cl, Callable<T> callable).

Thanks!

*Raúl Kripalani*
Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Raul Kripalani <ra...@evosent.com>.
Hi Willem,

Unfortunately this is not the case, as endpoints and EIPs are constructed
at route initialisation time. So we have no Exchange to work with.

Regards,

*Raúl Kripalani*
Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

On Wed, Nov 20, 2013 at 2:19 AM, Willem jiang <wi...@gmail.com>wrote:

> You can get the CamelContext from the Exchange which can be accessed from
> CamelLogProcessor.
> But I’m not sure if the setting the TCCL can resolve the issue of
> CAMEL-6694.
>
>
> --
> Willem Jiang
>
> Red Hat, Inc.
> Web: http://www.redhat.com
> Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/)
> (English)
>           http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
> Twitter: willemjiang
> Weibo: 姜宁willem
>
>
>
>
>
> On Wednesday, November 20, 2013 at 8:31 AM, Raul Kripalani wrote:
>
> > Hey guys,
> >
> > To solve CAMEL-6694, I'm having to enhance the constructors of the
> > CamelLogger and CamelLogProcessor to pass in either:
> >
> > - the ClassLoader of the Camel context (obtained with
> > CamelContext#getApplicationClassLoader) - or -
> >
> > - the Camel context itself, letting the constructors call
> > CamelContext#getApplicationClassLoader.
> >
> > This API change will percolate up to several other classes, such as:
> >
> > DeadLetterChannelBuilder
> > DefaultErrorHandlerBuilder
> > LoggingErrorHandlerBuilder
> > LoggingExceptionHandler
> > etc.
> >
> > I really dislike this solution, but I don't think there's another way to
> > get hold of the CamelContext. Or is there? Some clever trick I'm unaware
> of?
> >
> > If there's no other way out, we should postpone this change until Camel
> > 3.0, where we're allowed to introduce API changes. Agree?
> >
> > P.S.: I've enhanced the ObjectHelper with a new method <T> T
> > runWithClassLoader(ClassLoader cl, Callable<T> callable).
> >
> > Thanks!
> >
> > *Raúl Kripalani*
> > Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> > Integration specialist
> > http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> > http://blog.raulkr.net | twitter: @raulvk
>
>
>
>

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Raul Kripalani <ra...@evosent.com>.
Hi Johan

Any other ideas that could help solve the issue?

Thoughts welcome.

Thanks,

*Raúl Kripalani*
Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

On Wed, Nov 20, 2013 at 2:29 AM, Johan Edstrom <se...@gmail.com> wrote:

> I really don't want classloader dinking.
>
>

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Johan Edstrom <se...@gmail.com>.
I really don't want classloader dinking.

On Nov 19, 2013, at 7:19 PM, Willem jiang <wi...@gmail.com> wrote:

> You can get the CamelContext from the Exchange which can be accessed from CamelLogProcessor.
> But I’m not sure if the setting the TCCL can resolve the issue of CAMEL-6694.
> 
> 
> --  
> Willem Jiang
> 
> Red Hat, Inc.
> Web: http://www.redhat.com
> Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
>          http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
> Twitter: willemjiang  
> Weibo: 姜宁willem
> 
> 
> 
> 
> 
> On Wednesday, November 20, 2013 at 8:31 AM, Raul Kripalani wrote:
> 
>> Hey guys,
>> 
>> To solve CAMEL-6694, I'm having to enhance the constructors of the
>> CamelLogger and CamelLogProcessor to pass in either:
>> 
>> - the ClassLoader of the Camel context (obtained with
>> CamelContext#getApplicationClassLoader) - or -
>> 
>> - the Camel context itself, letting the constructors call
>> CamelContext#getApplicationClassLoader.
>> 
>> This API change will percolate up to several other classes, such as:
>> 
>> DeadLetterChannelBuilder
>> DefaultErrorHandlerBuilder
>> LoggingErrorHandlerBuilder
>> LoggingExceptionHandler
>> etc.
>> 
>> I really dislike this solution, but I don't think there's another way to
>> get hold of the CamelContext. Or is there? Some clever trick I'm unaware of?
>> 
>> If there's no other way out, we should postpone this change until Camel
>> 3.0, where we're allowed to introduce API changes. Agree?
>> 
>> P.S.: I've enhanced the ObjectHelper with a new method <T> T
>> runWithClassLoader(ClassLoader cl, Callable<T> callable).
>> 
>> Thanks!
>> 
>> *Raúl Kripalani*
>> Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
>> Integration specialist
>> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
>> http://blog.raulkr.net | twitter: @raulvk
> 
> 
> 


Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Willem jiang <wi...@gmail.com>.
You can get the CamelContext from the Exchange which can be accessed from CamelLogProcessor.
But I’m not sure if the setting the TCCL can resolve the issue of CAMEL-6694.


--  
Willem Jiang

Red Hat, Inc.
Web: http://www.redhat.com
Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
          http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
Twitter: willemjiang  
Weibo: 姜宁willem





On Wednesday, November 20, 2013 at 8:31 AM, Raul Kripalani wrote:

> Hey guys,
>  
> To solve CAMEL-6694, I'm having to enhance the constructors of the
> CamelLogger and CamelLogProcessor to pass in either:
>  
> - the ClassLoader of the Camel context (obtained with
> CamelContext#getApplicationClassLoader) - or -
>  
> - the Camel context itself, letting the constructors call
> CamelContext#getApplicationClassLoader.
>  
> This API change will percolate up to several other classes, such as:
>  
> DeadLetterChannelBuilder
> DefaultErrorHandlerBuilder
> LoggingErrorHandlerBuilder
> LoggingExceptionHandler
> etc.
>  
> I really dislike this solution, but I don't think there's another way to
> get hold of the CamelContext. Or is there? Some clever trick I'm unaware of?
>  
> If there's no other way out, we should postpone this change until Camel
> 3.0, where we're allowed to introduce API changes. Agree?
>  
> P.S.: I've enhanced the ObjectHelper with a new method <T> T
> runWithClassLoader(ClassLoader cl, Callable<T> callable).
>  
> Thanks!
>  
> *Raúl Kripalani*
> Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> Integration specialist
> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> http://blog.raulkr.net | twitter: @raulvk




Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Raul Kripalani <ra...@evosent.com>.
Well, this ticket is about log statements tossed by the Log EIP (and
possibly the Log component too) carrying incorrect values for the
bundle.name and bundle.id MDC entries.

They invariably refer to the camel-core bundle, because that's where the
Logger was initialised from.

So my first attempt to fix this ticket is to ensure that the TCCL when
constructing the Logger was the Camel Context's application ClassLoader.
That's why I needed to get hold of it.

But on deeper investigation of Pax Logging, I found that it calculates the
calling Bundle by investigating the Java call stack:
BundleHelper#getCallerBundle [1].

So the caller bundle will inevitably be camel-core always... Kinda a dead
end :(

Maybe Achim or Guillaume can lend a hand in figuring out how to get the
bundle.name and bundle.id of the bundle where the Camel route lives in the
MDC map.

[1]
http://grepcode.com/file/repo1.maven.org/maven2/org.ops4j.pax.logging/pax-logging-api/1.7.0/org/ops4j/pax/logging/internal/BundleHelper.java#BundleHelper.SecurityManagerEx

Regards,

*Raúl Kripalani*
Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

On Thu, Nov 21, 2013 at 7:25 PM, Claus Ibsen <cl...@gmail.com> wrote:

> Why is it you need that ClassLoader in the first place?
>
>
> On Wed, Nov 20, 2013 at 1:31 AM, Raul Kripalani <ra...@evosent.com> wrote:
> > Hey guys,
> >
> > To solve CAMEL-6694, I'm having to enhance the constructors of the
> > CamelLogger and CamelLogProcessor to pass in either:
> >
> > -  the ClassLoader of the Camel context (obtained with
> > CamelContext#getApplicationClassLoader)       - or -
> >
> > - the Camel context itself, letting the constructors call
> > CamelContext#getApplicationClassLoader.
> >
> > This API change will percolate up to several other classes, such as:
> >
> > DeadLetterChannelBuilder
> > DefaultErrorHandlerBuilder
> > LoggingErrorHandlerBuilder
> > LoggingExceptionHandler
> > etc.
> >
> > I really dislike this solution, but I don't think there's another way to
> > get hold of the CamelContext. Or is there? Some clever trick I'm unaware
> of?
> >
> > If there's no other way out, we should postpone this change until Camel
> > 3.0, where we're allowed to introduce API changes. Agree?
> >
> > P.S.: I've enhanced the ObjectHelper with a new method <T> T
> > runWithClassLoader(ClassLoader cl, Callable<T> callable).
> >
> > Thanks!
> >
> > *Raúl Kripalani*
> > Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> > Integration specialist
> > http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> > http://blog.raulkr.net | twitter: @raulvk
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
>

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Claus Ibsen <cl...@gmail.com>.
Why is it you need that ClassLoader in the first place?


On Wed, Nov 20, 2013 at 1:31 AM, Raul Kripalani <ra...@evosent.com> wrote:
> Hey guys,
>
> To solve CAMEL-6694, I'm having to enhance the constructors of the
> CamelLogger and CamelLogProcessor to pass in either:
>
> -  the ClassLoader of the Camel context (obtained with
> CamelContext#getApplicationClassLoader)       - or -
>
> - the Camel context itself, letting the constructors call
> CamelContext#getApplicationClassLoader.
>
> This API change will percolate up to several other classes, such as:
>
> DeadLetterChannelBuilder
> DefaultErrorHandlerBuilder
> LoggingErrorHandlerBuilder
> LoggingExceptionHandler
> etc.
>
> I really dislike this solution, but I don't think there's another way to
> get hold of the CamelContext. Or is there? Some clever trick I'm unaware of?
>
> If there's no other way out, we should postpone this change until Camel
> 3.0, where we're allowed to introduce API changes. Agree?
>
> P.S.: I've enhanced the ObjectHelper with a new method <T> T
> runWithClassLoader(ClassLoader cl, Callable<T> callable).
>
> Thanks!
>
> *Raúl Kripalani*
> Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> Integration specialist
> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> http://blog.raulkr.net | twitter: @raulvk



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Raul Kripalani <ra...@evosent.com>.
Hi Claus,

I thought about that, but I don't think it'll work.

Definitely not for the CamelLogger class; and I'm 90% confident that it
won't work either for the CamelLogProcessor, as it doesn't live in the
Registry. It is constructed programmatically.

Given that route initialization/construction happens in a single thread, my
idea is to create a CurrentCamelConfig class (naming WIP) with static
methods to "pin" a CamelContext to a thread via a ThreadLocal, i.e.

CurrentCamelConfig.setCamelContext();   <= used by the constructors of
Camel Contexts to pin themselves to the thread
CurrentCamelConfig.getCamelContext();   <= used by any configuration-time
element that wishes to access the CamelContext thereafter
CurrentCamelConfig.clearCamelContext(); <= called when configuration is
complete or fails, to release the reference to the CamelContext (otherwise
it won't be GC'ed).

This is analogous to the technique used by JSF with
FacesContext.getCurrentInstance().

Like this, any component down "the configuration stream" can access the
CamelContext through:

CurrentCamelConfig.getCamelContext();

Regards,

*Raúl Kripalani*
Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

On Wed, Nov 20, 2013 at 7:42 AM, Claus Ibsen <cl...@gmail.com> wrote:

> You can implement CamelContextAware and have CamelContext injected.
> Though this only happens for services and whatnot Camel setup for you.
>
> Not sure if it the injection would happen for these classes you mention
> though.
>
>
> On Wed, Nov 20, 2013 at 1:31 AM, Raul Kripalani <ra...@evosent.com> wrote:
> > Hey guys,
> >
> > To solve CAMEL-6694, I'm having to enhance the constructors of the
> > CamelLogger and CamelLogProcessor to pass in either:
> >
> > -  the ClassLoader of the Camel context (obtained with
> > CamelContext#getApplicationClassLoader)       - or -
> >
> > - the Camel context itself, letting the constructors call
> > CamelContext#getApplicationClassLoader.
> >
> > This API change will percolate up to several other classes, such as:
> >
> > DeadLetterChannelBuilder
> > DefaultErrorHandlerBuilder
> > LoggingErrorHandlerBuilder
> > LoggingExceptionHandler
> > etc.
> >
> > I really dislike this solution, but I don't think there's another way to
> > get hold of the CamelContext. Or is there? Some clever trick I'm unaware
> of?
> >
> > If there's no other way out, we should postpone this change until Camel
> > 3.0, where we're allowed to introduce API changes. Agree?
> >
> > P.S.: I've enhanced the ObjectHelper with a new method <T> T
> > runWithClassLoader(ClassLoader cl, Callable<T> callable).
> >
> > Thanks!
> >
> > *Raúl Kripalani*
> > Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> > Integration specialist
> > http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> > http://blog.raulkr.net | twitter: @raulvk
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
>

Re: CAMEL-6694 Getting hold of the Context ClassLoader from deep within

Posted by Claus Ibsen <cl...@gmail.com>.
You can implement CamelContextAware and have CamelContext injected.
Though this only happens for services and whatnot Camel setup for you.

Not sure if it the injection would happen for these classes you mention though.


On Wed, Nov 20, 2013 at 1:31 AM, Raul Kripalani <ra...@evosent.com> wrote:
> Hey guys,
>
> To solve CAMEL-6694, I'm having to enhance the constructors of the
> CamelLogger and CamelLogProcessor to pass in either:
>
> -  the ClassLoader of the Camel context (obtained with
> CamelContext#getApplicationClassLoader)       - or -
>
> - the Camel context itself, letting the constructors call
> CamelContext#getApplicationClassLoader.
>
> This API change will percolate up to several other classes, such as:
>
> DeadLetterChannelBuilder
> DefaultErrorHandlerBuilder
> LoggingErrorHandlerBuilder
> LoggingExceptionHandler
> etc.
>
> I really dislike this solution, but I don't think there's another way to
> get hold of the CamelContext. Or is there? Some clever trick I'm unaware of?
>
> If there's no other way out, we should postpone this change until Camel
> 3.0, where we're allowed to introduce API changes. Agree?
>
> P.S.: I've enhanced the ObjectHelper with a new method <T> T
> runWithClassLoader(ClassLoader cl, Callable<T> callable).
>
> Thanks!
>
> *Raúl Kripalani*
> Apache Camel PMC Member & Committer | Enterprise Architect, Open Source
> Integration specialist
> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> http://blog.raulkr.net | twitter: @raulvk



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen