[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [equinox-dev] Aspects: problem weaving same class file in different bundles

Martin wrote:
>Hi Rowan,
>
>I assume the problem is that the aspect should weave the same class from >different bundles. For the aspect both Widget classes are visible (because both >should be woven) and the weaver does not know which one to use for type >resolution. But this is just a first guess on the problem... Would you submit a bug >in bugzilla for this issue?
>
>Different aspects in different bundles with more specific supplement definitions >should workaround this problem, but I really would like to investigate this problem >in more detail (therefore the bug). Would be great if you could create a small test >case for this to reproduce.

I think the test case is a good idea (see below). I would rather you
take a look at that first before I submit a bug because I am at the
stage of learning BOTH equinox-aspects AND aspectj so possibly missed
something simple :-)

Description of problem (using a simple test case)

I have a very simple bundle (Widget) which has an Activator class and
a Widget class.

The Activator start() method prints out the Bundle Symbolic Name, then
instantiates a Widget

The Widget class looks like this:
package widgets;

public class Widget {
   private String wUID;
   public Widget() {
       init();
   }

   private void init() {
      wUID = java.util.UUID.randomUUID().toString();
      System.out.println("Widget has been assigned UID: " + wUID);
   }

   public void doSomething() {
      System.out.println("Widget " + wUID + " has done something");
   }
}

So the constructor calls the init() method which creates a random
UUID, assigns it, and prints it out.

I have two such bundles with a slightly different manifest file
(different Bundle Symbolic Name):

widgetbundle1.jar - Bundle Symbolic Name: Widget_01234
widgetbundle2.jar - Bundle Symbolic Name: Widget_56789

Example manifest file:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Widget Bundle
Bundle-SymbolicName: Widget_01234
Bundle-Version: 1.0.0
Bundle-ClassPath: .
Bundle-Activator: widgets.Activator
Import-Package: org.osgi.framework
Export-Package: widgets
Bundle-Description: Testing Aspects in OSGi...

The aspects look like this:
package widgetaspects;

import widgets.*;

public aspect MyAspects {
   pointcut doInit(Widget w):
      execution(void Widget.init(..)) && target(w);

   after(Widget w) : doInit(w)  {
      System.out.println("In the AFTER advice for doInit()");
      System.out.println("target:" + thisJoinPoint.getTarget());
      System.out.println("this:" + thisJoinPoint.getThis());
      w.doSomething();
   }
}

A pointcut is defined on the execution of the Widget init() method. In
the after advice, the Widget doSomething() method is called.

My aop.xml file looks like this:
<?xml version="1.0"?>
<aspectj>
    <aspects>
        <aspect name="widgetaspects.MyAspects"/>
    </aspects>
</aspectj>

and is installed in org/aspectj/aop.xml in the widget-aspects jar file.

Aspect bundle manifest file:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Widget Aspects
Bundle-SymbolicName: widgetaspects
Bundle-Version: 1.0.0
Export-Package: widgetaspects,org.aspectj
Import-Package: widgets
Require-Bundle: org.aspectj.runtime;visibility:=reexport
Eclipse-SupplementBundle: Widget_*
Bundle-ClassPath: .

If I install EITHER widgetbundle1 OR widgetbundle2 and the
widget-aspects bundle, then start the widgetbundle then it works and I
get this on the console:

Starting Widget Bundle: Widget_01234
[Widget_01234] weaveinfo Join point 'method-execution(void
widgets.Widget.init())' in Type 'widgets.Widget' (Widget.java:12)
advised by after advice from 'widgetaspects.MyAspects'
(MyAspects.aj:10) [with runtime test]
Widget has been assigned UID: 5356811b-3475-448e-8f9b-83a85fa98d3e
In the AFTER advice for doInit()
target:widgets.Widget@1af33d6
this:widgets.Widget@1af33d6
Widget 5356811b-3475-448e-8f9b-83a85fa98d3e has done something

If I install BOTH widgetbundles and the widget-aspects bundle, then
start one widgetbundle, that works as before. Starting the second
widgetbundle I get this on the console:

Starting Widget Bundle: Widget_56789
[Widget_56789] weaveinfo Join point 'method-execution(void
widgets.Widget.init())' in Type 'widgets.Widget' (Widget.java:12)
advised by after advice from 'widgetaspects.MyAspects'
(MyAspects.aj:10) [with runtime test]
Widget has been assigned UID: a26e7eba-b1d7-404c-b11b-c9586cfd5c82
org.osgi.framework.BundleException: Exception in
widgets.Activator.start() of bundle Widget_56789.
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:1018)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
        at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.LinkageError: loader constraint violation: when
resolving method
"widgetaspects.MyAspects.ajc$after$widgetaspects_MyAspects$1$ccb6ce9f(Lwidgets/Widget;Lorg/aspectj/lang/JoinPoint;)V"
the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the
current class, widgets/Widget, and the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) for resolved
class, widgetaspects/MyAspects, have different Class objects for the
type widgets/Widget used in the signature
        at widgets.Widget.init(Widget.java:14)
        at widgets.Widget.<init>(Widget.java:8)
        at widgets.Activator.start(Activator.java:12)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
        ... 14 more
Nested Exception:
java.lang.LinkageError: loader constraint violation: when resolving
method "widgetaspects.MyAspects.ajc$after$widgetaspects_MyAspects$1$ccb6ce9f(Lwidgets/Widget;Lorg/aspectj/lang/JoinPoint;)V"
the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the
current class, widgets/Widget, and the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) for resolved
class, widgetaspects/MyAspects, have different Class objects for the
type widgets/Widget used in the signature
        at widgets.Widget.init(Widget.java:14)
        at widgets.Widget.<init>(Widget.java:8)
        at widgets.Activator.start(Activator.java:12)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
        at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
        at java.lang.Thread.run(Thread.java:619)
Nested Exception:
java.lang.LinkageError: loader constraint violation: when resolving
method "widgetaspects.MyAspects.ajc$after$widgetaspects_MyAspects$1$ccb6ce9f(Lwidgets/Widget;Lorg/aspectj/lang/JoinPoint;)V"
the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the
current class, widgets/Widget, and the class loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) for resolved
class, widgetaspects/MyAspects, have different Class objects for the
type widgets/Widget used in the signature
        at widgets.Widget.init(Widget.java:14)
        at widgets.Widget.<init>(Widget.java:8)
        at widgets.Activator.start(Activator.java:12)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
        at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
        at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:260)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:252)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:260)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:150)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:300)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.console(FrameworkConsole.java:285)
        at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:221)
at java.lang.Thread.run(Thread.java:619)

In the aspect definition I have played around with perthis and pertarget, e.g.:

public aspect MyAspects pertarget(doInit(Widget)) {......

but it has not made any difference.

Rowan