Pax Exam 4和多个Maven存储库无法正常工作

时间:2015-01-23 11:59:13

标签: maven osgi integration-testing pax-exam

我试图运行一个非常基本的Pax Exam 4单元测试,但需要访问多个Maven存储库(不是Maven Central)。这是代码:

@RunWith(PaxExam.class)
public class ExamTest {
    @Inject
    private BundleContext bundleContext;

    @Configuration
    public Option[] config() {        
        return options(
            repositories(
                repository("http://maven.wso2.org/nexus/content/groups/wso2-public").id("wso2"),
                repository("http://nexus.codehaus.org/snapshots").id("nexus.public.repo").allowSnapshots(),
            ),
            mavenBundle("commons-httpclient.wso2", "commons-httpclient").version("3.1.0.wso2v2"),
            mavenBundle("org.codehaus.woodstox", "stax2-api").version("3.0.1-SNAPSHOT"),

            cleanCaches(),
            junitBundles()
        );
    }

    @Test
    public void testInjection() {
        Assert.assertNotNull(bundleContext);
        Bundle[] bundles = bundleContext.getBundles();
        for (Bundle bundle : bundles) {
            System.out.println(bundle.getSymbolicName() + ", state = " + bundle.getState());
        }
    }
}

实际测试是微不足道的,但仅用于测试目的,所以不要介意(repos和库也仅用于测试目的)。问题是以上操作不起作用,Pax考试抱怨存储库URL无效。运行此测试时的输出如下:

[main] ERROR org.ops4j.pax.url.mvn.internal.AetherBasedResolver - invalid repository URLs
java.net.MalformedURLException: no protocol: +http://nexus.codehaus.org/snapshots/
    at java.net.URL.<init>(URL.java:585)
    at java.net.URL.<init>(URL.java:482)
    at java.net.URL.<init>(URL.java:431)
    at org.ops4j.pax.url.mvn.internal.config.MavenRepositoryURL.<init>(MavenRepositoryURL.java:191)
    at org.ops4j.pax.url.mvn.internal.config.MavenConfigurationImpl.getRepositories(MavenConfigurationImpl.java:303)
    at org.ops4j.pax.url.mvn.internal.AetherBasedResolver.selectRepositories(AetherBasedResolver.java:254)
    ...

正如您所看到的,出于某种原因,&#34; +&#34;被添加到第二个URL之前,这会在MavenConfigurationImpl中导致异常。奇怪的是,第一个URL也有一个&#34; +&#34;当我调试代码但是那个被Pax代码剥离的时候。然而,当字符串传递给MavenRepositoryURL构造函数时,第二个不会被剥离,然后导致MalformedURLException:

if (repositoriesProp != null && repositoriesProp.trim().length() > 0) {
    String[] repositories = repositoriesProp.split(REPOSITORIES_SEPARATOR);
    for (String repositoryURL : repositories) {
        repositoriesProperty.add(new MavenRepositoryURL(repositoryURL.trim()));
    }
}

现在这对我来说似乎是一个错误,但我真的不相信这样一个基本选项(能够处理多个Maven回购)不起作用,所以我可能做错了。所以,我的问题是:如何让Pax Exam从多个Maven存储库下载maven包?

另外:如果您只添加1个存储库,一切正常,如果您使用存储库()方法,则无关紧要。如果您多次使用repository()方法,结果是相同的:

@Configuration
    public Option[] config() {        
        return options(
            repository("http://maven.wso2.org/nexus/content/groups/wso2-public").id("wso2"),
            repository("http://nexus.codehaus.org/snapshots").id("nexus.public.repo").allowSnapshots(),         
            mavenBundle("commons-httpclient.wso2", "commons-httpclient").version("3.1.0.wso2v2"),
            mavenBundle("org.codehaus.woodstox", "stax2-api").version("3.0.1-SNAPSHOT"),

            cleanCaches(),
            junitBundles()
        );
    }

在POM的片段下面显示我使用的依赖项(和版本):

<dependencies>        
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.core</artifactId>
        <version>4.3.1</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-container-native</artifactId>
        <version>4.4.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.url</groupId>
        <artifactId>pax-url-aether</artifactId>
        <version>2.3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.url</groupId>
        <artifactId>pax-url-link</artifactId>
        <version>2.3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.url</groupId>
        <artifactId>pax-url-classpath</artifactId>
        <version>2.3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-junit4</artifactId>
        <version>4.4.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.geronimo.specs</groupId>
        <artifactId>geronimo-atinject_1.0_spec</artifactId>
        <version>1.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-link-assembly</artifactId>
        <version>4.4.0</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>org.eclipse.osgi</artifactId>
        <version>3.7.0.v20110613</version>
        <scope>test</scope>
    </dependency> 
</dependencies>

2 个答案:

答案 0 :(得分:5)

这只是一个错误。

repository()选项的Pax考试regression tests目前不使用多个存储库,而且其他任何人都没有。 (事实上​​,处理多个外部存储库的首选方法是使用设置为镜像的存储库管理器,这样就解释了为什么这个功能可能根本不那么基本。)

Pax网址mvn: protocol handler的文档对于系统属性org.ops4j.pax.url.mvn.repositories的语法有点过于模糊。它提到了一个前导加号,表示除Maven settings.xml的存储库外还应使用给定的存储库。

Pax Exam目前为每个存储库添加了一个加号,但Pax URL最多只能为整个列表加一个。

作为解决方法,您可以通过系统属性选项替换存储库选项,如下所示:

systemProperty("org.ops4j.pax.url.mvn.repositories").value("+repo1,repo2")

注意:“repo1”和“repo2”是您的存储库的实际网址。

答案 1 :(得分:0)

此问题还有另一种解决方案。您可以设置构建和单元测试,以便Maven构建获取工件,而不是让Pax直接与Maven存储库交互。在大多数情况下,单元测试中配置的存储库也在POM中配置(例如,因为在编译期间也需要工件),这样也可以消除重复配置。

此处描述了解决方案:

http://veithen.github.io/alta/examples/pax-exam.html