dev@glassfish.java.net

Re: ClassCircularityError reported with the latest v3 trunk

From: Vivek Pandey <Vivek.Pandey_at_Sun.COM>
Date: Sun, 19 Apr 2009 13:43:08 -0700

Update on this: Richard's patched felix.jar seem to fix this issue. In
another week or so there will be a point release of felix and
integration of this release in glassfish should take care of this issue.

Issue, https://glassfish.dev.java.net/issues/show_bug.cgi?id=7648 is
updated accordingly.

Thanks Richard for working on the fix and providing the patch!

-vivek.

Vivek Pandey wrote:
>
> Richard S. Hall wrote:
>> 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?
>>
> Yes, a CNFE is expected as these classes are expected to be loaded by
> the URLClassLoader. Here Felix's ModuleClassLoader is the parent of
> this URLClassLoader.
>
>> 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.
>>
> Thanks this explians. Although the JDK bug might be the cause of this,
> although trying to introspect the class while it is in
> ClassLoader.loadClass() can get you in to this sort of issues. IOW, it
> might be JVM spec level limitation vs a real bug in JDK.
>> 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?
>
> Yes sure! Send it to me and will test it out.
>
> thanks,
>
> -vivek.
>>
>> -> 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
>>>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>