Как создать исполняемый jar-файл с помощью maven-jar-plugin и Groovy?

У меня есть пример приложения с основным классом в Groovy и основным классом в Java. maven-jar-plugin успешно создает исполняемый файл jar, когда класс Java указан как основной класс, но не, когда класс Groovy. Позвольте мне продемонстрировать. Вот моя сборка:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.0.2</version>
      <configuration>
        <archive>
          <manifest>
            <mainClass>com.example.hello.JavaHello</mainClass>
          </manifest>
        </archive>
      </configuration>
    </plugin>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
        <compilerId>groovy-eclipse-compiler</compilerId>
        <verbose>false</verbose>
        <source>${java.compiler.version}</source>
        <target>${java.compiler.version}</target>
      </configuration>
      <dependencies>
        <dependency>
          <groupId>org.codehaus.groovy</groupId>
          <artifactId>groovy-eclipse-compiler</artifactId>
          <version>${groovy-eclipse-compiler.version}</version>
        </dependency>
        <dependency>
          <groupId>org.codehaus.groovy</groupId>
          <artifactId>groovy-eclipse-batch</artifactId>
          <version>2.4.3-01</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

Затем компилируем и запускаем:

$ mvn -q clean package && \
>   jar xf target/hello-world-1.0-SNAPSHOT.jar META-INF/MANIFEST.MF && \
>   cat META-INF/MANIFEST.MF && rm -r META-INF && \
>   java -jar target/hello-world-1.0-SNAPSHOT.jar
Manifest-Version: 1.0
Built-By: tytk
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_66
Main-Class: com.example.hello.JavaHello

Hello from Java!

Затем измените mainClass на:

<mainClass>com.example.hello.GroovyHello</mainClass>

И выполнив ту же команду:

$ mvn -q clean package && \
>   jar xf target/hello-world-1.0-SNAPSHOT.jar META-INF/MANIFEST.MF && \
>   cat META-INF/MANIFEST.MF && rm -r META-INF && \
>   java -jar target/hello-world-1.0-SNAPSHOT.jar
Manifest-Version: 1.0
Built-By: tytk
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_66
Main-Class: com.example.hello.GroovyHello

Error: Could not find or load main class com.example.hello.GroovyHello

У каждого класса есть только основной метод с оператором println.

Итак, как я могу получить исполняемый файл jar с моими отличными классами? maven-shade-plugin работает, но мне не нужна толстая банка - я хочу исключить зависимости.


person tytk    schedule 05.11.2016    source источник
comment
можете показать нам структуру проекта? где находится класс GroovyHello (путь к папке)?   -  person AlinG    schedule 06.11.2016
comment
оба GroovyHello и JavaHello расположены по адресу hello-world/src/main/java/com/example/hello/   -  person tytk    schedule 07.11.2016


Ответы (1)


Я вижу ваше примечание об исключении зависимостей, поэтому вы не хотите использовать maven-shaded-plugin. Я не уверен, насколько хорошо это будет работать с классом Groovy.

(Но стоит отметить явным образом себе и другим новичкам в Java: maven-jar-plugin не включает зависимости)

Первая возможность: не работает ли Java из-за того, что она не может найти Groovy и действительно этого хочет?

Я нашел SO-ответ о возможности загрузки основных классов, которые расширяются от зависимых классов.

Я знаю, что простой файл сценария Groovy без явного объявления класса, который компилятор обертывает в класс, который он наследует от (Groovy's) Script. Я не знаю, что произойдет, если вы напишете свой собственный явный класс - я бы распаковал .jar и использовал декомпилятор Java., чтобы посмотреть на сгенерированный код и узнать, дает ли он какие-либо подсказки.

Вторая возможность: название пакета

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

Итак, два способа исправить это:

  1. Добавьте объявление package в свой сценарий Groovy.

    package com.example.hello
    println "I'm Groovy!"
    
  2. Пусть ваш тег maven mainClass относится к классу без пространства имен пакета (например: GroovyHello вместо com.example.hello.GroovyHello

person RyanWilcox    schedule 06.04.2017