Eclipse m2e не поддерживает тестовую флягу Maven с модулями JPMS

У меня есть проект 'java11-core', который генерирует тестовый jar-артефакт для совместного использования с проектом 'java11-app'. Эти проекты прекрасно работают с командной строкой Maven, но в Eclipse классы, общие для тестового jar, не могут быть найдены.

Информация о версии:

  • Apache Maven 3.6.0 (командная строка и Eclipse)
  • Версия Java: 11.0.1, поставщик: корпорация Oracle
  • Eclipse IDE: Версия: 2018-09 (4.9.0)
  • Плагин M2E: 1.9.1.20180912-1601

Я изначально создал их для проектов, как традиционные проекты не JPMS. Эти проекты компилировались и запускали тесты как обычно. После того, как я добавил module-info.java и в java11-core, и в java11-app, компилятор Eclipse не смог распознать общие тестовые файлы из основного проекта.

Вот снимок проводника пакетов для обзора структуры проекта.

введите описание изображения здесь

Добавленное содержимое java11-app и java11-core module-info соответственно:

module com.java11.app {

    exports com.java11.app;
    requires com.java11.core;
}

module com.java11.core {

    exports com.java11.core;
}

Как видите, я не экспортирую пакет тестовых утилит из com.java11.core. Я не хочу экспортировать тестовые пакеты, потому что это сделало бы тестовые классы общедоступными. Я также не хочу представлять новый тестовый проект, потому что в реальных сценариях очень вероятно, что это потребует циклических зависимостей между тестовыми утилитами и проектами, которые они помогают в тестировании.

введите описание изображения здесь

Ошибки сборки для в AppTest.java. Интересная ошибка, о которой сообщает Eclipse, состоит в том, что она не утверждает, что не может найти класс CoreTestUtil, а скорее:

The type com.java11.test.core.util.CoreTestUtil is not accessible   AppTest.java    /java11-app/src/test/java/com/java11/app    line 8  Java Problem
CoreTestUtil cannot be resolved                                     AppTest.java    /java11-app/src/test/java/com/java11/app    line 21 Java Problem

Я предполагаю, что отсутствие экспорта для этого пакета из java11-core и / или отсутствие требования для этого пакета в java11-app заставляют eclipse полагать, что доступ ограничен, даже если классы существуют в отдельном test-jar,

Путь к модулю для java11-app показывает, что он включает в себя java11-core в качестве модуля, а для кода без теста установлено значение No.

введите описание изображения здесь

Я знаю, что работаю с недавно выпущенными функциями и подозреваю, что совместное использование тестовых классов в проекте Eclipse JPMS еще не поддерживается. Но я не уверен, где искать (Eclipse? M2E плагин) для обновления на него поддерживается. Я также не знаю обходного пути, который позволил бы мне работать продуктивно при внедрении JPMS для моих программных проектов.

Для тех, кто считает, что тестовые утилиты не должны делиться таким образом...

Эта тема была охарактеризована как проблема передового опыта, которая должна быть решена путем рефакторинга тестовых утилит в отдельный модуль. Я уважаю эту точку зрения, но, пытаясь следовать этому руководству, я вынужден был нарушать другие передовые практики, в том числе DRY (не повторять себя) и циклические зависимости между пакетами.

Обычно тестовая утилита появляется при разработке модуля, который помогает эффективно тестировать этот модуль, а также зависит от этого модуля. Это создает цикл, если эти утилиты извлекаются в отдельный модуль. Кроме того, некоторые из этих утилит могут быть одинаково полезны при тестировании других модулей, которые зависят от этого модуля. Это создает дублирующийся код, если эти утилиты копируются в новый тестовый модуль для иждивенцев. Возможно, именно по этой причине изначально была добавлена ​​поддержка Maven 'test-jar'.

2 ответа

Eclipse не поддерживает несколько модулей информации для каждого проекта: в любой исходной папке (основной или тестовой) у вас должна быть только одна информация о модуле.

С точки зрения Eclipse, ваша единственная удача - создать новый проект Java, ссылающийся на другой и с его надлежащей информацией о модуле / экспортом:

      module mod.a {
  exports com.example.a;
  // com.example.a.Main
}

module mod.a.tests { // (1)
  exports com.example.a.tests;
  // com.example.a.tests.MainUtils calling com.example.a.Main
  requires mod.a;
}

В случае (1) у вас будут проблемы, если вы не воспользуетесь mod.a.tests: Java никогда не найдет com.example.a.Mainвозможно потому, что второй проект затмевает первый.

Я не эксперт по OSGI, но я думаю, что это одна из причин, почему у большинства плагинов Eclipse есть основной и тестовый проекты: org.eclipse.m2e.coreбудет исправлен путемorg.eclipse.m2e.core.tests

Однако информация о модуле ничего не знает о «патчах»: вы можете исправить модуль в командной строке ( java --patch-module), но не в самой информации о модуле: возможно, Eclipse мог бы сделать это от вашего имени, но это не так.

Как видите, два проекта в Eclipse = два модуля Maven.

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

Это можно сделать с помощью maven-compiler-plugin, maven-shade-plugin и maven-jar-plugin:

  • Я думаю, вам не следует полагаться на test-jar, потому что вы хотите подражать --patch-module Java путем слияния classes и test-classes каталоги.
  • Вы не хотите импортировать этот проект в Eclipse из-за нескольких module-info; или вы должны убедиться, что его информация о модуле видна только Maven (вы можете использовать профиль + m2e.version, чтобы обнаружить m2e и отключить его).

Полностью согласен с тобой. Почему я должен использовать только код src-main из некоторого основного модуля, если я также могу унаследовать некоторые функции src-test?

Но как решить проблему с масштабом? Когда я использую "test" -scope, я теряю связь с кодом src-main. Когда я не использую тестовую область, я теряю связь с кодом src-test.

Мой основной тестовый код меняется не очень часто, поэтому, чтобы все работало в Eclipse, я устанавливаю test-jar в свой локальный репозиторий, и все работает нормально.

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