我尝试在带有 SDO 的 Apache ServiceMix 中使用 Apache CXF。SDO 随 Apache Tuscany SDO 实现一起提供。
这是依赖关系图:
我的 osgi-bundle 公开了一个 web 服务,bundle 依赖于 SDO。
CXF 系统包也依赖于 SDO。
我安装了 Apache Tuscany SDO 捆绑堆栈,如下所示:
osgi:install -s mvn:org.apache.tuscany.sdo/tuscany-sdo-api-r2.1/1.1.1
osgi:install -s mvn:org.apache.tuscany.sdo/tuscany-sdo-impl/1.1.1
osgi:install -s mvn:org.apache.tuscany.sdo/tuscany-sdo-lib/1.1.1
osgi:install -s mvn:org.apache.tuscany.sdo/tuscany-sdo-tools/1.1.1
起始级别是:
...
tuscany-sdo-api-r2.1 28
tuscany-sdo-impl 28
tuscany-sdo-lib 28
tuscany-sdo-tools 28
Apache CXF Bundle Jar (2.4.6) 30
camel-cxf (2.8.5) 50
camel-cxf-transport (2.8.5) 50
...
MyApplication 60
当我重新启动服务器时,我打印了以下异常:
karaf@root> Exception in thread "SpringOsgiExtenderThread-4" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'iws': Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ExceptionInInitializerError
at org.apache.cxf.sdo.SDODataBinding.initialize(SDODataBinding.java:128)
at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:444)
at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:685)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:507)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:241)
at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:205)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:157)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:203)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:433)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:322)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:239)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:509)
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.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1544)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 14 more
Caused by: java.lang.NullPointerException
at org.apache.tuscany.sdo.api.SDOUtil.<clinit>(SDOUtil.java:48)
... 35 more
正如我在 org.apache.tuscany.sdo.api.SDOUtil.java 的源代码中看到的(链接):
46 public final class SDOUtil
47 {
48 protected static SDOHelper defaultSDOHelper = ((HelperProviderBase)HelperProvider.INSTANCE).sdoHelper();
49 ...
tuscany -sdo-api-r2.1中的 SDOUtil类依赖于辅助类 commonj.sdo.impl.HelperProvider.java。
HelperProvider.java 的源代码(链接)
64 static {
65 // initialize the default instance using this class's classloader
66 // set to null if none could be located (implies no default implementation)
67 HelperProvider provider;
68 try {
69 provider = getInstance(HelperProvider.class.getClassLoader());
70 } catch (NoHelperProviderException e) {
71 provider = null;
72 }
73 INSTANCE = provider;
74 }
这意味着 getInstance() 方法无法正常工作。
如何使 SDOHelper 在包含的 OSGi 中正确初始化?
更新
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Generated by Apache ServiceMix Archetype -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.bssys</groupId>
<artifactId>eg-smx-osgi-bundle</artifactId>
<packaging>bundle</packaging>
<version>1.0-SNAPSHOT</version>
<name>Apache ServiceMix :: Camel OSGi Bundle</name>
<properties>
<camel.version>2.8.3</camel.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- CXF SDO -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-sdo</artifactId>
<version>2.4.6</version>
</dependency>
<!-- Apache tuscany SDO -->
<dependency>
<groupId>org.apache.tuscany.sdo</groupId>
<artifactId>tuscany-sdo-api-r2.1</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sdo</groupId>
<artifactId>tuscany-sdo-impl</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sdo</groupId>
<artifactId>tuscany-sdo-lib</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sdo</groupId>
<artifactId>tuscany-sdo-tools</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.6</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Import-Package>*,org.apache.camel.osgi</Import-Package>
<Private-Package>com.bssys</Private-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
骆驼上下文.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Apache ServiceMix Archetype -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://camel.apache.org/schema/osgi"
xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
xmlns:ctx="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/osgi http://camel.apache.org/schema/osgi/camel-osgi.xsd
http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
">
<osgi:camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="timer://myTimer?fixedRate=true&period=10000"/>
<bean ref="myTransform" method="transform"/>
<to uri="log:ExampleRouter"/>
</route>
</osgi:camelContext>
<bean id="myTransform" class="com.bssys.MyTransform">
<property name="prefix" value="${prefix}"/>
</bean>
<osgix:cm-properties id="preProps" persistent-id="com.bssys">
<prop key="prefix">MyTransform</prop>
</osgix:cm-properties>
<ctx:property-placeholder properties-ref="preProps" />
<!-- HTTP Endpoint -->
<jaxws:endpoint xmlns:iws="http://www.bssys.com/SMEV/IWS/1"
id="iws" address="/iws1"
serviceName="iws:IWSExport_BaseImportIWSHttpService"
endpointName="iws:IWSExport_BaseImportIWSHttpPort"
implementor="com.bssys.smev.iws._1.BaseImportIWSImpl">
<!--
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
-->
</jaxws:endpoint>
<!--
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route/>
</camelContext>
-->
</beans>