PDA

View Full Version : Configurable annotation


volvin
Jun 1st, 2008, 05:51 PM
Hi,

I'm trying to get Configurable annotation to work in equinox for a standalone application (no webapp or eclipse RCP). I use the spring-agent.jar at startup and I configured equinox so that the cached Instrumentation is visible from the bundleclassloader.


<?xml version="1.0" encoding="UTF-8"?>
<beans ...>

<context:load-time-weaver/>
<context:spring-configured/>

<bean id="launcher" class="test.Launcher"/>

<bean id="domainobject" class="test.DomainObject" scope="prototype">
<property name="repo"><ref bean="repo"/></property>
</bean>

<bean id="repo" class="test.Repository" depends-on="org.springframework.beans.factory.aspectj.Annotati onBeanConfigurerAspect"/>

</beans>


The launcher is a client creating a domainobject.

I deployed on a target platform with Spring DM 1.1.0M1, aspectjrt, aspectjweaver (from the eclipse plugin directory) and spring-agent osgi bundles.

I get no errors, no aspectj output and the repo bean is not injected in the domainobject instance.

Any ideas?
Has anyone got this to work?

Thx

volvin
Jun 1st, 2008, 06:43 PM
Hi,

After digging some further in the code I noticed that the FilteringClassFileTransformer blocks the transformation because the defining classloader provided by the addTransformer call is not equal to the bundleclassloader.



private static class FilteringClassFileTransformer implements ClassFileTransformer {

private final ClassFileTransformer targetTransformer;

private final ClassLoader targetClassLoader;

public FilteringClassFileTransformer(ClassFileTransformer targetTransformer, ClassLoader targetClassLoader) {
this.targetTransformer = targetTransformer;
this.targetClassLoader = targetClassLoader;
}

public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

if (!this.targetClassLoader.equals(loader)) {
return null;
}
return this.targetTransformer.transform(
loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
}

public String toString() {
return "FilteringClassFileTransformer for: " + this.targetTransformer.toString();
}
}



The provided classloader is a ContextTypeMatchClassloader, a temporay application context classloader. The parent classloader of this ContextTypeMatchClassloader is the right one (the bundleClassloader).

Is this a bug?

volvin
Jun 2nd, 2008, 02:27 AM
Hi,

I created a new LoadTimeWeaver that does not block the weaving process if target CL is equal to the the parent classloader of the instrumentation (defining) loader. I added it as an extension to the spring-context bundle.

Now I see the following aspectJ logging several times for test.DomainObject for different ContextOverridingClassLoader instances:


[ContextOverridingClassLoader@1716fa0] weaveinfo Extending interface set for type 'test.DomainObject' (DomainObject.java) to include 'org.springframework.beans.factory.aspectj.Configu rableObject' (AnnotationBeanConfigurerAspect.aj)

[ContextOverridingClassLoader@1716fa0] weaveinfo Join point 'initialization(void org.springframework.beans.factory.aspectj.Configur ableObject.<init>())' in Type 'test.DomainObject' (DomainObject.java:9) advised by before advice from 'org.springframework.beans.factory.aspectj.Annotat ionBeanConfigurerAspect' (AbstractDependencyInjectionAspect.aj:78) [with runtime test]

[ContextOverridingClassLoader@1716fa0] weaveinfo Join point 'initialization(void org.springframework.beans.factory.aspectj.Configur ableObject.<init>())' in Type 'test.DomainObject' (DomainObject.java:9) advised by afterReturning advice from 'org.springframework.beans.factory.aspectj.Annotat ionBeanConfigurerAspect' (AbstractDependencyInjectionAspect.aj:87) [with runtime test]

[ContextOverridingClassLoader@1716fa0] weaveinfo Join point 'initialization(void test.DomainObject.<init>())' in Type 'test.DomainObject' (DomainObject.java:9) advised by afterReturning advice from 'org.springframework.beans.factory.aspectj.Annotat ionBeanConfigurerAspect' (AbstractDependencyInjectionAspect.aj:87) [with runtime test]


The created DomainObject instances are still not injected with the configured repository.

Is this because the weaving did on this ContextOverridingClassLoader instead of the bundle classloader?

Costin Leau
Jun 2nd, 2008, 05:01 AM
Weaving is still an area that is not officially covered by Spring-DM. In general, in OSGi, due to the nature of the platform and the many classloader that are present, it's recommended to use a more generic approach such as using a javaagent.
If you think there is a problem with FilteringClassFileTransformer then please raise an issue.
Note that it's likely the injection doesn't apply since the types are not compatible - the annotation is probably loaded through different classloaders and thus results in two different, incompatible types.

volvin
Jun 2nd, 2008, 05:17 AM
Do you mean I should use the aspectj agent instead (= a more generic approach)?

Costin Leau
Jun 2nd, 2008, 08:58 AM
Yes, give the agent a try and see how it goes.

ryanyang
Jun 6th, 2008, 01:06 AM
yes The created DomainObject instances are still not injected with the configured repository

Costin Leau
Jun 6th, 2008, 02:28 AM
Have you considered using the default load time weaving classes w/o your extension but using the AspectJ agent?

P.S. ryanyang (http://forum.springframework.org/member.php?u=39329), are you working on the same project as volvin (http://forum.springframework.org/member.php?u=21530) ?