Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Сборка Maven проекта в jar файл


Автор: NZero 24.6.2019, 12:52
Всем привет!

Пытаюсь собрать Maven в jar файл средствами Intellij Idea. В интернете пишут, что нужно всего лишь сделать структуру pom.xml файла нужную и всё заработает. У меня pom.xml получился следующий:

Код

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>TestITPhoneClient</groupId>
<artifactId>ru.minicom</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>TestITPhoneClient</name>
<url>http://maven.apache.org</url>
 
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-beta-1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sikulix/sikulixapi -->
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
 
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<mainClass>TestClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
 
</project>


При сборке никак не хочет появляться jar файл в директории target. В чём ошибка?

user posted image

Автор: Се ля ви 24.6.2019, 14:15
Во-первых, idea тут не при чём, собирать нужно в командной строке самим maven'ом примерно так:
Код
./mvnw verify

Во-вторых, mainClass должен быть в пакете, и с пакетом же должен быть указан в теге <mainClass>
В-третьих, все версии нужно выносить в секцию properties, а в самих зависимостях - на них ссылаться, иначе не будет работать чрезвычайно удобный maven-version plugin
В-четвёртых, groupID обычно именуется так же как пакеты - от сайтов с перестановкой домена первого и второго уровня, а такой groupId - TestITPhoneClient - я бы сказал, весьма диковат...
В-пятых, почитай про принцип "Convention Over Configuration", то что по умолчанию итак работает - писать не надо. В частности, тег packaging итак по умолчанию имеет значение jar в super-POM'е - так что не нужно его указывать вообще, это - тавтология. То же самое относится к maven'овским plugin'ам. Если значение groupId
Код
<groupId>org.apache.maven.plugins</groupId>

, то его так же можно не писать.
В-шестых, всё по тому же принипу CoC, ты не указал версию Java'ы, так что (для maven-plugin'а 3.8.1) получишь Java'у то ли 1.6, то ли 1.7 - тебя это точно устроит? Может, лучше указать явно?
В-седьмых, ты не используешь никакого BOM'а, да и по ходу на чистой Java'е собрался писать - без Lombok'а и Manifold'а, не используешь библиотеку Vavr, а для тестов - морально-устаревший JUnit 4 без assertJ - на голом Hamcrest'е и без mock'ов... ну смотри, по-моему так писать - сплошное мучение...
В-восьмых, зависимость
Код
<dependency>
  <groupId>com.sikulix</groupId>
  <artifactId>sikulixapi</artifactId>
  <version>1.1.2</version>
</dependency>

имеет проблемы - транзитивно она тянет за собой зависимость
Код
<dependency>
  <groupId>com.github.vidstige</groupId>
  <artifactId>jadb</artifactId>
  <version>-v1.0-g94ebf38-23</version>
</dependency>

, которой нет в maven.central'е, который в Maven'е используется по умолчанию как источник jar'ников. На https://mvnrepository.com/artifact/com.github.vidstige/jadb/-v1.0-g94ebf38-23 очень кстати есть приписка:
Цитата
Note: this artifact it located at Mulesoft repository (https://repository.mulesoft.org/nexus/content/repositories/public/)

она означает, что для того, что бы воспользоваться этой зависимостью, следует прописать этот репозиторий так же в своём pom'нике (лучше - непосредственно перед блоком dependencies):
Код
<repositories>
  <repository>
    <id>Mulesoft</id>
    <url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
  </repository>
</repositories>

Кроме того, версия этой зависимости явно кривая и, видимо, после обнаружения сего факта, её тупо удалили из этого репозитория, что и привело к проблеме (её там нет). По-этому на той же странице можем видеть, что
Цитата
Note: There is a new version for this artifact

и ниже видим, что версия эта - "94ebf38"
Соответственно, в таких случаях я обычно ДОПУСКАЮ, что автор библиотеки не поломал обратную совместимость и делаю операцию по замене старой транзитивной зависимости на новую явную. В принципе, для этого можно было бы просто подсунуть более новую и положиться на то, что Maven сам выберет ту, которая более новая, но Maven в этом плане может затупить, если ему не хватит метаданных, так что полагаться на этот механизм в общем случае я бы не стал. Лучше исключить транзитивную зависимость явно и уже вместо этого явно подтянуть ей на замену свою зависимость со своей версией.
Короче говоря, выглядеть pom'ник c этой зависимостью и 11-й Java'ой у тебя по итогу должен примерно вот так:
Код
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>TestITPhoneClient</groupId>
  <artifactId>demo-project</artifactId>
  <version>1.0</version>
  <name>TestITPhoneClient</name>
  <url>http://maven.apache.org</url>

  <properties>

    <!--region General-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>11</java.version>
    <!--endregion-->

    <!--region Libs -->
    <selenium-java.version>3.141.59</selenium-java.version>
    <sikulixapi.version>1.1.2</sikulixapi.version>
    <jadb.version>94ebf38</jadb.version>
    <junit.version>4.13-beta-1</junit.version>
    <!--endregion-->

    <!--region Plugins-->
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
    <maven.compiler.release>${java.version}</maven.compiler.release><!-- for compiler plugin version >= 3.8 -->
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven-jar-plugin.version>3.1.2</maven-jar-plugin.version>
    <!--endregion-->

  </properties>

  <repositories>
    <repository>
      <id>Mulesoft</id>
      <url>https://repository.mulesoft.org/nexus/content/repositories/public</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium-java.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
    </dependency>

    <dependency><!-- https://mvnrepository.com/artifact/com.sikulix/sikulixapi -->
      <groupId>com.sikulix</groupId>
      <artifactId>sikulixapi</artifactId>
      <version>${sikulixapi.version}</version>
      <exclusions>
        <exclusion>
          <groupId>com.github.vidstige</groupId>
          <artifactId>jadb</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.github.vidstige</groupId>
      <artifactId>jadb</artifactId>
      <version>${jadb.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
      </plugin>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>${maven-jar-plugin.version}</version>
        <configuration>
          <archive>
            <manifest>
              <mainClass>mypackage.TestClass</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Автор: NZero 25.6.2019, 15:35
Ура, проект собрался, только теперь ругается при запуске

Код

D:\Project\ITPhone_Firelink\ver.8.0\Tests\ClientTest>java -jar target\ru.minicom-1.0.jar
Error: Could not find or load main class mypackage.TestClass

Автор: NZero 25.6.2019, 16:59
Вроде разобрался что нужно писать.

Код

package ru.minicom.itphone.client;

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class RunTests {
public static void main(String[] args){
Result result = JUnitCore.runClasses(LoginPageTest.class);

System.out.println("Total number of tests " + result.getRunCount());

System.out.println("Total number of test failed " + result.getFailureCount());

for(Failure failure : result.getFailures()){
System.out.println(failure.getMessage());
}

System.out.println(result.wasSuccessful());
}
}



В pom.xml пописал

Код

<configuration>
<archive>
<manifest>
<mainClass>ru.minicom.itphone.client.RunTests</mainClass>
</manifest>
</archive>
</configuration>



Но при компиляции теперь ругается 

Код

D:\Project\ITPhone_Firelink\ver.8.0\Tests\ClientTest>mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------< TestITPhoneClient:ru.minicom.itphone.client >-------------
[INFO] Building TestITPhoneClient 1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ ru.minicom.itphone.client ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 10 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ ru.minicom.itphone.client ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 5 source files to D:\Project\ITPhone_Firelink\ver.8.0\Tests\ClientTest\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.158 s
[INFO] Finished at: 2019-06-25T16:53:34+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project ru.minicom.itphone.client: Fatal error compiling: invalid flag: --release -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Автор: LSD 26.6.2019, 10:11
Замени
Код

<maven.compiler.release>${java.version}</maven.compiler.release><!-- for compiler plugin version >= 3.8 -->
<maven.compiler.parameters>true</maven.compiler.parameters>

на
Код

<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

Автор: NZero 26.6.2019, 12:01
Цитата(LSD @ 26.6.2019,  10:11)
Замени
Код

<maven.compiler.release>${java.version}</maven.compiler.release><!-- for compiler plugin version >= 3.8 -->
<maven.compiler.parameters>true</maven.compiler.parameters>

на
Код

<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

Спасибо) Работает

Автор: Се ля ви 27.6.2019, 00:28
Так какая всё-таки версия Java'ы?
Начиная с 9-й Java'ы работает ( https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#release )
Код
<maven.compiler.release>${java.version}</maven.compiler.release>
 А до этого приходилось дублировать, что весьма раздражало...

LSD, но вот это -
Код
<maven.compiler.parameters>true</maven.compiler.parameters>

зачем ты пишешь, что нужно заменять? Оно ничем не помешает. Это - ни что иное, как флаг "-parameters" компилятору ( https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#parameters ) . Начиная с 8-й версии Java'ы он добавляет метаинформацию в байт-код, благодаря которой через Reflection можно узнать имена параметров методов и конструкторов. Без этого флага имена, как бы ты их реально не называл, будут "arg0", "arg1", "arg2" и т.д.

Автор: LSD 28.6.2019, 13:18
Цитата(Се ля ви @  27.6.2019,  01:28 Найти цитируемый пост)
зачем ты пишешь, что нужно заменять?

Я просто придерживаюсь мнения, что не стоит добавлять параметры которые не нужны.

Автор: Се ля ви 28.6.2019, 18:36
 smile
Цитата(LSD @  28.6.2019,  13:18 Найти цитируемый пост)
Цитата(Се ля ви @  27.6.2019,  00:28 Найти цитируемый пост)
зачем ты пишешь, что нужно заменять?

Я просто придерживаюсь мнения, что не стоит добавлять параметры которые не нужны.

А... Ну в целом позиция понятна, но ведь ты не станешь отрицать, что бывают вещи, которые просто более логичны, чем поведение по-умолчанию - являются best practice и не добавлены в язык и платформу по умолчанию только из-за backward-compatibility. И в Java'е их много. Те же самые private'ы, которые нужно везде ставить или CheckedException'ы, необходимость самому писать getter'ы, setter'ы, equals'ы, hashCode'ы, toString'и, конструкторы, которые просто инициализируют поля, или вот возможность через Reflection узнавать имена параметров методов и конструкторов...

Соответственно, я предпочитаю, что бы они у меня просто всегда были в любом проекте, с которым я работаю. Java не была выстроена по "Convention over Configuration", но в наших силах её для себя исправить - особенно сегодня, когда есть Lombok и Manifold. Поэтому я разрабатываю сейчас собственный стартер для проектов на Java, в который всё это и включил - и теперь уверен, что на всех моих проектах всё будет так как мне надо. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)