我在 Eclipse IDE 中用 Javafx 和 scenebuilder 编写了一个简单的计算器程序。 它运行良好。我还可以通过 Launch4J 创建 .JAR 文件。这个 jar 也在命令 promt 中运行,并带有我在 run as->argument 部分中使用的 JVM 参数 --module-path "C:\Program Files\Java\openjfx-22.0.2_windows-x64_bin-sdk\javafx-sdk-22.0.2\lib" --add-modules javafx.controls,javafx.fxml 但是当我在 Launch4j 中创建 .exe 时,该 .exe 文件不起作用。
我尝试将整个 jdk 文件夹、jre 文件夹、javafx 文件夹保留在我的应用程序创建文件夹中。
我的程序文件下的文件夹为 PROGRAM FILES->JAVA->JDK-1.8、JDK-22、JDK-22.0.2、JRE1.8.0_421、javafx-sdk-22.0.2。
(我在program files->java->openjfx-22.0._2_windows-x64_bin-sdk->javafx-sdk-22.0.2下有javafx文件夹)
Stil.exe 无法工作
demofxapp
├── pom.xml
└── src
└── main
├── java
│ ├── com
│ │ └── example
│ │ └── demofxapp
│ │ ├── App.java
│ │ ├── PrimaryController.java
│ │ └── SecondaryController.java
│ └── module-info.java
├── launch4j
│ ├── DemoApp_LocalDir.xml
│ └── logo.ico
└── resources
├── com
│ └── example
│ └── demofxapp
│ ├── primary.fxml
│ └── secondary.fxml
└── log4j2.xml
module com.example.demofxapp {
requires javafx.controls;
requires javafx.fxml;
requires org.apache.logging.log4j;
opens com.example.demofxapp to javafx.fxml;
exports com.example.demofxapp;
}
更改:仅添加 log4j 功能。
package com.example.demofxapp;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
/**
* JavaFX App
*/
public class App extends Application {
private static final Logger logger = LogManager.getLogger(App.class);
private static Scene scene;
static void setRoot(String fxml) throws IOException {
logger.info("setRoot");
scene.setRoot(loadFXML(fxml));
}
private static Parent loadFXML(String fxml) throws IOException {
logger.info("loadFXML");
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
public static void main(String[] args) {
logger.info("launch");
launch();
}
@Override
public void start(Stage stage) throws IOException {
logger.info("start");
scene = new Scene(loadFXML("primary"), 640, 480);
stage.setScene(scene);
stage.setTitle("DemoApp");
stage.show();
}
}
更改:仅添加 log4j 功能。
package com.example.demofxapp;
import javafx.fxml.FXML;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
public class PrimaryController {
private static final Logger logger = LogManager.getLogger(PrimaryController.class);
@FXML
private void switchToSecondary() throws IOException {
logger.info("switchToSecondary");
App.setRoot("secondary");
}
}
package com.example.demofxapp;
import javafx.fxml.FXML;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
public class SecondaryController {
private static final Logger logger = LogManager.getLogger(SecondaryController.class);
@FXML
private void switchToPrimary() throws IOException {
logger.info("switchToPrimary");
App.setRoot("primary");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demofxapp.PrimaryController">
<children>
<Label text="Primary View" />
<Button fx:id="primaryButton" text="Switch to Secondary View" onAction="#switchToSecondary"/>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demofxapp.SecondaryController">
<children>
<Label text="Secondary View" />
<Button fx:id="secondaryButton" text="Switch to Primary View" onAction="#switchToPrimary" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<!-- Console Appender Configuration -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</Console>
<!-- File Appender Configuration -->
<File name="File" fileName="logs/app.log" append="true">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</File>
</Appenders>
<Loggers>
<!-- Root Logger Configuration -->
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>
<!-- Application Specific Logger Configuration -->
<Logger name="com.example" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Logger>
</Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<launch4jConfig>
<dontWrapJar>false</dontWrapJar>
<headerType>gui</headerType>
<jar>demofxapp.jar</jar>
<outfile>demofxapp.exe</outfile>
<errTitle>Demo FX App</errTitle>
<cmdLine></cmdLine>
<chdir>.</chdir>
<priority>normal</priority>
<downloadUrl></downloadUrl>
<supportUrl></supportUrl>
<stayAlive>true</stayAlive>
<restartOnCrash>false</restartOnCrash>
<manifest></manifest>
<icon>logo.ico</icon>
<jre>
<path>jre</path>
<requiresJdk>false</requiresJdk>
<requires64Bit>true</requires64Bit>
<minVersion></minVersion>
<maxVersion></maxVersion>
<opt>-Dlog4j.configurationFile=conf/log4j2.xml</opt>
</jre>
</launch4jConfig>
您可以使用您的图标文件。
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>com.example</groupId>
<artifactId>demofxapp</artifactId>
<name>demofxapp</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>21</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>21</version>
</dependency>
<!-- Log4j2 core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.23.1</version>
</dependency>
<!-- Log4j2 API -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.23.1</version>
</dependency>
</dependencies>
<build>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs\</classpathPrefix>
<mainClass>
com.example.demofxapp.App
</mainClass>
</manifest>
<manifestEntries>
<Class-Path>conf/log4j2.xml</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<outputDirectory>${project.build.directory}\libs</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- `mvn clean package exec:exec@jlink-build-jre` -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>jlink-build-jre</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>jlink</executable>
<arguments>
<argument>--strip-debug</argument>
<argument>--no-man-pages</argument>
<argument>--no-header-files</argument>
<argument>--compress=2</argument>
<argument>--module-path</argument>
<argument>${project.build.directory}/libs</argument>
<argument>--add-modules</argument>
<argument>
java.base,javafx.fxml,javafx.graphics,javafx.controls,org.apache.logging.log4j,org.apache.logging.log4j.core
</argument>
<argument>--output</argument>
<argument>${project.build.directory}/dist/app/jre</argument>
</arguments>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
</execution>
<!-- `mvn exec:exec@launch4j-build-app-exe` -->
<execution>
<id>launch4j-build-app-exe</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>"C:\Program Files (x86)\Launch4j\launch4jc.exe"</executable>
<arguments>
<argument>${project.build.directory}\dist\app\DemoApp_LocalDir.xml</argument>
</arguments>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>com.example.demofxapp.App</mainClass>
</configuration>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
</execution>
<execution>
<!-- Configuration for manual attach debugging -->
<!-- Usage: mvn clean javafx:run@debug -->
<id>debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000
</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE debugging -->
<id>ide-debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE profiling -->
<id>ide-profile</id>
<configuration>
<options>
<option>${profiler.jvmargs.arg1}</option>
<option>${profiler.jvmargs.arg2}</option>
<option>${profiler.jvmargs.arg3}</option>
<option>${profiler.jvmargs.arg4}</option>
<option>${profiler.jvmargs.arg5}</option>
</options>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
<executions>
<!-- Run Command
`mvn resources:copy-resources@prepare-launch4j-resources`
-->
<!-- copy-resources , after jlink-build-app-jre-->
<execution>
<id>prepare-launch4j-resources</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dist/app</outputDirectory>
<resources>
<resource>
<directory>src/main/launch4j</directory>
<includes>
<include>logo.ico</include>
<include>DemoApp_LocalDir.xml</include>
</includes>
</resource>
<resource>
<directory>${project.build.directory}</directory>
<includes>
<include>demofxapp.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<!-- Run Command
`mvn resources:copy-resources@prepare-launch4j-resources-conf`
-->
<!-- copy-resources , after jlink-build-app-jre -->
<execution>
<id>prepare-launch4j-resources-conf</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dist/app/conf</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>log4j2.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
mvn clean package
你可以找到输出:
demofxapp.jar
libs
包含依赖jartarget
├── demofxapp.jar
└── libs
├── javafx-base-21.jar
├── javafx-base-21-linux.jar
├── javafx-base-21-win.jar
├── javafx-controls-21.jar
├── javafx-controls-21-linux.jar
├── javafx-controls-21-win.jar
├── javafx-fxml-21.jar
├── javafx-fxml-21-linux.jar
├── javafx-fxml-21-win.jar
├── javafx-graphics-21.jar
├── javafx-graphics-21-linux.jar
├── javafx-graphics-21-win.jar
├── log4j-api-2.23.1.jar
└── log4j-core-2.23.1.jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs\</classpathPrefix>
<mainClass>
com.example.demofxapp.App
</mainClass>
</manifest>
<manifestEntries>
<Class-Path>conf/log4j2.xml</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
下载依赖jar到
target/libs
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<outputDirectory>${project.build.directory}\libs</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
mvn exec:exec@jlink-build-jre
创建文件夹
target/dist/app/jre
target
└── dist
└── app
└── jre (85 MB)
与命令行相同:
jlink ^
--module-path target\libs ^
--add-modules java.base,javafx.fxml,javafx.graphics,javafx.controls,org.apache.logging.log4j,org.apache.logging.log4j.core ^
--strip-debug ^
--no-man-pages ^
--no-header-files ^
--compress=2 ^
--output target\dist\app\jre
注意:在 Windows 中,命令行指令的换行符是
^
。此表示法可用于将长指令分成多行。
使用 exec-maven-plugin 做同样的事情。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!-- `mvn clean package exec:exec@jlink-build-jre` -->
<execution>
<id>jlink-build-jre</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>jlink</executable>
<arguments>
<argument>--strip-debug</argument>
<argument>--no-man-pages</argument>
<argument>--no-header-files</argument>
<argument>--compress=2</argument>
<argument>--module-path</argument>
<argument>${project.build.directory}/libs</argument>
<argument>--add-modules</argument>
<argument> java.base,javafx.fxml,javafx.graphics,javafx.controls,org.apache.logging.log4j,org.apache.logging.log4j.core
</argument>
<argument>--output</argument>
<argument>${project.build.directory}/dist/app/jre</argument>
</arguments>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
</execution>
mvn ^
resources:copy-resources@prepare-launch4j-resources ^
resources:copy-resources@prepare-launch4j-resources-conf
获取输出
target/dist/app
├── DemoApp_LocalDir.xml (*Launch4j)
├── logo.ico (*Launch4j)
├── demofxapp.jar
├── conf
│ └── log4j2.xml
└── jre
mvn exec:exec@launch4j-build-app-exe
获取输出:demofxapp.exe
target/dist/app
├── DemoApp_LocalDir.xml (*Launch4j)
├── logo.ico (*Launch4j)
├── demofxapp.jar
├── demofxapp.exe
├── conf
│ └── log4j2.xml
└── jre
相同的终端命令:
"C:\Program Files (x86)\Launch4j\launch4jc.exe" C:\Users\IEUser\Documents\demofxapp\target\dist\app\DemoApp_LocalDir.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!-- `mvn exec:exec@launch4j-build-app-exe` -->
<execution>
<id>launch4j-build-app-exe</id>
<!-- <phase>package</phase> -->
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>"C:\Program Files (x86)\Launch4j\launch4jc.exe"</executable>
<arguments>
<argument>${project.build.directory}\dist\app\DemoApp_LocalDir.xml</argument>
</arguments>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
</execution>
请删除这些文件。
target/dist/app
├── DemoApp_LocalDir.xml (*DELETE)
├── logo.ico (*DELETE)
├── demofxapp.jar (*DELETE)
app
├── demofxapp.exe
├── conf
│ └── log4j2.xml
└── jre
现在您可以将整个app目录复制到其他无需安装JDK或JRE的环境中执行。
app
到C:\TOOLS
jre
模块java --list-modules
JDK、JavaFX、Log4j
结果:
C:\Users\IEUser>cd C:\TOOLS\app\jre\bin
C:\TOOLS\app\jre\bin>java --list-modules
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
javafx.base@21
javafx.controls@21
javafx.fxml@21
javafx.graphics@21
[email protected]
[email protected]
[email protected]
运行exe
检查日志文件
您可以修改
conf\log4j2.xml
来更改日志格式。