Faltan los componentes de Maven Shade JavaFX runtime
javafx-11 (1)
Estoy intentando crear un frasco autocontenido JFX11 utilizando dependencias de Maven. A partir de la investigación que he hecho, parece que la mejor manera de hacerlo es a través del complemento Maven Shade. Sin embargo, cuando lo ejecuto, me sale este error:
Error: faltan componentes de tiempo de ejecución de JavaFX y se requieren para ejecutar esta aplicación
No entiendo por qué sucede esto. ¿Qué estoy arruinando? ¿Hay una mejor manera de hacer esto? También he probado el plugin de montaje de Maven con el mismo mensaje.
archivo pom para referencia
<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>
Esta answer explica por qué un archivo fat / uber jar falla en JavaFX 11. En resumen:
Este error proviene de sun.launcher.LauncherHelper en el módulo java.base. La razón de esto es que la aplicación principal extiende la aplicación y tiene un método principal. Si ese es el caso, LauncherHelper comprobará que el módulo
javafx.graphics
esté presente como un módulo con nombre. Si ese módulo no está presente, el lanzamiento se cancela.
Y ya propone una solución para Gradle.
Para Maven, la solución es exactamente la misma: proporcionar una nueva clase principal que no se extienda desde
Application
.
Tendrá una nueva clase en su paquete de
application
(nombre incorrecto):
// NewMain.java
public class NewMain {
public static void main(String[] args) {
Main.main(args);
}
}
Y su clase
Main
existente, como es:
//Main.java
public class Main extends Application {
@Override
public void start(Stage stage) {
...
}
public static void main(String[] args) {
launch(args);
}
}
Ahora necesita modificar su pom y configurar su clase principal para los diferentes complementos:
<mainClass>application.NewMain</mainClass>
Tarro de grasa específico de la plataforma
Finalmente, con el plugin de sombra vas a producir un frasco de grasa en tu máquina .
Esto significa que, hasta ahora, sus dependencias de JavaFX están utilizando un clasificador único.
Si, por ejemplo, está en Windows, Maven utilizará internamente el clasificador de
win
.
Esto tiene el efecto de incluir solo las bibliotecas nativas para Windows.
Así que estás utilizando:
- org.openjfx: javafx-controls: 11
- org.openjfx: javafx-controls: 11: win
- org.openjfx: javafx-graphics: 11
- org.openjfx: javafx-graphics: 11: win <- esto contiene los archivos DLL nativos para Windows
- org.openjfx: javafx-base: 11
- org.openjfx: javafx-base: 11: win
Ahora, si produce el frasco grande, agrupará todas esas dependencias (y aquellas otras dependencias de terceros habituales de su proyecto), y podrá ejecutar su proyecto como:
java -jar myFatJar-1.0-SNAPSHOT.jar
Si bien esto es muy bueno, si desea distribuir su jar, tenga en cuenta que este jar no es multiplataforma y solo funcionará en su plataforma, en este caso Windows.
Jarra de grasa multiplataforma
Existe una solución para generar un jar multiplataforma que puede distribuir: incluya el resto de las bibliotecas nativas de las otras plataformas.
Esto se puede hacer fácilmente, ya que solo necesita incluir las dependencias del módulo de gráficos para las tres plataformas:
<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>
tamaño
Hay un problema principal con este enfoque: el tamaño. Como puede ver en esta otra answer , si usa el control WebView, estará empaquetando alrededor de 220 MB debido a las bibliotecas nativas de WebKit.