Use Spring AOP in OSGi bundle

2019-07-22 02:46发布

问题:

I am trying to use the Spring AOP for logging purposes. I have set up the logging bundle, and the OSGi service in it.

I have other OSGi bundle which uses the service from logging bundle as a OSGi reference.

The logging bundle is deployed into Apache Karaf and running. I can not get my other bundle deployed.

The spring configuration in my bundle is like that:

<osgi:reference id="loggingIterceptor" interface="com.groupgti.commons.log.LoggingInterceptorAdvice"/>
<aop:config>
    <aop:pointcut id="logger" expression="@annotation(com.groupgti.esb.assessments.kenexa.log.InOutLogger)"/>
    <aop:advisor pointcut-ref="logger" advice-ref="loggingIterceptor"/>
</aop:config>

When I am trying to start my bundle it gives me:

java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
    at java.lang.Class.getDeclaredMethods0(Native Method)[:1.6.0_33]
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)[:1.6.0_33]
    at java.lang.Class.getDeclaredMethods(Class.java:1791)[:1.6.0_33]
    at org.springframework.core.type.StandardAnnotationMetadata.hasAnnotatedMethods(StandardAnnotationMetadata.java:136)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.checkConfigurationClassCandidate(ConfigurationClassBeanDefinitionReader.java:318)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:175)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:161)
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:479)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:467)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:395)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:281)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:247)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:214)[71:org.springframework.osgi.extender:1.2.1]
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:169)[71:org.springframework.osgi.extender:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:175)[70:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.extender.internal.activator.ContextLoaderListener$2.run(ContextLoaderListener.java:716)[71:org.springframework.osgi.extender:1.2.1]
    at java.lang.Thread.run(Thread.java:662)[:1.6.0_33]
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException not found by org.springframework.aop [57]
    at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:787)
    at org.apache.felix.framework.ModuleImpl.access$400(ModuleImpl.java:71)
    at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1768)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)[:1.6.0_33]

I have added the maven dependency into my pom.xml:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.2</version>
</dependency>

Still does not solves the problem. What I am missing here?

回答1:

The problem is that the Maven dependency you are importing does not have a proper OSGI manifest. The Export-Package tag, next to all other OSGI tags, is missing from the manifest.

So, the org.aspectj.weaver.reflect package is not exported, and in OSGI this means the classes in that package will not be known to other bundles. Hence the ClassNotFoundException.

To solve your problem, replace your dependency with the following:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>com.springsource.org.aspectj.weaver</artifactId>
    <version>1.6.2.RELEASE</version>
</dependency>

The springsource jars are basically repackages of the official versions, but with a proper osgi manifest.