2017-01-30 4 views
1

Во-первых, я долгое время (и получатель) StackOverflow, но это мой первый вопрос. Я много искал эту тему, но большинство статей, которые я включил, говорят о создании JAR-файлов, не работая с сторонними JAR-серверами из Maven Central repo, которые у меня действительно нет возможности исправить. Несколько решений, которые я видел, плавающие вокруг, на самом деле не приемлемы.Ошибка сборки Maven с использованием пути класса MANIFEST.MF в зависимостях JAR

Проблема заключается в том, что большинство JAR-файлов jaxb, найденных в репозитории Maven Central, содержат записи пути к классу (в файле MANIFEST.MF), которые указывают на зависимости, и эти зависимости задаются с относительными путями - обычно предполагая, что панель зависимостей .jar существует в том же каталоге, что и foo.jar.

Это нормально, если у вас есть все ваши JAR-зависимости в одном каталоге lib, например. Но:

  • Maven хочет сохранить свой собственный локальный репозиторий, поэтому каждый упакованный JAR живет в своем собственном каталоге (с каждой версией в отдельном подкаталоге).
  • Maven JARs обычно называются с информацией о версии, встроенной в имя файла, тогда как запись в classpath в MANIFEST.MF указывает зависимость только с базовым именем файла (без версии).

Конечным результатом является сообщение об ошибке, как это:

[ERROR] плохой путь элемент «C: \ Users \ rpoole \ .m2 \ репозиторий \ COM \ ВС \ XML \ привязывать \ JAXB-осущ \ 2.2.11 \ JAXB-core.jar ": нет такого файла или каталога

Одно из решений состоит в написании сценария или небольшое приложение, чтобы пройти через все баночки и вычистить информацию из пути к классам встроенный файл MANIFEST.MF. Но это не очень чисто, и для выполнения реальной сборки требуется дополнительный шаг.

Еще одно потенциальное решение заключается в том, что некоторые более ранние опубликованные версии JARs, предположительно, исправили эту проблему с классом, поэтому используйте последние и самые большие. К сожалению, это приложение, над которым я работаю, является устаревшим и разрабатывается для стороннего пользователя, поэтому я не могу обновлять зависимости за пределами определенной версии. До сих пор все JAR-модули jaxb, которые я ткнул, похоже, имеют проблемы.

Есть ли способ сказать Maven игнорировать встроенный путь класса в JAR и полагаться только на собственное разрешение зависимостей Maven? Я пробовал такие вещи, как переупорядочивание зависимостей, но это не работает (или перемещает проблему сборки из одного подпроекта в другой).

Еще одно раздражение: есть «благословенный» Maven-репо, который у нас есть, что, похоже, позволяет строить без проблем, но до сих пор мне не удалось понять, почему этот набор JARs строит ОК. Я подозреваю, что кто-то, возможно, входил и настраивал некоторые JAR или POM вручную, но есть скудная информация, и инструменты diff не очень помогают.

Независимо от того, проект должен построить с нуля.

Что было бы неплохо, если бы я мог указать что-то вроде блока исключения в pom.xml для взломанного подпроекта, но для работы с встроенным classpath JAR вместо собственных транзитивных зависимостей Maven (заданных groupId/artifactId) ,

Редактировать: По-видимому, некоторые люди считают, что это невозможно, и что Maven игнорирует запись класса Path в Manifest.MF. Однако это известная проблема, как обсуждалось в this StackOverflow article. Там также есть another good article, который объясняет некоторые из истории этого немного лучше.

Проблема в том, что я не могу проходить через JAR и редактировать файлы MANIFEST.MF на каждой части процесса сборки. Это просто не практический подход, даже если он автоматизирован сценарием. Мне нужно решение, которое действительно будет работать для кода, который уже находится в производстве. Эти проблемы были предположительно исправлены в более поздних версиях JAR, о которых идет речь, но я не могу использовать более новые версии этих.

Кроме того, одним из предлагаемых исправлений является добавление -Xlint:-path к компиляторам args, которые подавляют сообщение об ошибке. Однако сборка просто терпит неудачу в другой точке для меня, поэтому сначала краснеть это тоже не является хорошим решением. Я попробую это снова, потому что согласно this, синтаксис для аргументов компилятора внутри файлов POM немного застенчив.

+0

Пожалуйста, покажите ваш файл POM ... – khmarbaise

+0

сам Maven игнорирует MANIFEST.MF, так что я не очень понимаю, что это ваша проблема с пути к классам? Это создается полученным приложением ... – khmarbaise

+1

Насколько я знаю, записи Class-Path манифеста.mf не используются для компиляции. –

ответ

1

Ненавижу отвечать на свой вопрос, но мне, наконец, удалось преодолеть эту проблему. Для тех, кто настаивает на том, что сборка Maven не может быть затронута в записи Class-Path в файле MANIFEST.MF в банке, пожалуйста, прочитайте this article Майклом Бэйном. Он суммирует проблему и решение довольно красиво. Подсказка: javac, конечно же, заботится о встроенном classpath в баночках.

Хитрость заключается в том, чтобы добавить аргументы компилятора -Xlint:-path, хотя изначально я был сомневаюсь в этом решении. Выполнение этого приведет к подавлению предупреждений/ошибок в неправильном пути, и поэтому Maven не будет преждевременно останавливать сборку. Проблема была в том, чтобы выяснить правильный синтаксис для встраивания этих аргументов в pom.xml. Вот где this article пригодится. Таким образом, конфигурация компилятор плагина должен выглядеть следующим образом следует понимать правильно:

<plugins> 
    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <configuration> 
      <source>${java-version}</source> 
      <target>${java-version}</target> 
      <compilerArguments> 
       <Xlint/> 
       <Xlint:-path/> 
      </compilerArguments> 
      <showWarnings>true</showWarnings> 
      <showDeprecation>true</showDeprecation> 
     </configuration> 
    </plugin> 
</plugins> 

Обратите внимание, что этот синтаксис не очень хорошо XML (как Бейн указывает), и большинство Иды отметит второй Xlint линию как ошибка, но она будет работать с Maven. Использование синтаксиса, приведенного в некоторых учебниках Maven, может привести к тому, что аргументы, которые не передаются компилятору вообще, или только последний передаваемый аргумент.

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

0

Проблема заключается в том, что вы ссылаетесь на пост, который семь лет old..and не использовать более поздние версии maven-compiler-plugin:

Аргументы javac compiler может лучше сделать так:

<project> 
    [...] 
    <build> 
    [...] 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.6.1</version> 
     <configuration> 
      <compilerArgs> 
      <arg>-Xlint</arg> 
      <arg>-Xlint:-path</arg> 
      </compilerArgs> 
     </configuration> 
     </plugin> 
    </plugins> 
    [...] 
    </build> 
    [...] 
</project> 
+0

Сообщение, на которое я ссылаюсь, может быть 7 лет, но это единственный рабочий совет, который я нашел , Рабочий совет. –

+0

Кроме того, если вы хотите предоставить соответствующую ссылку на текущие документы для плагина компилятора maven, вот более прямая ссылка, которая фактически содержит соответствующий пример с участием '-Xlint': http://maven.apache.org/plugins/ maven-compiler-plugin/examples/pass-compiler-arguments.html Однако обратите внимание, что мы вынуждены использовать версию 2.5.1 плагина компилятора (последнее, как представляется, 3.6.1). Зачем? Потому что это разрабатывается для третьей стороны, и это то, что они указали. Так что догадаться? Синтаксис, который вы укажете здесь, не будет работать для меня вообще. –

+0

Наконец, я должен указать, что пример, приведенный в вышеупомянутой ссылке (мой предыдущий комментарий), ясно показывает еще лучший способ указать аргументы '-Xlint' для случая использования, когда вам нужно включить все проверки/предупреждения, за исключением одного или два, и это позволяет вам сделать это на одной строке: ' -Xlint: all, -options, -path' Использование списка предупреждений, разделенных запятыми, выглядело немного странно для моих глаз, но javac поддерживает это точный синтаксис из командной строки. Слишком плохо, что это не работает для параметров командной строки, таких как '-bootclasspath'; см. http://stackoverflow.com/a/42042367/7491719 –