O FAT JAR (JAR Gordo) é um tipo de distribuição de aplicações Java onde um único JAR contém todas as dependencias para a aplicação ser executada, necessitando somente de uma máquina virtual Java, uma JVM.
Para qualquer aplicação Java baseada em maven, criar um FAT JAR poderia ser resolvido usando o plugin Maven Shade. No entanto, criar FAT Jars com JavaFX pode ser um desafio, pois JavaFX usa módulos.
Felizmente esse assunto foi intensamente discutido na internet e uma boa explicação e olução foi proposta pelo Jose Pereda nessa resposta no StackOverflow.
Nesse post eu quero brevemente compartilhar os passos para fazer um FAT JAR e postar um exemplo do meu github para que outros possam criar seus próprios JARs baseados nesses exemplo.
Como criar um JAR de uma aplicação JavaFX?
1- Crie uma classe com o método main para rodar sua aplicação. Essa classe precisa ter o método main e chamar a sua real aplicação usando o método main dela;
2- Adicione o plugin shade para o seu projeto. Para quem usar o Gradle notem que o próprio José Pereda postou uma resposta sobre isso no Stack Overflow;
3- Na sua configuração do plugin shade certifique-se que você configurou a classe que criou no passo 1.
Isso é basicamente tudo que você precisa. Se não estiver claro, cheque meu exemplo no github. Os três arquivos, App.java, Main.java e pom.xml podem ser vistos abaixo.
package org.fxapps.javafx.fatjar; | |
import javafx.animation.Animation; | |
import javafx.animation.FadeTransition; | |
import javafx.application.Application; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Label; | |
import javafx.scene.effect.InnerShadow; | |
import javafx.scene.layout.StackPane; | |
import javafx.scene.paint.Color; | |
import javafx.scene.text.Font; | |
import javafx.scene.text.FontWeight; | |
import javafx.stage.Stage; | |
import javafx.stage.StageStyle; | |
import javafx.util.Duration; | |
public class App extends Application { | |
public static void main(String[] args) { | |
launch(); | |
} | |
@Override | |
public void start(Stage stage) throws Exception { | |
var lblHello = new Label("Hello World!"); | |
var fd = new FadeTransition(Duration.millis(900), lblHello); | |
// Label Setup | |
lblHello.setFont(Font.font(Font.getDefault().getFamily(), FontWeight.BOLD, 60)); | |
lblHello.setEffect(new InnerShadow()); | |
lblHello.setTextFill(Color.GOLD); | |
lblHello.setOnMouseClicked(e -> System.exit(0)); | |
// Animation Setup | |
fd.setAutoReverse(true); | |
fd.setFromValue(1.0); | |
fd.setToValue(0.2); | |
fd.setCycleCount(Animation.INDEFINITE); | |
fd.play(); | |
stage.setScene(new Scene(new StackPane(lblHello))); | |
stage.initStyle(StageStyle.UNDECORATED); | |
stage.show(); | |
} | |
} |
package org.fxapps.javafx.fatjar; | |
// This is the Main used by the shade plugin. | |
public class Main { | |
public static void main(String[] args) { | |
App.main(args); | |
} | |
} |
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>org.fxapps.javafx.fatjar</groupId> | |
<artifactId>fatjar-javafx</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<name>Fat Jar JavaFX</name> | |
<description>Project to build a JavaFX 11+ Fat JAR.</description> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<maven.compiler.release>11</maven.compiler.release> | |
<maven.compiler.source>11</maven.compiler.source> | |
<maven.compiler.target>11</maven.compiler.target> | |
<javafx.version>11.0.2</javafx.version> | |
<javafx.plugin.version>0.0.4</javafx.plugin.version> | |
<main.class>org.fxapps.javafx.fatjar.Main</main.class> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.openjfx</groupId> | |
<artifactId>javafx-base</artifactId> | |
<version>${javafx.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.openjfx</groupId> | |
<artifactId>javafx-graphics</artifactId> | |
<version>${javafx.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.openjfx</groupId> | |
<artifactId>javafx-controls</artifactId> | |
<version>${javafx.version}</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.openjfx</groupId> | |
<artifactId>javafx-maven-plugin</artifactId> | |
<version>${javafx.plugin.version}</version> | |
<configuration> | |
<mainClass>${main.class}</mainClass> | |
</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>${main.class}</mainClass> | |
</transformer> | |
</transformers> | |
</configuration> | |
</execution> | |
</executions> | |
</plugin> | |
</plugins> | |
</build> | |
</project> |