dev@glassfish.java.net

Re: ClassCircularityError reported with the latest v3 trunk

From: Richard S. Hall <heavy_at_ungoverned.org>
Date: Sun, 19 Apr 2009 11:15:28 -0400

This code in Felix should only ever be executed when there is a CNFE
that is going to be thrown. Do you know if you should correctly be
getting a CNFE?

To be clear, the explicit issue we are talking about is this change in
Felix:

     http://issues.apache.org/jira/browse/FELIX-962

We actually try to determine if a class is an inner class of a class
loader when we are trying to guess whether or not we should delegate to
the parent class loader. This is part of a hack which is a last ditch
effort to avoid CNFE for bad JRE code that assumes it should be able to
see everything on the class path from any class loader.

The change from FELIX-962 is actually implemented in two different ways,
one for JDK < 1.5 and one for JDK >= 1.5. In the >= 1.5 version we use
the method Class.getEnclosingClass(), which seems to cause the error for
perhaps the reasons in the JDK bug you referenced. We implemented the
two different approaches since we assumed performance would be better by
just using getEnclosingClass() than trying to figure it out the
enclosing class manually, which involves doing a class load.

We could potentially try always using the < 1.5 approach, which does not
use that method. If I created a felix.jar that did that, could you test
it to see if it resolved the issue?

-> richard

On 4/18/09 11:39 PM, Vivek Pandey wrote:
> I guess, I tried various things on my end to work around this issue.
> Given that the bug is there since 2007 and not sure when JDK will fix
> it. On our side we need a workaround. With this issue we wont have
> jruby working on glassfish :-(
>
> -vivek.
>
> Richard S. Hall wrote:
>> From reading the JDK bug description, this definitely sounds like it
>> is related to that bug, since Felix is trying to determine the
>> relationship among an inner and outer class.
>>
>> -> richard
>>
>> On 4/18/09 8:52 PM, Vivek Pandey wrote:
>>> [Adding Richard Hall and dev alias]
>>>
>>> Ok, so the root cause is upgrade to Felix 1.6.0. Not sure if
>>> FELIX-851[2] is causing this to happen. Basically Felix
>>> ModuleClassLoader is the parent class loader of the URLClassLoader
>>> using which all of jruby runtime classes are loaded. There is some
>>> logic in felix where it tries to determine the enclosing class of
>>> inner classes and thats where a ClassCircularityError is reported.
>>>
>>> Although it is ignored from inside Felix but somehow this behavior
>>> of determining if a class being loaded is requested by the one from
>>> an OSGi bundle or not is causing certain instability that latter on
>>> results in to more of ClassCirculatoryError. There is JDK bugs [1]
>>> reported on jdk 5 and 6 as well.
>>>
>>> Here is the felix stack trace, where this error is reported:
>>> http://pastie.org/451117
>>>
>>> This is the code in felix 1.6.0 branch where this error occurs:
>>>
>>> org.apache.felix.framework.searchpolicy.ModuleImpl:1287 (felix 1.6.0
>>> codebase)
>>>
>>> if (getEnclosingClassMethod != null)
>>> {
>>> try
>>> {
>>> Class enclosing = (Class)
>>> getEnclosingClassMethod.invoke(clazz, null);
>>> clazz = (enclosing != null) ? enclosing : clazz;
>>> }
>>> catch (Throwable t)
>>> {
>>> // Ignore everything and use original class.
>>> }
>>> }
>>>
>>> Here is how I am loading classes:
>>>
>>> I have a jar file at: glassfish/modules/grizzly-jruby.jar.
>>>
>>> I use a URLClassLoader to load this jar file and also external jars
>>> files (part of application/jruby jars). The classes are loaded
>>> reflectively using this URLClassLoader. The parent of this
>>> URLClassLoader is ModuleClassLoader from felix.
>>>
>>> The deployment fails with ClassCirculatoryError. I would like to
>>> know if there is a bug in felix 1.6 code or if I need to do
>>> something else to workaround this error. Please note that the whole
>>> thing worked with the previous felix version 1.2.2 of glassfish b43.
>>>
>>> Due to this failure I am not able to proceed further and not sure
>>> how I can integrate JRuby monitoring code as I cant test it on v3
>>> trunk.
>>>
>>> -vivek,
>>>
>>>
>>>
>>> [1]http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6508296
>>> [2]http://www.mail-archive.com/dev@felix.apache.org/msg06806.html
>>>
>>>
>>> Vivek Pandey wrote:
>>>> There is JRuby QL failure:
>>>> https://glassfish.dev.java.net/issues/show_bug.cgi?id=7648.
>>>>
>>>> You might recall how jruby compiler runtime is initiated by jruby
>>>> container. Basically, based on where jruby install (jruby.home is),
>>>> a URLClassLoader is created using the jruby install jars. This
>>>> URLClassLoader is used to start of JRuby runtime by reflection.
>>>>
>>>>
>>>> URL[] urls = findJRubyJars();
>>>> ClassLoader cl = new URLClassLoader(urls,
>>>> JRubyApplication.class.getClassLoader());
>>>>
>>>> Class<?> c =
>>>> cl.loadClass("com.sun.grizzly.jruby.RubyRuntime");
>>>> this.jRubyRuntime = c.getConstructor(Properties.class,
>>>> String.class,
>>>> String.class).newInstance(deploymentContext.getAppProps(),
>>>> railsRoot, contextRoot);
>>>> this.adapter = (com.sun.grizzly.tcp.Adapter)
>>>> c.getMethod("getAdapter").invoke(jRubyRuntime);
>>>> startJRubyGrizzlyAdapter();
>>>>
>>>> See method initJRubyGrizzlyAdapter() and rest of the code at:
>>>> http://pastie.org/450451
>>>>
>>>> for some reason with b45 onward and latest v3 trunk, I see one
>>>> thing that the previous v3 build b43, used to have
>>>> ContentClassLoader that loaded the JRubyApplication and now in
>>>> trunka dn b45, there is ModuleClassLoader. Not sure whats going on
>>>> that is causing such ClassCirculatoryError.
>>>>
>>>>
>>>> ---------
>>>> java.lang.ClassCircularityError:
>>>> org/jruby/lexer/yacc/RubyYaccLexer$LexState
>>>> Apr 17, 2009 4:02:40 PM SEVERE: at
>>>> org.jruby.lexer.yacc.RubyYaccLexer.yylex(RubyYaccLexer.java:917)
>>>> ---------
>>>>
>>>> See the details stack trace: http://pastie.org/450344
>>>>
>>>> Due to this error, JRuby/Rails etc. are not working on trunk.
>>>> Probably you would have some idea as to whats going on.
>>>>
>>>> thanks,
>>>>
>>>> -vivek.
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>>