Pax Exam 4 и несколько репозиториев Maven не работают

Я пытаюсь запустить очень простой модульный тест 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());
        }
    }
}

Реальный тест тривиален, но только для целей тестирования, так что не берите в голову (репозитории и библиотеки также выбираются только для целей тестирования). Проблема в том, что вышеприведенное не работает, и Pax Exam жалуется, что 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)
    ...

Как вы можете видеть, по какой-то причине "+" добавляется перед вторым URL, и это вызывает исключение в MavenConfigurationImpl. Странно то, что первый URL также имеет "+", когда я отлаживаю код, но этот код удаляется Pax-кодом. Второй, однако, не удаляется и затем вызывает исключение MalformedURLException при передаче строки в конструктор MavenRepositoryURL:

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 репозиторий, и не имеет значения, используете ли вы метод repositories() или нет. Результат тот же, если вы используете метод 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 ответа

Решение

Это просто ошибка.

Регрессионные тесты Pax Exam для repository() опция в настоящее время не использует более одного хранилища, и, очевидно, никто другой никогда не использовал. (На самом деле, предпочтительный способ работы с несколькими внешними репозиториями - это использование менеджера репозитория, настроенного как зеркальное отображение, поэтому это объясняет, почему эта функция может быть не такой уж базовой).

В документации к Pax URL обработчик протокола mvn: слишком неясен в отношении синтаксиса системного свойства org.ops4j.pax.url.mvn.repositories, В нем упоминается начальный знак плюс, указывающий, что данные репозитории должны использоваться в дополнение к репозиториям от Maven. settings.xml,

Экзамен Pax в настоящее время ожидает плюс для каждого хранилища, но Pax URL ожидает максимум один плюс для всего списка.

В качестве обходного пути вы можете заменить параметры хранилища на системное свойство, например:

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

Примечание. "Repo1" и "repo2" - это фактические URL-адреса ваших репозиториев.

Есть другое решение этой проблемы. Вместо того, чтобы позволить Pax напрямую взаимодействовать с репозиториями Maven, вы можете настроить сборку и юнит-тесты так, чтобы артефакты выбирались сборкой Maven. В большинстве случаев репозитории, сконфигурированные в модульных тестах, также в любом случае конфигурируются в POM (например, потому что артефакты также необходимы во время компиляции), так что это также устранит дублирующую конфигурацию.

Решение описано здесь:

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

Другие вопросы по тегам