14 de nov. de 2020

Criando JARs de aplicações JavaFX

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();
}
}
view raw App.java hosted with ❤ by GitHub
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);
}
}
view raw Main.java hosted with ❤ by GitHub
<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>
view raw pom.xml hosted with ❤ by GitHub