Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Equinox » bundle class loaders caching issues?
bundle class loaders caching issues? [message #79909] Wed, 27 December 2006 14:41 Go to next message
Eclipse UserFriend
Originally posted by: david.eauee.gmail.com

Hi,

I have a weird situation here were multiple calls to the "JAXBContext.newInstance(...)" causes an avalanche of "java.lang.LinkageError: duplicate class definition:..." error being spit out. I have copied a sample stack trace at the end of this mail

This call is made indirectly by one of the lib my plug-in is using.
The lib itself is hosted by a separate binary plug-in that also contains all the other dependant jars that i require.

Just to make sure I checked that the offending classes were not present more than once in the build path.

The weird thing is that the 1st call to the method returns happily but each one after that will fail. Don’t the bundle class loaders have a caching mechanism to prevent them from trying to load the same class multiple times?

Has anybody come across this before?

Thanks,
David.


stack trace:

java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:125)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:48)
at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.pre pare(AccessorInjector.java:51)
at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFac tory.get(OptimizedAccessorFactory.java:128)
at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection .optimize(Accessor.java:198)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$Compo siteTransducedAccessorImpl. <init>(TransducedAccessor.java:193)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(T ransducedAccessor.java:135)
at com.sun.xml.bind.v2.runtime.property.AttributeProperty.<init >(AttributeProperty.java:53)
at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create( PropertyFactory.java:68)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:135)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXB ContextImpl.java:404)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:122)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXB ContextImpl.java:404)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:122)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXB ContextImpl.java:404)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:246)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFact ory.java:76)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFact ory.java:55)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFact ory.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java: 132)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:286)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
...
Caused by: java.lang.LinkageError: duplicate class definition: ...
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
... 72 more
Re: bundle class loaders caching issues? [message #79941 is a reply to message #79909] Thu, 28 December 2006 17:47 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: alex_blewitt.yahoo.com

It looks like what's happening is that it's trying to redefine a class by reusing a classloader. Although the names should be unique, chances are whenever it tries to get a new call it's using the same name as before, and that somehow due to class loader linkagaes, that causes problems in the OSGi framework.

That's just a guess, based on what little I know of how such XML binding libraries work. You might get better results by embedding the JAXB libraries into the same plug-in that you're using; that way, the classes should be in the same classloader rather than cross-classloaders (which may be where a conflict occurs).

These are all just guesses; it may be something else all together.

Alex.
Re: bundle class loaders caching issues? [message #80003 is a reply to message #79941] Tue, 02 January 2007 11:15 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: david.eauee.gmail.com

thanks for the answer,

i am not sure of what you mean in the 1st paragraph. but it's true that the same class is used for various extensions and and should be instanciated several times.

What bugs me is that, to the extend of my knowledge, structure of the OSGI classloading should only be an issues when various dependant libs gets spread across several bundles. In my case, everything i need is in that single lib plugin.

i actually tried to host the libs in the plugin that uses them (not that it's an option in the long run though) but got the same problem.

thnks,
d.
Re: bundle class loaders caching issues? [message #80017 is a reply to message #80003] Tue, 02 January 2007 12:10 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: alex_blewitt.yahoo.com

You need to be careful with terminology. It's not that the same class is being instantiated multiple times, but rather that (through JaxB) the class is being *defined* multiple times:

Caused by: java.lang.LinkageError: duplicate class definition: ...
at java.lang.ClassLoader.defineClass1(Native Method)

What I'd imagine is happening is that there's some weirdness going on that doesn't expose itself when being used in a simple classloader scenario, but fails in the OSGi nested classloader case. One example might be that the class that's being defined is somehow leaking to the parent classloader, and that that's preventing the class from being redefined when it's next called.

If it doesn't work even when everything is being packaged up in a single plugin, and you're just using the JaxB stuff yourself (i.e. you're not trying to call defineClass multiple times) then I'd say it's a bug in JaxB that's exposed when running under OSGi. Perhaps using a different API (JibX, for example) might be the only way forward.

It's probably worth raising it as a bug at https://bugs.eclipse.org if you can provide a simple testcase, so that others know of the issue and/or someone might find out what it is.

Alex.
Re: bundle class loaders caching issues? [message #80410 is a reply to message #80017] Mon, 08 January 2007 15:57 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: alex_blewitt.yahoo.com

By the way, for anyone else reading this and/or having this problem, I found the following on java.net:

http://forums.java.net/jive/thread.jspa?messageID=191633& ;tstart=0#191633

<blockquote>Due to classloader constraints when loading JAXB generated code into
an OSGi bundle, we've had to set this magic property ( com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize) to true, preventing
the reference impl from force-feeding a class (via defineClass) into a
classloader that already has the class defined.

Thing is, we don't know what the side-effects may be. I think it might
just cause things to slow down ever so slightly, but is there more to it?
</blockquote>

The answer was no, it's just an optimisation feature. But this property might help out people -- try running your app with -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true (or put it in the .ini) to see if that has any effect.

Alex.
Re: bundle class loaders caching issues? [message #80438 is a reply to message #80410] Mon, 08 January 2007 21:11 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 437
Registered: July 2009
Senior Member
Interesting ... This sounds like what is really going on. JAXB is
forcing a class with defineClass that is already defined. I would have
expected them to synch the classloader and call findLoadedClass then
defineClass to ensure that the class is not already defined.

BTW the most interesting part of the stacktrace is missing the
information we need ...

Caused by: java.lang.LinkageError: duplicate class definition: ...
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
... 72 more

I would be interested to know who was calling defineClass here. If this
is indeed JAXB then there is nothing we can do.

Tom


Alex Blewitt wrote:
> By the way, for anyone else reading this and/or having this problem, I found the following on java.net:
>
> http://forums.java.net/jive/thread.jspa?messageID=191633& ;tstart=0#191633
>
> <blockquote>Due to classloader constraints when loading JAXB generated code into
> an OSGi bundle, we've had to set this magic property ( com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize) to true, preventing
> the reference impl from force-feeding a class (via defineClass) into a
> classloader that already has the class defined.
>
> Thing is, we don't know what the side-effects may be. I think it might
> just cause things to slow down ever so slightly, but is there more to it?
> </blockquote>
>
> The answer was no, it's just an optimisation feature. But this property might help out people -- try running your app with -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true (or put it in the .ini) to see if that has any effect.
>
> Alex.
Re: bundle class loaders caching issues? [message #80522 is a reply to message #80438] Tue, 09 January 2007 08:47 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: alex_blewitt.yahoo.com

It did seem to be by the original report/stack trace:

... multiple calls to the "JAXBContext.newInstance(...)" causes an avalanche of "java.lang.LinkageError: duplicate class definition:. ...

stack trace:

java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:125)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:48)
:
Caused by: java.lang.LinkageError: duplicate class definition: ...
at java.lang.ClassLoader.defineClass1(Native Method)

It looks like the JAXB is doing a dynamic method call to build up the bytecode, which in turn is then invoking the defineClass when it's already defined. I suspect that if you put together a quick ClassLoader and overrode the defineClass() method to print out diagnostics, you'd see the same thing. Alternatively, putting a breakpoint in the defineClass and using a JAXB sample would do the trick :-)

David, would you be able to open a bug at https://bugs.eclipse.org and attach a snippet that exhibits this problem? At least that way we could verify whether it's a JAXB issue or not.

Alex.
Re: bundle class loaders caching issues? [message #80674 is a reply to message #80522] Thu, 11 January 2007 09:34 Go to previous messageGo to next message
David Beaurpere is currently offline David BeaurpereFriend
Messages: 15
Registered: July 2009
Junior Member
sorry for not replying for the past few days (was sick)

You are correct Alex, The "injector" class from the JAXB impl really
goes out of it way to "force define" classes: it retrieves the Method
handle from Classloader.class, reset its accessibility settings and call
invoke on it directly (see the snippets from the injector class at the end)

Now, I have no idea why in the 1st place JAXB seems to believe that it
needs to go to such extremes to load classes (generated on the fly) that
the class loader knows about already.

That said, as a colleague of mine mentioned on java.net (the thread you
referenced earlier) we came across a work around: setting the env var
"com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize" will cause JAXB to
avoid that code completely. For now we are content enough with that
resolution.

i will open a bug...
Regarding replicating the issue, I think the simplest would be to import
a recent apache cxf distrib (which includes and uses JAXB) in a plugin,
attach the srcs to the jar and call some of their their wsdl related
APIs. Would that be ok?

thanks,
d.

#############################
.....
private static final Method defineClass;
private static final Method resolveClass; ....
defineClass =
ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].cl
ass,Integer.TYPE,Integer.TYPE);
resolveClass =
ClassLoader.class.getDeclaredMethod("resolveClass",Class.class);
.....
// TODO: check security implication
// do these setAccessible allow anyone to call these methods freely?s
defineClass.setAccessible(true);
resolveClass.setAccessible(true);
....

(Class)defineClass.invoke(parent,className.replace('/','.'), image,0,imag
e.length);
resolveClass.invoke(parent,c);
.....
#############################




Alex Blewitt wrote:
> It did seem to be by the original report/stack trace:
>
> .. multiple calls to the "JAXBContext.newInstance(...)" causes an avalanche of "java.lang.LinkageError: duplicate class definition:. ...
>
> stack trace:
>
> java.lang.reflect.InvocationTargetException
> at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:125)
> at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Inje ctor.java:48)
> :
> Caused by: java.lang.LinkageError: duplicate class definition: ...
> at java.lang.ClassLoader.defineClass1(Native Method)
>
> It looks like the JAXB is doing a dynamic method call to build up the bytecode, which in turn is then invoking the defineClass when it's already defined. I suspect that if you put together a quick ClassLoader and overrode the defineClass() method to print out diagnostics, you'd see the same thing. Alternatively, putting a breakpoint in the defineClass and using a JAXB sample would do the trick :-)
>
> David, would you be able to open a bug at https://bugs.eclipse.org and attach a snippet that exhibits this problem? At least that way we could verify whether it's a JAXB issue or not.
>
> Alex.
Re: bundle class loaders caching issues? [message #80695 is a reply to message #80674] Thu, 11 January 2007 14:24 Go to previous message
Eclipse UserFriend
Originally posted by: alex_blewitt.yahoo.com

> You are correct Alex, The "injector" class from the JAXB impl
> really goes out of it way to "force define" classes: it retrieves
> the Method handle from Classloader.class, reset its accessibility
> settings and call invoke on it directly.

Cool, glad we found that error.

> Now, I have no idea why in the 1st place JAXB seems to believe
> that it needs to go to such extremes to load classes ...

A cynic might point out that JAXB is written by Sun, and that they don't like Eclipse or any of that nasty little OSGi stuff that it runs on when there's a perfectly good JSR277 around the corner :-)

> Regarding replicating the issue, I think the simplest would be
> to import a recent apache cxf distrib (which includes and uses
> JAXB) in a plugin, attach the srcs to the jar and call some of
> their their wsdl related APIs. Would that be ok?

The easier it is for the Eclipse guys to reproduce it, the easier that they can see what to do about it. A few lines that invoke (say) the WS code, and a 'download the Jar from http://...' would probably do.

That being said, I suspect it might be that the JAXB code is behaving badly, and that it turns out that it's not an issue that Equinox can work around anyway. So I wouldn't spend *too* long on it :-)

Alex.

PS I'm not an Eclipse committer; if you raise a bug, they may have different opions about reproducibility :-)
Previous Topic:equinox http with whiteboard model?
Next Topic:ClassLoader Problem (ClassCastException)?
Goto Forum:
  


Current Time: Mon Dec 22 12:50:25 GMT 2014

Powered by FUDForum. Page generated in 0.01956 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software