You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@abdera.apache.org by Ugo Cei <ug...@apache.org> on 2008/05/13 14:57:01 UTC

Using Abdera in a Confluence plugin

Hi,

I'm currently trying to use Abdera 0.4.0 for generating Atom feeds  
from an Atlassian Confluence plugin. I suspect there are some  
classloader issues when using Abdera in this scenario, because if I  
use the following typical idiom:

abdera = new Abdera();
Feed feed = abdera.newFeed();

I get an NPE due to the fact that abdera.getFactory() returns null.  
Apparently the ServiceUtils class is not finding classes to load. I  
tried working around the issue by using my own version of  
AbderaConfiguration that "news" FOMFactory, FOMParser, etc. instead  
of relying on ServiceUtils (which confirms, by the way, that the  
various dependencies like Axiom are in the classpath), but I got  
stuck again with the following trace:

javax.servlet.ServletException: Servlet execution threw an exception
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter 
(ApplicationFilterChain.java:292)
...
caused by: java.lang.ExceptionInInitializerError
  at org.apache.axiom.om.impl.llom.OMNodeImpl.serialize 
(OMNodeImpl.java:408)
...
caused by: java.lang.IllegalStateException: No valid ObjectCreator  
found.
  at org.apache.axiom.om.util.StAXUtils$Pool.(StAXUtils.java:64)

Has anyone ever tried doing something similar or fallen into the same  
kind of problems? For the record, this is using Abdera 0.4.0 in  
Confluence 2.8, JDK 1.5 on OS X Tiger.

	Thanks in Advance

		Ugo


-- 
Ugo Cei
Sourcesense - making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by Ugo Cei <u....@sourcesense.com>.
On May 13, 2008, at 4:55 PM, James M Snell wrote:

> What application server are you using?  I know, for instance, with  
> certain versions of WebSphere, I've need to have the application  
> classloader configured as the first classloader in order to get  
> things to work properly.

Tomcat 5.5.23

	Ugo

-- 
Ugo Cei
Sourcesense - making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by James M Snell <ja...@gmail.com>.
What application server are you using?  I know, for instance, with 
certain versions of WebSphere, I've need to have the application 
classloader configured as the first classloader in order to get things 
to work properly.

- James

Ugo Cei wrote:
> Hi,
> 
> I'm currently trying to use Abdera 0.4.0 for generating Atom feeds from 
> an Atlassian Confluence plugin. I suspect there are some classloader 
> issues when using Abdera in this scenario, because if I use the 
> following typical idiom:
> 
> abdera = new Abdera();
> Feed feed = abdera.newFeed();
> 
> I get an NPE due to the fact that abdera.getFactory() returns null. 
> Apparently the ServiceUtils class is not finding classes to load. I 
> tried working around the issue by using my own version of 
> AbderaConfiguration that "news" FOMFactory, FOMParser, etc. instead of 
> relying on ServiceUtils (which confirms, by the way, that the various 
> dependencies like Axiom are in the classpath), but I got stuck again 
> with the following trace:
> 
> javax.servlet.ServletException: Servlet execution threw an exception
>  at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
> 
> ...
> caused by: java.lang.ExceptionInInitializerError
>  at org.apache.axiom.om.impl.llom.OMNodeImpl.serialize(OMNodeImpl.java:408)
> ...
> caused by: java.lang.IllegalStateException: No valid ObjectCreator found.
>  at org.apache.axiom.om.util.StAXUtils$Pool.(StAXUtils.java:64)
> 
> Has anyone ever tried doing something similar or fallen into the same 
> kind of problems? For the record, this is using Abdera 0.4.0 in 
> Confluence 2.8, JDK 1.5 on OS X Tiger.
> 
>     Thanks in Advance
> 
>         Ugo
> 
> 

Re: Using Abdera in a Confluence plugin

Posted by James M Snell <ja...@gmail.com>.
Go forth and code :-)

- James

Dan Diephouse wrote:
> We should be using a utility class like this to load classes:
> 
> http://svn.apache.org/repos/asf/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java
> 
> It has been consistently proven to work on a large variety of appservers and
> use cases (its been in use over 4 years on a nearly every platform
> imaginable). I think that depending on the context classloader all the time
> is probably the wrong thing. I'm not sure if this will solve Ugo's issue,
> but it could save us pain down the road.
> 
> Dan
> 
> On Thu, May 15, 2008 at 11:01 PM, James M Snell <ja...@gmail.com> wrote:
> 
>> The rationale for the existing design is that, for the majority of cases,
>> the context class loader is simply the Right Class Loader.  In WebSphere,
>> for instance, class loaders are hierarchical.  Using the contet class loader
>> ensures that even if the abdera jars are deployed to the server libs, and
>> therefore loaded by the server's class loader, each webapp can still have
>> it's own set of extensions in their respective classpaths.  The hierarchy
>> works it all out.
>>
>> - James
>>
>>
>> Ugo Cei wrote:
>>
>>> On May 15, 2008, at 3:56 PM, Chris Berry wrote:
>>>
>>>  Wouldn't this work;
>>>>      return ServiceUtil.class.getClassLoader ();
>>>>
>>> I tried this, but I was still having problems with Axiom and Commons
>>> Logging, so I ended up manually copying a bunch of JARs in WEB-INF/lib and
>>> solved my problems (at least temporarily) because I wanted to write code and
>>> not waste time debugging class loader issues.
>>>
>>> I'm not keen on committing this change, because I am not that expert with
>>> class loader issues, and would like to hear the rationale behind the current
>>> version before we change it.
>>>
>>>    Ugo
>>>
>>>
> 
> 

Re: Using Abdera in a Confluence plugin

Posted by Dan Diephouse <da...@mulesource.com>.
We should be using a utility class like this to load classes:

http://svn.apache.org/repos/asf/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java

It has been consistently proven to work on a large variety of appservers and
use cases (its been in use over 4 years on a nearly every platform
imaginable). I think that depending on the context classloader all the time
is probably the wrong thing. I'm not sure if this will solve Ugo's issue,
but it could save us pain down the road.

Dan

On Thu, May 15, 2008 at 11:01 PM, James M Snell <ja...@gmail.com> wrote:

> The rationale for the existing design is that, for the majority of cases,
> the context class loader is simply the Right Class Loader.  In WebSphere,
> for instance, class loaders are hierarchical.  Using the contet class loader
> ensures that even if the abdera jars are deployed to the server libs, and
> therefore loaded by the server's class loader, each webapp can still have
> it's own set of extensions in their respective classpaths.  The hierarchy
> works it all out.
>
> - James
>
>
> Ugo Cei wrote:
>
>>
>> On May 15, 2008, at 3:56 PM, Chris Berry wrote:
>>
>>  Wouldn't this work;
>>>      return ServiceUtil.class.getClassLoader ();
>>>
>>
>> I tried this, but I was still having problems with Axiom and Commons
>> Logging, so I ended up manually copying a bunch of JARs in WEB-INF/lib and
>> solved my problems (at least temporarily) because I wanted to write code and
>> not waste time debugging class loader issues.
>>
>> I'm not keen on committing this change, because I am not that expert with
>> class loader issues, and would like to hear the rationale behind the current
>> version before we change it.
>>
>>    Ugo
>>
>>


-- 
Dan Diephouse
http://mulesource.com | http://netzooid.com/blog

Re: Using Abdera in a Confluence plugin

Posted by James M Snell <ja...@gmail.com>.
The rationale for the existing design is that, for the majority of 
cases, the context class loader is simply the Right Class Loader.  In 
WebSphere, for instance, class loaders are hierarchical.  Using the 
contet class loader ensures that even if the abdera jars are deployed to 
the server libs, and therefore loaded by the server's class loader, each 
webapp can still have it's own set of extensions in their respective 
classpaths.  The hierarchy works it all out.

- James

Ugo Cei wrote:
> 
> On May 15, 2008, at 3:56 PM, Chris Berry wrote:
> 
>> Wouldn't this work;
>>       return ServiceUtil.class.getClassLoader ();
> 
> I tried this, but I was still having problems with Axiom and Commons 
> Logging, so I ended up manually copying a bunch of JARs in WEB-INF/lib 
> and solved my problems (at least temporarily) because I wanted to write 
> code and not waste time debugging class loader issues.
> 
> I'm not keen on committing this change, because I am not that expert 
> with class loader issues, and would like to hear the rationale behind 
> the current version before we change it.
> 
>     Ugo
> 

Re: Using Abdera in a Confluence plugin

Posted by Ugo Cei <u....@sourcesense.com>.
On May 15, 2008, at 3:56 PM, Chris Berry wrote:

> Wouldn't this work;
>       return ServiceUtil.class.getClassLoader ();

I tried this, but I was still having problems with Axiom and Commons  
Logging, so I ended up manually copying a bunch of JARs in WEB-INF/ 
lib and solved my problems (at least temporarily) because I wanted to  
write code and not waste time debugging class loader issues.

I'm not keen on committing this change, because I am not that expert  
with class loader issues, and would like to hear the rationale behind  
the current version before we change it.

	Ugo

-- 
Ugo Cei
Sourcesense - making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by Chris Berry <ch...@gmail.com>.
Ugo,

Wouldn't this work;
       return ServiceUtil.class.getClassLoader ();

Cheers,
-- Chris


On May 15, 2008, at 7:56 AM, ugo cei wrote:

>
> ----- ugo cei <u....@sourcesense.com> wrote:
>> This experience taught me that maybe we have just too many components
>> trying to do smart things with class-loading, starting with Abdera's
>> ServiceUtils, Axiom, and Commons Logging. When you try to make all of
>> them work inside a framework that tries to do its own "smart" things
>> with class-loading in order to manage plugins, hells breaks loose.
>> Something to ponder, I think.
>
> Could someone who understand Java class loaders better than I do  
> please review this method from the ServiceUtil class?
>
>
>  /**
>   * Get the context class loader for this thread
>   */
>  public static ClassLoader getClassLoader() {
>    return Thread.currentThread().getContextClassLoader();
>  }
>
> What happens with Confluence (but could happen with other plugin  
> architectures) is that a plugin is loaded by a class loader that is  
> not the webapp one. But the thread that responds to the HTTP request  
> is spawned by the webapp class loader, which knows nothing about  
> classes loaded by the plugin class loader. Thus, whenever the class  
> loader returned by that method is used to load a class which is in  
> the plugin's classpath only, an exception is thrown (and silently  
> swallowed by ServiceUtil#locateInstance, incidentally, which does  
> not help with debugging).
>
> Assuming my analysis is correct, how can we fix this bahavior?
>
>  Ugo
>
> -- 
> Ugo Cei
> Sourcesense - Making sense of Open Source: http://www.sourcesense.com
>


Re: Using Abdera in a Confluence plugin

Posted by James M Snell <ja...@gmail.com>.
I'm not familiar with confluence, but the design being used by abdera is
correct and appropriate for the overall majority of cases.  It would be
appropriate, however, to allow an alternative classloader to be set
instead of always assuming text context class loader.

- James

ugo cei wrote:
> ----- ugo cei <u....@sourcesense.com> wrote:
>> This experience taught me that maybe we have just too many components
>> trying to do smart things with class-loading, starting with Abdera's
>> ServiceUtils, Axiom, and Commons Logging. When you try to make all of
>> them work inside a framework that tries to do its own "smart" things
>> with class-loading in order to manage plugins, hells breaks loose.
>> Something to ponder, I think.
> 
> Could someone who understand Java class loaders better than I do please review this method from the ServiceUtil class?
> 
>   
>   /**
>    * Get the context class loader for this thread
>    */
>   public static ClassLoader getClassLoader() {
>     return Thread.currentThread().getContextClassLoader();
>   }
> 
> What happens with Confluence (but could happen with other plugin architectures) is that a plugin is loaded by a class loader that is not the webapp one. But the thread that responds to the HTTP request is spawned by the webapp class loader, which knows nothing about classes loaded by the plugin class loader. Thus, whenever the class loader returned by that method is used to load a class which is in the plugin's classpath only, an exception is thrown (and silently swallowed by ServiceUtil#locateInstance, incidentally, which does not help with debugging).
> 
> Assuming my analysis is correct, how can we fix this bahavior?
> 
>   Ugo
> 


Re: Using Abdera in a Confluence plugin

Posted by ugo cei <u....@sourcesense.com>.
----- ugo cei <u....@sourcesense.com> wrote:
> This experience taught me that maybe we have just too many components
> trying to do smart things with class-loading, starting with Abdera's
> ServiceUtils, Axiom, and Commons Logging. When you try to make all of
> them work inside a framework that tries to do its own "smart" things
> with class-loading in order to manage plugins, hells breaks loose.
> Something to ponder, I think.

Could someone who understand Java class loaders better than I do please review this method from the ServiceUtil class?

  
  /**
   * Get the context class loader for this thread
   */
  public static ClassLoader getClassLoader() {
    return Thread.currentThread().getContextClassLoader();
  }

What happens with Confluence (but could happen with other plugin architectures) is that a plugin is loaded by a class loader that is not the webapp one. But the thread that responds to the HTTP request is spawned by the webapp class loader, which knows nothing about classes loaded by the plugin class loader. Thus, whenever the class loader returned by that method is used to load a class which is in the plugin's classpath only, an exception is thrown (and silently swallowed by ServiceUtil#locateInstance, incidentally, which does not help with debugging).

Assuming my analysis is correct, how can we fix this bahavior?

  Ugo

-- 
Ugo Cei
Sourcesense - Making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by ugo cei <u....@sourcesense.com>.
----- James M Snell <ja...@gmail.com> wrote:
> "Java classloader hell" is redundant to the extreme :-(

Found myself a way out of the pit of hell by manually copying Abdera and dependent JARs into the application's WEB-INF/lib directory (updating stuff like commons-logging to more recent versions in the process).

This means I cannot use Confluence's plugin manager to deploy my plugin, but at least it works.

This experience taught me that maybe we have just too many components trying to do smart things with class-loading, starting with Abdera's ServiceUtils, Axiom, and Commons Logging. When you try to make all of them work inside a framework that tries to do its own "smart" things with class-loading in order to manage plugins, hells breaks loose. Something to ponder, I think.

  Ugo

-- 
Ugo Cei
Sourcesense - Making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by James M Snell <ja...@gmail.com>.
"Java classloader hell" is redundant to the extreme :-(

- James

ugo cei wrote:
> [snip]
> Think I'm lost in Java classloader hell :(
> 
>   Ugo
> 

Re: Using Abdera in a Confluence plugin

Posted by ugo cei <u....@sourcesense.com>.
----- Ugo Cei <ug...@apache.org> wrote:
> Don't know whether to blame CLogging or Confluence ;(

Got rid of the CLogging problem by upgrading Abdera to use version 1.1.1 (might be sensible to do this on trunk, do you know of any issues with it?) but now I'm back to NPEs due to ServiceUtils not working right, so probably ABDERA-155 was not relevant.

Think I'm lost in Java classloader hell :(

  Ugo

-- 
Ugo Cei
Sourcesense - Making sense of Open Source: http://www.sourcesense.com


Re: Using Abdera in a Confluence plugin

Posted by Ugo Cei <ug...@apache.org>.
On May 13, 2008, at 3:07 PM, Ugo Cei wrote:

> [Replying to myself, as usual ;) ]
>
> On May 13, 2008, at 2:57 PM, Ugo Cei wrote:
>
>> I'm currently trying to use Abdera 0.4.0 for generating Atom feeds  
>> from an Atlassian Confluence plugin. I suspect there are some  
>> classloader issues when using Abdera in this scenario, because if  
>> I use the following typical idiom:
>>
>> abdera = new Abdera();
>> Feed feed = abdera.newFeed();
>>
>> I get an NPE due to the fact that abdera.getFactory() returns  
>> null. Apparently the ServiceUtils class is not finding classes to  
>> load.
>
> I suspect this could be the same issue as ABDERA-155, at least the  
> symptoms are the same. Now, since ABDERA-155 was fixed yesterday by  
> James, do we publish snaphsot builds on a Maven repo somewhere?

Using locally built 0.5.0 snapshot build, now I get the following:

javax.servlet.ServletException: Servlet execution threw an exception
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter 
(ApplicationFilterChain.java:292)
caused by: java.lang.ExceptionInInitializerError
  at org.apache.abdera.Abdera.(Abdera.java:81)
caused by: org.apache.commons.logging.LogConfigurationException:  
org.apache.commons.logging.LogConfigurationException:  
org.apache.commons.logging.LogConfigurationException: Class  
org.apache.commons.logging.impl.Log4JLogger does not implement Log
  at org.apache.commons.logging.impl.LogFactoryImpl.newInstance 
(LogFactoryImpl.java:532)
caused by: org.apache.commons.logging.LogConfigurationException:  
org.apache.commons.logging.LogConfigurationException: Class  
org.apache.commons.logging.impl.Log4JLogger does not implement Log
  at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor 
(LogFactoryImpl.java:416)
caused by: org.apache.commons.logging.LogConfigurationException:  
Class org.apache.commons.logging.impl.Log4JLogger does not implement Log
  at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor 
(LogFactoryImpl.java:412)

Don't know whether to blame CLogging or Confluence ;(

	Ugo


Re: Using Abdera in a Confluence plugin

Posted by Ugo Cei <u....@sourcesense.com>.
[Replying to myself, as usual ;) ]

On May 13, 2008, at 2:57 PM, Ugo Cei wrote:

> I'm currently trying to use Abdera 0.4.0 for generating Atom feeds  
> from an Atlassian Confluence plugin. I suspect there are some  
> classloader issues when using Abdera in this scenario, because if I  
> use the following typical idiom:
>
> abdera = new Abdera();
> Feed feed = abdera.newFeed();
>
> I get an NPE due to the fact that abdera.getFactory() returns null.  
> Apparently the ServiceUtils class is not finding classes to load.

I suspect this could be the same issue as ABDERA-155, at least the  
symptoms are the same. Now, since ABDERA-155 was fixed yesterday by  
James, do we publish snaphsot builds on a Maven repo somewhere?

	Ugo

-- 
Ugo Cei
Sourcesense - making sense of Open Source: http://www.sourcesense.com