PaxExam OSGI 容器和 ServiceLookupException
PaxExam OSGI Container and ServiceLookupException
我构建了一个非常简单的包,它具有零依赖性并且不导入包。它的唯一内容是一个 CalculatorService 接口和相应的实现 class,只包含一个简单的 add(int a, int b) 方法。
我为此包创建了两个 PaxExam 测试容器,一个使用 Karaf 容器,另一个使用 OSGI 容器。 Karaf 容器测试工作正常,但 OSGI 测试容器没有。
稍微澄清一下...如果我删除 CalculatorService 到 OSGI 测试容器中的注入,并在我的 JUnit 测试用例中直接实例化 CalculatorServiceImpl class,它工作正常。因此,我的简单包中的 class 对 OSGI 测试容器可见。
一些问题:
- 我的 pom.xml 文件中是否遗漏了一些东西来完成这项工作?
- 我应该向我的 OsgiTestClient.config() 方法添加更多包吗?
- 关于什么是保留的其他想法是非常精简的示例?
以下是我尝试将 CalculatorService 注入我的 PaxExam OSGI 测试容器时得到的堆栈跟踪。
org.ops4j.pax.swissbox.tracker.ServiceLookupException: gave up waiting for service info.xyz.common.Calculator
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:199)
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:136)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectField(ServiceInjector.java:89)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectDeclaredFields(ServiceInjector.java:69)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectFields(ServiceInjector.java:61)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.createTest(ContainerTestRunner.java:61)
at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at org.ops4j.pax.exam.nat.internal.NativeTestContainer.call(NativeTestContainer.java:112)
at org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactor.invoke(AllConfinedStagedReactor.java:84)
at org.ops4j.pax.exam.junit.impl.ProbeRunner.evaluate(ProbeRunner.java:267)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.ops4j.pax.exam.junit.impl.ProbeRunner.run(ProbeRunner.java:98)
at org.ops4j.pax.exam.junit.PaxExam.run(PaxExam.java:93)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
我的包含计算器服务的简单包的 pom.xml 如下:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>info.xyz</groupId>
<artifactId>xyz-businessLogic</artifactId>
<version>0.0.1</version>
<packaging>bundle</packaging>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Import-Package>
</Import-Package>
<Export-Package>
info.xyz.common,
info.xyz.common.impl
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
很明显,我的简单包的依赖性为零,并且导出了包含 Calculator 和 CalculatorImpl 文件的包。下面是用于定义这些服务的 blueprint.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager" xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance
http://aries.apache.org/xmlns/jpa/v1.0.0 http://aries.apache.org/xmlns/jpa/v1.0.0
http://aries.apache.org/xmlns/transactions/v1.0.0 http://aries.apache.org/xmlns/transactions/v1.0.0">
<bean id="calculatorService" class="info.xyz.common.impl.CalculatorImpl" />
<service ref="calculatorService" interface="info.xyz.common.Calculator" />
</blueprint>
接下来,我的 PaxExam OSGI 容器的 pom.xml 如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>info.xyz</groupId>
<artifactId>xyz-test-osgi</artifactId>
<version>0.0.1</version>
<parent>
<groupId>info.xyz</groupId>
<artifactId>xyz</artifactId>
<version>0.0.1</version>
<relativePath>../xyz</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-container-native</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-junit4</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-link-mvn</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-aether</artifactId>
<version>${pax.url.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-inject</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax.inject.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Testing target -->
<dependency>
<groupId>info.xyz</groupId>
<artifactId>xyz-businessLogic</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Needed if you use versionAsInProject() -->
<plugin>
<groupId>org.apache.servicemix.tooling</groupId>
<artifactId>depends-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>generate-depends-file</id>
<goals>
<goal>generate-depends-file</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
最后给出OSGI测试class如下:
package info.xyz.test.osgi;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import info.xyz.common.Calculator;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.Constants;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class OsgiTestClient
{
@Inject
protected Calculator _calculator;
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe)
{
System.out.println("TestProbeBuilder gets called");
probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*");
probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.common");
probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.common.impl");
return probe;
}
@Configuration
public Option[] config()
{
return new Option[] {
junitBundles(),
mavenBundle().groupId("info.xyz").artifactId("xyz-businessLogic").versionAsInProject(),
};
}
@Test
public void testAdd()
{
info.xyz.common.impl.CalculatorImpl calculator = new info.xyz.common.impl.CalculatorImpl();
int result = calculator.add(1, 2);
System.out.println("--- testing: ");
}
}
最后一个评论,如果我注释掉用于注入 CalculatorService 的代码,代码 运行 没问题(因为我正在手动实例化 CalculatorImpl class)。因此,我的测试容器确实对计算器接口和实现具有编译时和 运行 时可见性。但是此服务的注入不起作用。
最后提醒一下,当我构建 PaxExam Karaf 测试容器时,计算器服务的注入成功并且测试用例 运行 正常。错误是 运行 在这个 post.
中描述的 PaxExam OSGI 容器
是的,那就是蓝图stack/libraries没有默认安装在原生容器中(但它们在Karaf中)。
您需要将此 deps 添加到您的测试 pom:
<dependency>
<groupId>org.apache.aries</groupId>
<artifactId>org.apache.aries.util</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.aries.proxy</groupId>
<artifactId>org.apache.aries.proxy.api</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.aries.proxy</groupId>
<artifactId>org.apache.aries.proxy.impl</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.api</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core.compatibility</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.cm</artifactId>
<version>1.0.5</version>
</dependency>
并在测试中将以下包添加到您的配置中:
mavenBundle().groupId("org.apache.aries").artifactId("org.apache.aries.util").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.api").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.impl").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.api").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.cm").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core.compatibility").versionAsInProject().noStart(),
这应该可以解决问题![=12=]
我构建了一个非常简单的包,它具有零依赖性并且不导入包。它的唯一内容是一个 CalculatorService 接口和相应的实现 class,只包含一个简单的 add(int a, int b) 方法。
我为此包创建了两个 PaxExam 测试容器,一个使用 Karaf 容器,另一个使用 OSGI 容器。 Karaf 容器测试工作正常,但 OSGI 测试容器没有。
稍微澄清一下...如果我删除 CalculatorService 到 OSGI 测试容器中的注入,并在我的 JUnit 测试用例中直接实例化 CalculatorServiceImpl class,它工作正常。因此,我的简单包中的 class 对 OSGI 测试容器可见。
一些问题:
- 我的 pom.xml 文件中是否遗漏了一些东西来完成这项工作?
- 我应该向我的 OsgiTestClient.config() 方法添加更多包吗?
- 关于什么是保留的其他想法是非常精简的示例?
以下是我尝试将 CalculatorService 注入我的 PaxExam OSGI 测试容器时得到的堆栈跟踪。
org.ops4j.pax.swissbox.tracker.ServiceLookupException: gave up waiting for service info.xyz.common.Calculator
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:199)
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:136)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectField(ServiceInjector.java:89)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectDeclaredFields(ServiceInjector.java:69)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectFields(ServiceInjector.java:61)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.createTest(ContainerTestRunner.java:61)
at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at org.ops4j.pax.exam.nat.internal.NativeTestContainer.call(NativeTestContainer.java:112)
at org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactor.invoke(AllConfinedStagedReactor.java:84)
at org.ops4j.pax.exam.junit.impl.ProbeRunner.evaluate(ProbeRunner.java:267)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.ops4j.pax.exam.junit.impl.ProbeRunner.run(ProbeRunner.java:98)
at org.ops4j.pax.exam.junit.PaxExam.run(PaxExam.java:93)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
我的包含计算器服务的简单包的 pom.xml 如下:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>info.xyz</groupId>
<artifactId>xyz-businessLogic</artifactId>
<version>0.0.1</version>
<packaging>bundle</packaging>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Import-Package>
</Import-Package>
<Export-Package>
info.xyz.common,
info.xyz.common.impl
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
很明显,我的简单包的依赖性为零,并且导出了包含 Calculator 和 CalculatorImpl 文件的包。下面是用于定义这些服务的 blueprint.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager" xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance
http://aries.apache.org/xmlns/jpa/v1.0.0 http://aries.apache.org/xmlns/jpa/v1.0.0
http://aries.apache.org/xmlns/transactions/v1.0.0 http://aries.apache.org/xmlns/transactions/v1.0.0">
<bean id="calculatorService" class="info.xyz.common.impl.CalculatorImpl" />
<service ref="calculatorService" interface="info.xyz.common.Calculator" />
</blueprint>
接下来,我的 PaxExam OSGI 容器的 pom.xml 如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>info.xyz</groupId>
<artifactId>xyz-test-osgi</artifactId>
<version>0.0.1</version>
<parent>
<groupId>info.xyz</groupId>
<artifactId>xyz</artifactId>
<version>0.0.1</version>
<relativePath>../xyz</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-container-native</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-junit4</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-link-mvn</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-aether</artifactId>
<version>${pax.url.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-inject</artifactId>
<version>${pax.exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax.inject.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Testing target -->
<dependency>
<groupId>info.xyz</groupId>
<artifactId>xyz-businessLogic</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Needed if you use versionAsInProject() -->
<plugin>
<groupId>org.apache.servicemix.tooling</groupId>
<artifactId>depends-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>generate-depends-file</id>
<goals>
<goal>generate-depends-file</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
最后给出OSGI测试class如下:
package info.xyz.test.osgi;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import info.xyz.common.Calculator;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.Constants;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class OsgiTestClient
{
@Inject
protected Calculator _calculator;
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe)
{
System.out.println("TestProbeBuilder gets called");
probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*");
probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.common");
probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.common.impl");
return probe;
}
@Configuration
public Option[] config()
{
return new Option[] {
junitBundles(),
mavenBundle().groupId("info.xyz").artifactId("xyz-businessLogic").versionAsInProject(),
};
}
@Test
public void testAdd()
{
info.xyz.common.impl.CalculatorImpl calculator = new info.xyz.common.impl.CalculatorImpl();
int result = calculator.add(1, 2);
System.out.println("--- testing: ");
}
}
最后一个评论,如果我注释掉用于注入 CalculatorService 的代码,代码 运行 没问题(因为我正在手动实例化 CalculatorImpl class)。因此,我的测试容器确实对计算器接口和实现具有编译时和 运行 时可见性。但是此服务的注入不起作用。
最后提醒一下,当我构建 PaxExam Karaf 测试容器时,计算器服务的注入成功并且测试用例 运行 正常。错误是 运行 在这个 post.
中描述的 PaxExam OSGI 容器是的,那就是蓝图stack/libraries没有默认安装在原生容器中(但它们在Karaf中)。
您需要将此 deps 添加到您的测试 pom:
<dependency>
<groupId>org.apache.aries</groupId>
<artifactId>org.apache.aries.util</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.aries.proxy</groupId>
<artifactId>org.apache.aries.proxy.api</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.aries.proxy</groupId>
<artifactId>org.apache.aries.proxy.impl</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.api</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core.compatibility</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.cm</artifactId>
<version>1.0.5</version>
</dependency>
并在测试中将以下包添加到您的配置中:
mavenBundle().groupId("org.apache.aries").artifactId("org.apache.aries.util").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.api").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.impl").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.api").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.cm").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core").versionAsInProject(),
mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core.compatibility").versionAsInProject().noStart(),
这应该可以解决问题![=12=]