Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 365677

Summary: WeavingHook causes failure due to missing packages
Product: [Eclipse Project] Equinox Reporter: Brian <pradine>
Component: FrameworkAssignee: Thomas Watson <tjwatson>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: P3 CC: timothyjward, tjwatson
Version: unspecified   
Target Milestone: Juno M5   
Hardware: PC   
OS: Windows Server 2003   
Whiteboard:
Bug Depends on:    
Bug Blocks: 368248    
Attachments:
Description Flags
possible fix none

Description Brian CLA 2011-12-05 18:10:23 EST
I am currently using org.eclipse.osgi_3.7.2.R37x_v20111028-1418 with Apache Aries and I am running into a problem with WeavingHooks.

org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to instantiate components
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:634)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:326)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:228)
	at org.apache.aries.blueprint.utils.threading.impl.DiscardableRunnable.run(DiscardableRunnable.java:48)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:452)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:314)
	at java.util.concurrent.FutureTask.run(FutureTask.java:149)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:109)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:218)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:897)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:919)
	at java.lang.Thread.run(Thread.java:736)
Caused by: java.lang.NoClassDefFoundError: org.apache.aries.proxy.weaving.WovenProxy
	at java.lang.ClassLoader.defineClassImpl(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:275)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:601)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:567)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:490)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass_LockClassLoader(ClasspathManager.java:478)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:458)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:619)
	at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
	at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
	at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.loadClass(BlueprintContainerImpl.java:374)
	at org.apache.aries.blueprint.container.BlueprintRepository.loadClass(BlueprintRepository.java:385)
	at org.apache.aries.blueprint.container.GenericType.parse(GenericType.java:113)
	at org.apache.aries.blueprint.di.AbstractRecipe.loadType(AbstractRecipe.java:144)
	at org.apache.aries.blueprint.container.BeanRecipe.loadClass(BeanRecipe.java:189)
	at org.apache.aries.blueprint.container.BeanRecipe.getType(BeanRecipe.java:775)
	at org.apache.aries.blueprint.container.BeanRecipe.getInstance(BeanRecipe.java:261)
	at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:708)
	at org.apache.aries.blueprint.di.AbstractRecipe$1.call(AbstractRecipe.java:71)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:314)
	at java.util.concurrent.FutureTask.run(FutureTask.java:149)
	at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:79)
	at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:220)
	at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:154)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:630)
	... 11 more
Caused by: java.lang.ClassNotFoundException: org.apache.aries.proxy.weaving.WovenProxy
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:619)
	... 44 more

This exception goes away if I explicitly import the org.apache.aries.proxy and org.apache.aries.proxy.weaving packages in my bundle, but I wouldn't expect to have to do that.
Comment 1 Thomas Watson CLA 2011-12-06 10:29:43 EST
Moving to Framework: I assume aries is using the standard WeavingHook provided by the R4.3 OSGi framework.

I would assume the weaving hook implementation would add the dynamic imports for these two packages if it wove bytecode into the class that required this.  Do you know if it is doing that?  Is there anything else you can tell us about the scenario?  Let me take a guess that composites are somehow involved.  If so does the composite which contains the affected bundle import the packages?
Comment 2 Brian CLA 2011-12-07 20:02:00 EST
Hi Tom,

Your assumption about the use of composite bundles is correct. The relevant packages are being propagated into the composite. The weaving hook implementation in question can be found here:

https://svn.apache.org/repos/asf/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/ProxyWeavingHook.java

As you can see it is attempting to add dynamic imports, but I do not believe that it is working.
Comment 3 Thomas Watson CLA 2011-12-08 12:23:33 EST
In your testing could you confirm that you can load the class org.apache.aries.proxy.weaving.WovenProxy from the composite surrogate bundle?  For example:

CompositeBundle composite = ... get your problem composite
SurrogateBundle surrogate = compositeBundle.getSurrogateBundle();
try {
	surrogate.loadClass(
		"org.apache.aries.proxy.weaving.WovenProxy");
} catch (ClassNotFoundException e) {
	... error case, the surrogate should be able to load this class
}

I have released a testcase for the scenario as I understand it and it passes:

http://git.eclipse.org/c/equinox/rt.equinox.framework.git/commit/?id=aefd5bd422b0f347c291f061805e0468f975d8ff
Comment 4 Thomas Watson CLA 2011-12-08 12:30:18 EST
My theory is that if you don't have a bundle in your composite that explicitly imports a package then the aries application container will not setup the composite to actually import the packages you need when you weave a class.  This is my reason for asking if you can load the class in question from the surrogate bundle for the problematic composite.
Comment 5 Thomas Watson CLA 2012-01-06 14:40:14 EST
I think you are running into this issue because of a class space consistency issue (introduced by the uses: directive) when trying to dynamically resolve the proxy package for the woven bundle.

If you have a composite definition which imports a package which is provided by the system.bundle from the parent framework then we end up with a surrogate bundle inside the composite framework which has a substitutable export (it exports and imports the package.  In your particular case I think the proxy packages you import must have a uses: constraint on the org.osgi.framework package.  Ultimately this ends up causing the surrogate bundle to both import and export the org.osgi.framework package.  The surrogate's import is scoped to only allow it to get wired to the system.bundle with a matching attribute bundle-symbolic-name=system.bundle.

What I suspect is happening in your case is that the surrogate bundle is not being allowed to import this package and ultimately does not have its export of org.osgi.framework be substituted with the real package from the system bundle.  The most likely cause of this is some resolver hook which is hiding the org.osgi.framework package from the surrogate bundle.
Comment 6 Thomas Watson CLA 2012-01-06 14:42:34 EST
I am resolving as not eclipse.  I was able to reproduce the issue with an environment provided by Brian and was able to confirm that some (non-eclipse) resolver hook is hiding a system.bundle package from the surrogate bundle for the application.  You will need to fix this resolver hook so that it does not do this.
Comment 7 Thomas Watson CLA 2012-01-09 16:44:20 EST
Reopening bug.  I had a look at the resolver hook in question and it does appear there is an issue in the framework which we can address to help with this issue.

The system bundle exports are not providing accurate attribute values for the bundle-symbolic-name attribute key.  Currently it only has a single value of org.eclipse.osgi for the sustem bundle's symbolic name.  It should use a collection so that it can include the alieas value of system.bundle.
Comment 8 Thomas Watson CLA 2012-01-09 16:48:56 EST
Created attachment 209231 [details]
possible fix

Here is a possible fix.
Comment 9 Thomas Watson CLA 2012-01-09 17:01:46 EST
I released the patch to master with commit:

http://git.eclipse.org/c/equinox/rt.equinox.framework.git/commit/?id=1d44655e23034efd02c0d9a80202742d9b7b0dbc