javafx的maven项目打jar包配置
项目结构
.
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ ├── com
│ │ │ │ └── bingbaihanji
│ │ │ │ ├── Main.java ──────────────────────────────> 继承 javafx.application.Application
│ │ │ │ ├── StartApplication.java ────────────────> 启动类 Main.main(args);
│ │ │ │ ├── data
│ │ │ │ │ └── CpuLoadMetricService.java
│ │ │ │ └── view
│ │ │ │ ├── CustomStage.java
│ │ │ │ └── SystemAreaChartView.java
│ │ │ └── module-info.java
│ │ └── resources
│ │ ├── chart-styles.css
│ │ ├── close.png
│ │ ├── cpu.png
│ │ ├── logback.xml
│ │ ├── max.png
│ │ └── min.png
│ └── test
│ └── java
│ └── com
│ └── bingbiahanji
│ └── SimpleBigInteger.java
1.使用使用maven打包插件 maven-shade-plugin 将项目打包成fatjar
完整 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bingbaihanji</groupId>
<artifactId>fxoshi</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>21</java.version>
<javafx.version>21.0.4</javafx.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.6.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>${javafx.version}</version>
</dependency>
<!-- slf4j与logback集成配置 -->
<!-- slf4j日志门面 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- logback 日志实现-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.14</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
<!--logback提供HTTP访问日志功能-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.4.14</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>javafx-windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
</dependency>
</dependencies>
</profile>
<profile>
<id>javafx-linux</id>
<activation>
<os>
<family>linux</family>
</os>
</activation>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
<classifier>linux</classifier>
</dependency>
</dependencies>
</profile>
<profile>
<id>javafx-macos</id>
<activation>
<os>
<family>mac</family>
</os>
</activation>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
<classifier>mac</classifier>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
<plugins>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>21</source> <!-- 替换为项目使用的 JDK 版本 -->
<target>21</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<configuration>
<mainClass>com.bingbaihanji.Main</mainClass>
</configuration>
</plugin>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- 指定 Main-Class -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.bingbaihanji.StartApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
在项目根目录下执行 mvn package
在 target
目录下生成fatjar 可以直接使用java -jar
方式启动
其中 MANIFEST.MF
内容为
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.5
Built-By: 冰白寒祭
Build-Jdk: 21.0.5
Main-Class: com.bingbaihanji.StartApplication
此jar包可以通过graalvm 打包成平台对应的二进制可执行文件
Graalvm通过静态分析提前编译来为Java应用程序构建高度优化的本机可执行文件,这就需要在编译时就知道所有的程序类型,而java中的jni、反射、动态代理等功能,在编译时不确定具体的类型,所以在使用GraalVm构建native image前需要通过配置列出反射可见的所有类型。而程序内置提供了agentlib
具体步骤如下
1 使用agentlib打包跟踪jvm生成配置文件
java -agentlib:native-image-agent=config-output-dir=.\${artifactId}\ -jar [jar包]
这里的 {artifactId} 为 jar包的 artifactId,执行后会在{artifactId} 目录下生成 配置文件。
2 配置jar包
在jar包里边的META-INF文件夹中创建native-image文件夹,在native-image新增带有groupid(com.bingbaihanji)和artifactId(将生成的${artifactId}复制到native-image目录下)
3 编译成平台二进制可执行文件
在配置好c编译语言环境的终端中执行 native-image -jar [jar包] --no-fallback --static
编译完成后可直接运行二进制可执行文件
其中
--no-fallback build stand-alone image or report failure [构建独立镜像(不依赖环境jvm),如果失败,则报告错误]
--static build statically linked executable (requires static libc and zlib) [构建静态链接的可执行文件(需要静态版本的 libc 和 zlib)]
若 windows 环境报错 Native-image building on Windows currently only supports target architecture: AMD64 (?? unsupported)
需要设置 Visual Studio
中只保留英文语言包
2.使用maven打包插件 maven-dependency-plugin 将项目打包成分散的jar包 (项目启动包和依赖库)
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>com.bingbaihanji.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
然后在当前项目下运行 mvn package
即可打包完成 在 target
目录下生成 libs 和 项目的jar包,
其中libs是项目运行时所依赖的库,其中项目jar包的清单文件内容为
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.5
Built-By: 冰白寒祭
Build-Jdk: 17.0.2
Class-Path: libs/javafx-controls-17.0.2.jar libs/javafx-controls-17.0.2-
win.jar libs/javafx-graphics-17.0.2.jar libs/javafx-graphics-17.0.2-win
.jar libs/javafx-base-17.0.2.jar libs/javafx-base-17.0.2-win.jar libs/j
avafx-fxml-17.0.2.jar libs/javafx-fxml-17.0.2-win.jar
Main-Class: com.bingbaihanji.Main
如果此时直接用 java -jar 命令来运行项目jar包会提示 错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
是由于从 jdk9 开始 java开始添加了以模块化来构建项目的规范;
解决办法有
1.可以添加jvm参数
可以在当前路径下执行
java -jar --module-path ./libs --add-modules javafx.controls,javafx.fxml ./javaFxDemo.jar
来启动项目。
2.在项目中添加一个启动类
maven打包的时候主类指定为启动类
修改maven插件配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>com.bingbaihanji.Start</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
新建一个启动类
package com.bingbaihanji;
import com.bingbaihanji.Main;
/**
* @author 冰白寒祭
* @date 2023-12-03 00:09:51
* @description //TODO
*/
public class Start {
public static void main(String[] args) {
Main.main(args);
}
}
重新打包后即可直接用 java -jar
的方式来启动项目
3.使用springboot的maven打包插件[简单快捷]来打成一个可执行的jar包
maven的pom.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--1.引入springboot的父工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bingbaihanji</groupId>
<artifactId>javaFxDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.2</version>
</dependency>
</dependencies>
<build>
<!--修改编译出来的jar包名,仅为{artifactId}.jar-->
<finalName>${project.artifactId}</finalName>
<plugins>
<!--springboot的打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类
加入 @SpringBootApplication 注解和启动函数
@SpringBootApplication
public class Main extends Application {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
······
}
}
然后在当前项目下运行 mvn package
即可在当前目录下生成的target目录中找到可以执行的jar包
jar包大致结构如下
.
├── BOOT-INF
│ ├── classes
│ │ └── com
│ │ └── bingbaihanji
│ │ └── Main.class // 项目启动类
│ ├── classpath.idx
│ ├── layers.idx
│ └── lib // 项目运行所依赖的jar包
├── META-INF
│ ├── MANIFEST.MF // 项目清单文件
│ └── maven
│ └── com.bingbaihanji
│ └── javaFxDemo
│ ├── pom.properties
│ └── pom.xml
├── module-info.class
└── org // springboot框架提供的用来启动jar相关的类
└── springframework
└── boot
└── loader
19 directories, 97 files
MANIFEST.MF 文件结构
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.3.0
Build-Jdk-Spec: 17
Implementation-Title: javaFxDemo
Implementation-Version: 1.0-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.bingbaihanji.Main
Spring-Boot-Version: 3.1.2
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx