[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

Hi Stuart,

another possibility would be to import and export the 'widgets'
package from both widget bundles, then they would both see
the same class regardless of the order they were installed.

eg:

  Export-Package: widgets
  Import-Package: org.osgi.framework, widgets

see:
http://www.osgi.org/blog/2007/04/importance-of-exporting-nd-importing.html

Good idea, haven't thought about this one. But that means also that both widget bundles see the same class (so one of the two Widget classes). If they are different from each other (for some reason, don't know), this won't work, right?


-Martin



Just a first idea, there might be other solutions for your problem. Tell me
more about why you choose this design and we could discuss alternatives, ok?

HTH,
-Martin






sorbus wrote:

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
_______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev




_______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev





------------------------------------------------------------------------

_______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev