web-dev-qa-db-fra.com

Il manque des composants d'exécution JavaFX Maven Shade

J'essaie de créer un JAR contenant JFX11 en utilisant des dépendances maven. D'après les recherches que j'ai effectuées, il semble que le meilleur moyen de le faire consiste à utiliser le plugin maven shade. Cependant, lorsque je l'exécute, j'obtiens l'erreur suivante:

Erreur: les composants d'exécution JavaFX sont manquants et sont nécessaires pour exécuter cette application.

Je ne comprends pas pourquoi cela se passe. Qu'est-ce que je fous? Y a-t-il une meilleure manière de faire cela? J'ai aussi essayé le plugin maven Assembly avec le même message.

pom file pour référence

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>Application</groupId>
    <artifactId>Main</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpaceRunner</name>
    <url>http://maven.Apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>10</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>Java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>Application.Main</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>
                                Application.Main
                            </mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.Apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>Application.Main</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
22
Bitclef

Ceci réponse explique pourquoi un jar fat/uber échoue sous JavaFX 11. En bref:

Cette erreur provient de Sun.launcher.LauncherHelper du module Java.base. La raison en est que l'application principale étend l'application et dispose d'une méthode principale. Si tel est le cas, LauncherHelper recherchera le javafx.graphics module à présenter en tant que module nommé. Si ce module n'est pas présent, le lancement est annulé.

Et propose déjà un correctif pour Gradle.

Pour Maven, la solution est exactement la même: fournir une nouvelle classe principale qui ne s'étend pas de Application.

Vous aurez une nouvelle classe dans votre paquet application (mauvais nom):

// NewMain.Java
public class NewMain {

    public static void main(String[] args) {
        Main.main(args);
    }
}

Et votre classe Main existante, telle quelle:

//Main.Java
public class Main extends Application {

    @Override
    public void start(Stage stage) {
        ...
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Maintenant, vous devez modifier votre pom et définir votre classe principale pour les différents plugins:

<mainClass>application.NewMain</mainClass>

Fat jar spécifique à la plate-forme

Enfin, avec le plugin shade, vous allez produire un gros pot, sur votre machine.

Cela signifie que, jusqu'à présent, vos dépendances JavaFX utilisent un classificateur unique. Si, par exemple, vous êtes sous Windows, Maven utilisera en interne le classificateur win. Cela a pour effet d'inclure uniquement les bibliothèques natives pour Windows.

Donc, vous utilisez:

  • org.openjfx: javafx-controls: 11
  • org.openjfx: javafx-controls: 11: gagner
  • org.openjfx: javafx-graphics: 11
  • org.openjfx: javafx-graphics: 11: win <- contient les dll natives pour Windows
  • org.openjfx: javafx-base: 11
  • org.openjfx: javafx-base 11: gagner

Maintenant, si vous produisez le gros pot, vous regrouperez toutes ces dépendances (et les autres dépendances tierces habituelles de votre projet) et vous pourrez exécuter votre projet en tant que:

Java -jar myFatJar-1.0-SNAPSHOT.jar

Bien que ce soit très agréable, si vous voulez distribuer votre fichier jar, sachez que ce fichier est pas multiplate-forme, et que cela ne fonctionnera que sur votre plate-forme, dans ce cas Windows.

Fat Jar multiplateforme

Il existe une solution pour générer un fichier jar multiplate-forme que vous pouvez distribuer: incluez le reste des bibliothèques natives des autres plates-formes.

Cela peut être fait facilement, il suffit d’inclure les dépendances du module graphique pour les trois plates-formes:

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>11</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics </artifactId>
        <version>11</version>
        <classifier>win</classifier>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics </artifactId>
        <version>11</version>
        <classifier>linux</classifier>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics </artifactId>
        <version>11</version>
        <classifier>mac</classifier>
    </dependency>
</dependencies>

Taille

Cette approche présente un problème majeur: la taille. Comme vous pouvez le voir dans cet autre réponse , si vous utilisez le contrôle WebView, vous regrouperez environ 220 Mo en raison des bibliothèques natives WebKit.

44
José Pereda