Load-time weaving in an OSGi environment is different than in single-classpath-settings like you often have in Java. There you typically use a JVM agent or a specialized classloader that gets ClassFileTransformer components injected from your application. Those ClassFileTransformer components then to the real job of modifying bytecode at load-time. This is also used in the Spring framework to enable aspect weaving or JPA bytecode enhancements.
This gets different when you are working in an OSGi environment. Within OSGi you no longer have a single classpath application, you cannot (or at least should not) create specialized classloaders for yourself to do the magic, maybe the weaving should happen specifically for each bundle or the woven code gets additional dependencies woven into it. Using Spring in an OSGi environment doesn't make things easier. You can use
Spring Dynamic Modules to implement really cool OSGi applications, but your Spring load-time weaving support remains broken to some degree (see all the related questions in the Spring-DM forum).
I often thought about using
Equinox Aspects to solve these problems. Since Equinox Aspects is not tightly bound to AspectJ weaving only, you could re-use the base infrastructure to hook any kind of bytecode modifier into the Equinox runtime - and reuse the caching of Equinox Aspects at the same time.
Now I have a first sketch implemented that bridges between Spring-LTW and Equinox Aspects. The EquinoxAspectsLoadTimeWeaver class implements the LoadTimeWeaver interface of Spring and can therefore be used in your spring context as the load-time weaver component:
<context:spring-configured>
<context:annotation-config>
<context:load-time-weaver
class="org.eclipse.equinox.weaving.springweaver.EquinoxAspectsLoadTimeWeaver"/>
If you define this load-time weaver your bundle need to define an Import-Package on "org.eclipse.equinox.weaving.springweaver", of course.
To use this kind of load-time weaver definition to need to add "org.eclipse.equinox.weaving.hook" (from Equinox Aspects) to your target platform as well as "org.eclipse.equinox.weaving.springweaver":
When you launch your OSGi runtime you need to set the system property: (osgi.framework.extensions=org.eclipse.equinox.weaving.hook) and start the springweaver bundle right at startup. You can do this by adding it to the config.ini file (org.eclipse.equinox.weaving.springweaver@4:start). This is basically the same when using Equinox Aspects, except that you no longer start org.eclipse.equinox.weaving.aspectj but instead the springweaver bundle.
There are still some issues that need to be solved (see
this comment in the spring forum for details), but I hope to can try it out and tell me what works fine and what needs some more work.
Feedback always welcome! Enjoy!
Load-time weaving in an OSGi environment is different than in single-classpath-settings like you often have in Java. There you typically use a JVM agent or a specialized classloader that gets ClassFileTransformer components injected from your application. Those ClassFileTransformer components then to the real job of modifying bytecode at load-time. This is also used in the Spring framework to enable aspect weaving or JPA bytecode enhancements.
This gets different when you are working in an OSGi environment. Within OSGi you no longer have a single classpath application, you cannot (or at least should not) create specialized classloaders for yourself to do the magic, maybe the weaving should happen specifically for each bundle or the woven code gets additional dependencies woven into it. Using Spring in an OSGi environment doesn't make things easier. You can use
Spring Dynamic Modules to implement really cool OSGi applications, but your Spring load-time weaving support remains broken to some degree (see all the related questions in the Spring-DM forum).
I often thought about using
Equinox Aspects to solve these problems. Since Equinox Aspects is not tightly bound to AspectJ weaving only, you could re-use the base infrastructure to hook any kind of bytecode modifier into the Equinox runtime - and reuse the caching of Equinox Aspects at the same time.
Now I have a first sketch implemented that bridges between Spring-LTW and Equinox Aspects. The EquinoxAspectsLoadTimeWeaver class implements the LoadTimeWeaver interface of Spring and can therefore be used in your spring context as the load-time weaver component:
<context:spring-configured>
<context:annotation-config>
<context:load-time-weaver
class="org.eclipse.equinox.weaving.springweaver.EquinoxAspectsLoadTimeWeaver"/>
If you define this load-time weaver your bundle need to define an Import-Package on "org.eclipse.equinox.weaving.springweaver", of course.
To use this kind of load-time weaver definition to need to add "org.eclipse.equinox.weaving.hook" (from Equinox Aspects) to your target platform as well as "org.eclipse.equinox.weaving.springweaver":
When you launch your OSGi runtime you need to set the system property: (osgi.framework.extensions=org.eclipse.equinox.weaving.hook) and start the springweaver bundle right at startup. You can do this by adding it to the config.ini file (org.eclipse.equinox.weaving.springweaver@4:start). This is basically the same when using Equinox Aspects, except that you no longer start org.eclipse.equinox.weaving.aspectj but instead the springweaver bundle.
There are still some issues that need to be solved (see
this comment in the spring forum for details), but I hope to can try it out and tell me what works fine and what needs some more work.
Feedback always welcome! Enjoy!
Load-Time Weaving for Spring-DM