Zbuduj wieloplatformowy plik wykonywalny dla aplikacji SWT za pomocą Maven

Moje pytanie brzmi: w jaki sposób można wygenerować wiele plików wykonywalnych Jar (w tym zależności) dla aplikacji SWT zgodnie z docelowym os / architektura jednocześnie za pomocą Maven?

Stworzyłem aplikację SWT, która musi działać na różnych systemach operacyjnych i architekturach. Projekt jest wielomodułowym projektem Maven, w tym macierzystym POM.

project-pom.xml (packaging = pom, specify SWT dependencies)
`- application-module (inherit SWT dependencies)
   `- pom.xml (packaging = jar)
`- domain-specific-module
   `- pom.xml (packaging = jar)
`- utils-module (inherit SWT dependencies)
   `- pom.xml (packaging = jar)

W nadrzędnym POM (project-pom.xml) Uwzględniłem zależności SWT według mojego systemu operacyjnego i architektury za pomocą profili Maven, które działają dobrze:

<dependencies>
    <dependency>
        <groupId>org.eclipse.swt</groupId>
        <artifactId>${swt.artifactId}</artifactId>
        <version>4.3</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>EclipseSwtRepository</id>
        <url>https://swt-repo.googlecode.com/svn/repo/</url>
    </repository>
</repositories>

<profiles>
    <profile>
        <id>unix-amd64</id>
        <activation>
            <os>
                <family>unix</family>
                <arch>amd64</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId>
        </properties>
    </profile>
    <profile>
        <id>windows-x86</id>
        <activation>
            <os>
                <family>windows</family>
                <arch>x86</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.win32.win32.x86</swt.artifactId>
        </properties>
    </profile>
    <profile>
        <id>windows-x86_64</id>
        <activation>
            <os>
                <family>windows</family>
                <arch>x86_64</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.win32.win32.x86_64</swt.artifactId>
        </properties>
    </profile>
</profiles>

Teraz maven wybiera odpowiednią zależność SWT, np. do kompilacji aplikacji. Sprawdziłem aktywny profil za pomocą polecenia mavenmvn help:active-profiles.

Teraz chcę wygenerować wykonywalne słoiki dla platform docelowych linux_x86_64 / amd64, windows_x86 i windows_x86_64. W pierwszym kroku użyłemmaven-jar-plugin wygenerować słoik i plik manifestu (application-module/pom.xml):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>libs/</classpathPrefix>
                 <mainClass>qualified.path.to.MyApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

To działa dobrze. Słoik jest generowany, a manifest jest wewnątrz. Jak widać, moim zamiarem jest umieszczenie wszystkich zależności w katalogu o nazwielib/. Ale plik Jar nie jest wykonywalny (brakuje bibliotek).

Następnym krokiem (teoretycznie) jest znalezienie zależności i skopiowanie ich w postaci kostkilib/ katalog podczaspackage faza. W tym kroku (próbowałem) użyć wtyczki zależnej od Maven (application-module/pom.xml):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.8</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

Jeśli uruchomię poleceniemvn package nic się nie dzieje (w katalogu nie jest tworzony żaden katalog)target/ lub gdzie indziej). Aby sprawdzić, czy wtyczka działa poprawnie, użyłem poleceniamvn dependency:copy-dependencies który utworzył katalog o nazwiedependency (Zakładam domyślnie dla tej wtyczki) i umieściłem tam wszystkie zależne pliki Jar.

To pierwszy problem, jaki mam. Kolejny problem polega na tym, jak mogę utworzyć wiele (nie tylko pojedynczych) plików wykonywalnych Jar zgodnie z docelową architekturą os / mojej aplikacji SWT jednocześnie (za pomocą jednego polecenia, takiego jakmvn package)? Wynikowa struktura katalogu kompilacji powinna wyglądać podobnie do tej:

target/
`- linux_x86_64/
   `- application-version_linux_x86_64.jar
   `- libs/
      `- org.eclipse.swt.gtk.linux.x86_64-4.3.jar
      `- ...
`- windows_x86/
   `- application-version_windows_x86.jar
   `- libs/
      `- org.eclipse.swt.win32.win32.x86-4.3.jar
      `- ...
`- windows_x86_64/
   `- application-version_x86_64.jar
   `- libs/
      `- org.eclipse.swt.win32.win32.x86_64-4.3.jar
      `- ...

Innym rozwiązaniem jest umieszczenie zależności w pliku Jar bezpośrednio, ale obecnie nie wiem, jak mogę to zrobić.

Czytałem o innych wtyczkach w tym kontekście (maven-assembly-plugin, maven-shade-plugin), ale obecnie są to dla mnie zbyt wiele informacji i sprawdzam, czy będzie działać, czy nie. Czy ktoś może mi powiedzieć, która wtyczka jest najlepsza do moich celów?

Po wykonaniu tej czynności chcę użyćplugin launch4j-maven do generowania rodzimych plików wykonywalnych systemu Windows (użytkownik końcowy nie lubi odczuć nie rodzimych plików wykonywalnych), używając poprzednich generowanych plików wykonywalnych Jar dla okien.

Mam nadzieję, że to wystarczająca ilość informacji.

questionAnswers(1)

yourAnswerToTheQuestion