felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Richard S. Hall (JIRA)" <j...@apache.org>
Subject [jira] Commented: (FELIX-2653) LinkageError caused by duplicate class definition during implicit boot delegation
Date Tue, 12 Oct 2010 19:35:33 GMT

    [ https://issues.apache.org/jira/browse/FELIX-2653?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12920319#action_12920319

Richard S. Hall commented on FELIX-2653:

I am not sure why we get the LinkageError. It seems that URLClassLoader or SecureClassLoader
don't expect anyone to jump in front of them and define a class. In the case of the Felix
module class loader, we do expect this and do a double-check just before calling defineClass().

Regardless, while debugging I noticed it looks like we were implicitly boot delegating when
we shouldn't be, which resulted in this situation. We are only supposed to implicitly boot
delegate if a non-bundle-loaded class (e.g., one from the app or boot class path) is trying
to load a class from a bundle. The module class loader was implicitly boot delegating as long
as there was any non-bundle-loaded class on the call stack, when in reality it should have
failed implicit boot delegation as soon as it found any bundle-loaded class on the stack.

I have committed a patch which appears to resolve this particular issue, but it is not clear
to me if the same time of LinkageError couldn't occur in a different scenario if the JRE class
loaders don't double check loaded classes.

> LinkageError caused by duplicate class definition during implicit boot delegation
> ---------------------------------------------------------------------------------
>                 Key: FELIX-2653
>                 URL: https://issues.apache.org/jira/browse/FELIX-2653
>             Project: Felix
>          Issue Type: Bug
>          Components: Framework
>    Affects Versions: framework-3.0.4
>         Environment: java version "1.6.0_21"
> Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
> Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)
>            Reporter: Sahoo
>            Assignee: Richard S. Hall
>            Priority: Critical
>             Fix For: framework-3.2.0
> I am seeing linkage errors caused by attempt to load duplicate classes and I think it
is caused by implicit boot delegation. In our server log, we see the following exception stack:
> java.lang.LinkageError: loader (instance of  java/net/URLClassLoader): attempted  duplicate
class definition for name: "com/acme/Foo"
> 	at java.lang.ClassLoader.defineClass1(Native Method)
> 	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
> 	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
> 	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
> 	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
> 	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
> 	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
> 	at java.security.AccessController.doPrivileged(Native Method)
> 	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> 	at com.acme.Foo$Factory.createRequest(Foo.java:93)
> I tried to trace the execution to find out what causes the class to be defined for the
first time and with the help of btrace (http://projectkenai.com/projects/btrace/), I could
obtain the stack and relevant information. First time the class is defined, the stack looks
like this:
> java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
> java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
> java.net.URLClassLoader.access$000(URLClassLoader.java:58)
> java.net.URLClassLoader$1.run(URLClassLoader.java:197)
> java.security.AccessController.doPrivileged(Native Method)
> java.net.URLClassLoader.findClass(URLClassLoader.java:190)
> java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> org.apache.felix.framework.ModuleImpl.getEnclosingClass(ModuleImpl.java:1570)
> org.apache.felix.framework.ModuleImpl.isClassNotLoadedFromBundle(ModuleImpl.java:1545)
> org.apache.felix.framework.ModuleImpl.doImplicitBootDelegation(ModuleImpl.java:1498)
> org.apache.felix.framework.ModuleImpl.searchDynamicImports(ModuleImpl.java:1452)
> org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:727)
> org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
> org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1733)
> java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> org.apache.felix.framework.ModuleImpl.getClassByDelegation(ModuleImpl.java:638)
> org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1599)
> org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:904)
> org.jvnet.hk2.osgiadapter.OSGiModuleImpl$3$1.run(OSGiModuleImpl.java:399)
> java.security.AccessController.doPrivileged(Native Method)
> org.jvnet.hk2.osgiadapter.OSGiModuleImpl$3.loadClass(OSGiModuleImpl.java:395)
> java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> com.sun.enterprise.v3.server.APIClassLoaderServiceImpl$APIClassLoader.loadClass(APIClassLoaderServiceImpl.java:169)
> java.lang.ClassLoader.loadClass(ClassLoader.java:296)
> java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> com.acme.Foo$Factory.bar(Foo.java:93)
> As you can see, when bar method is called, VM tries to load com.acme.Foo.class and the
call reaches org.apache.felix.framework.ModuleImpl.getEnclosingClass. getEnclosingClass actually
causes the enclosing class, com.acme.Foo, to be defined. So, VM actually records this new
class in loaded classes cache of the appropriate loader, but Felix does not consult the loaded
classes cache again before trying to define the class. 

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message