Статьи

Взлом Maven


Мы не используем M2Eclipse для интеграции Maven и Eclipse, отчасти потому, что у нас был плохой опыт пару лет назад, когда мы все еще использовали Eclipse 3.4, и отчасти потому, что некоторые наши разработчики используют IBM RAD для разработки, а это не так ( или, по крайней мере, не) совместим.
Наш процесс состоит в том, чтобы обновить наши локальные источники из SVN, а затем запустить Maven eclipse: eclipse локально с соответствующими настройками рабочего пространства, чтобы наши файлы .project и .classpath генерировались на основе зависимостей и другой информации в POM. Это работает достаточно хорошо, но план действительно состоит в том, чтобы вскоре перейти на M2Eclipse.

У нас есть родительские POM для каждой подсистемы (каждая из которых состоит из нескольких проектов Eclipse). Некоторые из нас тянут несколько подсистем в наши рабочие пространства, что полезно при рефакторинге интерфейсов между подсистемами, потому что Eclipse может реорганизовывать код, который вызывает интерфейсы, одновременно с рефакторингом интерфейсов, что экономит много работы. Maven генерирует файлы .classpath для Eclipse, которые ссылаются на все в рабочей области как на исходный проект, а не на JAR из локального репозитория Maven. Это важно, потому что если бы Maven создавал ссылки на JAR, а не ссылки на проекты, рефакторинг Eclipse не изменил бы код, вызывающий реорганизованный код.

10 дней назад мы перешли от процесса сборки на основе континуума и архива к jenkins и nexus. Внезапно мы потеряли некоторые ссылки на источники, которые были заменены ссылками на JAR. Если проект упоминался в родительском POM, то он упоминался как проект в Eclipse, но если это была подсистема, построенная с использованием второго родительского POM, то Eclipse ссылался на проект как JAR из локального репозитория Maven. , Это была плохая новость для нашего рефакторинга! Вот пример того, что происходило:

    подсистема-проект-1

    подсистема-проект-2 ссылается на подсистему-проект-1 как

    подсистема проекта
-б-проект-1 ссылается на подсистему-проект-1 как
проект

Вот что происходило, когда мы использовали Jenkins и Nexus:

    subsystem-a-project-1

    subsystem-a-project-2 ссылается на subsystem-a-project-1 как проект

    подсистема-b-project-1 ссылается на subsystem-a-project-1 как
JAR !!!

Одновременно с переходом на Jenkins и Nexus мы обновили несколько библиотек и нашу организационную POM. Мы также переместили наши родительские POM из корневого каталога подсистемы в проект для родителя (в рамках подготовки к использованию M2Eclipse, который предпочитает иметь родительский POM в рабочей области).

Вопрос был в том, где мы начнем искать? Некоторые люди полагали, что это произошло из-за того, что мы переместили родительский POM, другие думали, что это произошло потому, что мы обновили версию библиотеки, от которой может зависеть eclipse: eclipse, а другие высказали мнение, что мы должны вернуться в Continuum и Archiva.

Один из наших проницательных разработчиков заметил, что во время локальной сборки Maven мы получали следующий вывод из командной строки:

    Artifact subsystem-a-project-1 already available as a workspace project, but with different version...

Это была единственная находка, которая позволила нам быстро решить проблему. Я загрузил источник eclipse: eclipse из центрального центра Maven в разделе org / apache / maven / plugins / maven-eclipse-plugin. Я создал фиктивный проект Java в Eclipse. Затем я добавил следующую переменную среды в мою командную строку, из которой запускаю Maven:

    set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=28000

Это говорит JRE открыть порт отладки и дождаться подключения отладчика, прежде чем запускать приложение. Запуск Java-программы с этими аргументами приводит к выводу «Listening для транспорта dt_socket по адресу: 28000». В Eclipse я перешел к настройкам запуска отладки и добавил удаленное соединение на localhost на порту 28000. Ему нужен проект, поэтому я добавил фиктивный проект, который только что создал. Я подключился, и теперь Мейвен продолжал бежать, когда был подключен. Следующим шагом было добавление исходного кода Maven Plugin, который я скачал с Maven Central. Щелкнув правой кнопкой мыши на представлении отладки в перспективе отладки (щелкните на дереве), можно добавить / обновить исходные вложения, и я добавил загруженный JAR-файл с исходными текстами. Последний бит должен был найти подходящую точку останова.Я извлек источники из загруженного ZIP-файла и искал в файлах текст, который выводил Maven, который намекал на проблему («уже доступный как проект рабочей области»). EclipsePlugin был подозреваемым классом!

Я добавил JAR eclipse: eclipse в свой фиктивный проект, чтобы открыть класс в Eclipse, используя ctrl + shift + t. Eclipse открыл класс, но не понял, что источник из исходного вложения принадлежит этому классу. В редакторе есть кнопка для прикрепления исходного кода путем поиска JAR-файла, загруженного из Maven Central, а затем в Eclipse был показан исходный код, и я смог добавить точку останова. К этому времени Maven закончил, поэтому я перезапустил его, и на этот раз я достиг точки останова, и проблема стала совершенно ясной. По какой-то причине, вместо версии, являющейся простой версией SNAPSHOT, она содержала временную метку. Плагин eclipse: eclipse считал, что у меня нет правильного кода в рабочей области, и поэтому вместо создания ссылки на проект он создал ссылку на JAR на основе JAR в локальном репозитории Maven.

В Интернете полно информации о том, как Maven3 теперь использует нестандартные временные метки для каждого артефакта сборки, развернутого в репозитории. Были некоторые ссылки, в которых говорилось, что вы можете отключить его для Maven2 (который мы все еще используем), но когда вы переходите на Maven3, вы не можете отключить его. Я думал о том, чтобы отправить отчет об ошибке в Codehaus (который предоставляет плагин eclipe: eclipse), но мне пришло в голову, что мы все еще ссылаемся на версию 2.8 в нашем организационном POM, и я заметил версию 2.9, когда был в Maven Central. Поэтому я обновил организационное POM, чтобы использовать версию 2.9 eclipse: eclipse и дал этому шанс.

Ура! 23:17 и я бы исправил нашу проблему. Позор, у меня было начало в 6:30 следующего дня для встречи: — /

Это не первый случай, когда мы совершаем ошибку, делая слишком много в процессе миграции. Мы могли бы остаться с Continuum и Archiva, когда обновили наш org-POM, а затем пошагово перешли на Nexus (все еще используя Archiva) и, наконец, перешли на Nexus. Если бы мы сделали это, у нас не было бы проблем, которые мы сделали; но усилие медленной миграции могло бы быть и больше.

Для меня смысл в том, что отладить maven и перейти непосредственно к источнику проблемы проще, чем пытаться исправить проблему методом следа и ошибки, как мы делали до отладки Maven. Отладка Maven может звучать так, будто она продвинутая или сложная, но это чертовски весело — это настоящий хакер, и чувство решения головоломки таким образом стоит потраченных усилий. Я полностью рекомендую его, если по какой-либо другой причине вы подвергаетесь чтению кода других людей (с открытым исходным кодом).