diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java index 7412424232..90312adb8f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java @@ -565,7 +565,13 @@ public class HMCLGameInstance extends DefaultGameInstance { return getLayout().getInstanceGameSettingsFile(id); } - public LaunchOptions.Builder getLaunchOptions(JavaRuntime javaVersion, Path gameDir, List javaAgents, List javaArguments, boolean makeLaunchScript) { + public LaunchOptions.Builder getLaunchOptions( + JavaRuntime javaRuntime, + Path javaExecutable, + Path gameDir, + List javaAgents, + List javaArguments, + boolean makeLaunchScript) { GameSettings.Effective vs = getEffectiveSettings(); boolean noJVMOptions = vs.getInheritable(GameSettings::noJVMOptionsProperty); boolean autoMemory = vs.getInheritable(GameSettings::autoMemoryProperty); @@ -577,7 +583,7 @@ public class HMCLGameInstance extends DefaultGameInstance { ? null : Math.toIntExact(HMCLGameRepository.getAutoAllocatedMemory( SystemInfo.getPhysicalMemoryStatus().available(), - javaVersion.getPlatform()) / 1024L / 1024L); + javaRuntime.getPlatform()) / 1024L / 1024L); } else { maxMemory = vs.getMaxMemory(); } @@ -585,7 +591,8 @@ public class HMCLGameInstance extends DefaultGameInstance { LaunchOptions.Builder builder = new LaunchOptions.Builder() .setInstanceId(getId()) .setGameDir(gameDir) - .setJava(javaVersion) + .setJava(javaRuntime) + .setJavaExecutable(javaExecutable) .setVersionType(Metadata.TITLE) .setVersionName(getId().id()) .setProfileName(Metadata.TITLE) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index a1ce26124e..07783eb491 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -57,11 +57,11 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.net.SocketTimeoutException; import java.nio.file.AccessDeniedException; +import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @@ -148,29 +148,46 @@ public final class LauncherHelper { } /// Builds and executes the launch pipeline for the captured game instance. + @SuppressWarnings("NonAtomicOperationOnVolatileField") private void launch0() { // https://github.com/HMCL-dev/HMCL/pull/4121 PROCESSES.removeIf(it -> it.get() == null); + final var context = new Object() { + volatile GameInstanceManifest launchManifest; + volatile JavaRuntime javaRuntime; + volatile Path javaExecutable; + }; + HMCLGameRepository repository = repository(); DefaultDependencyManager dependencyManager = repository.getDependency(); - // Resolve already deduplicated libraries; apply loader-specific argument repairs for this launch. - var launchManifest = new AtomicReference<>(LaunchManifestNormalizer.repairForLaunch(gameInstance.getResolvedManifest())); boolean integrityCheck = gameInstance.unmarkLaunchedAbnormally(); CountDownLatch launchingLatch = new CountDownLatch(1); List javaAgents = new ArrayList<>(0); List javaArguments = new ArrayList<>(0); - AtomicReference javaVersionRef = new AtomicReference<>(); + // Resolve already deduplicated libraries; apply loader-specific argument repairs for this launch. + context.launchManifest = LaunchManifestNormalizer.repairForLaunch(gameInstance.getResolvedManifest()); - TaskExecutor executor = checkGameState(gameInstance, setting, launchManifest.get()) + TaskExecutor executor = checkGameState(gameInstance, setting, context.launchManifest) .thenComposeAsync(java -> { - javaVersionRef.set(Objects.requireNonNull(java)); - launchManifest.set(NativePatcher.patchNative(gameInstance, launchManifest.get(), java, setting, javaArguments)); + context.javaRuntime = Objects.requireNonNull(java); + context.javaExecutable = java.getBinary(); + if (java.getPlatform().os() == OperatingSystem.WINDOWS + && scriptFile == null + && !setting.getInheritable(GameSettings::notUseJavawProperty) + && FileUtils.getName(java.getBinary()).equalsIgnoreCase("java.exe")) { + Path javawBinary = java.getBinary().resolveSibling("javaw.exe"); + if (Files.isRegularFile(javawBinary)) { + context.javaExecutable = javawBinary; + } + } + + context.launchManifest = NativePatcher.patchNative(gameInstance, context.launchManifest, java, setting, javaArguments); if (setting.getInheritable(GameSettings::notCheckGameProperty)) return null; return Task.allOf( - dependencyManager.checkGameCompletionAsync(gameInstance, launchManifest.get(), integrityCheck), + dependencyManager.checkGameCompletionAsync(gameInstance, context.launchManifest, integrityCheck), Task.composeAsync(() -> { try { @Nullable ModpackConfiguration configuration = @@ -203,7 +220,7 @@ public final class LauncherHelper { String agent = FileUtils.getAbsolutePath(file) + "=" + renderer.mesaDriverName(); - if (GameLibrariesTask.shouldDownloadLibrary(repository, launchManifest.get(), lib, integrityCheck)) { + if (GameLibrariesTask.shouldDownloadLibrary(repository, context.launchManifest, lib, integrityCheck)) { return new LibraryDownloadTask(dependencyManager, file, lib) .thenRunAsync(() -> javaAgents.add(agent)); } else { @@ -213,13 +230,13 @@ public final class LauncherHelper { }) ); }).withStage("launch.state.dependencies") - .thenComposeAsync(() -> new GameVerificationFixTask(gameInstance, gameInstance.getVersion(), launchManifest.get())) + .thenComposeAsync(() -> new GameVerificationFixTask(gameInstance, gameInstance.getVersion(), context.launchManifest)) .thenComposeAsync(() -> { if (setting.getInheritable(GameSettings::allowAutoAgentProperty) || setting.getInheritable(GameSettings::noJVMOptionsProperty) || setting.getInheritable(GameSettings::noOptimizingJVMOptionsProperty) || Boolean.TRUE.equals(state().getShownTips().get(LWJGL_3_4_1_TIP)) - || !NativePatcher.needPatchMemoryUtil(launchManifest.get(), javaVersionRef.get().getParsedVersion())) { + || !NativePatcher.needPatchMemoryUtil(context.launchManifest, context.javaRuntime.getParsedVersion())) { return Task.completed(null); } else { CompletableFuture future = new CompletableFuture<>(); @@ -239,7 +256,12 @@ public final class LauncherHelper { .thenComposeAsync(() -> logIn(account).withStage("launch.state.logging_in")) .thenComposeAsync(authInfo -> Task.supplyAsync(() -> { LaunchOptions.Builder launchOptionsBuilder = gameInstance.getLaunchOptions( - javaVersionRef.get(), repository.getBaseDirectory(), javaAgents, javaArguments, scriptFile != null); + context.javaRuntime, + context.javaExecutable, + repository.getBaseDirectory(), + javaAgents, + javaArguments, + scriptFile != null); if (disableOfflineSkin) { launchOptionsBuilder.setDaemon(false); } @@ -248,7 +270,7 @@ public final class LauncherHelper { } if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS && setting.getInheritable(GameSettings::highPerformanceProperty)) { - @Nullable String javaPathGpuReg = FileUtils.getAbsolutePath(javaVersionRef.get().getBinary()); + @Nullable String javaPathGpuReg = FileUtils.getAbsolutePath(context.javaExecutable); try { WinReg reg = WinReg.INSTANCE; if (reg != null) { @@ -283,7 +305,7 @@ public final class LauncherHelper { return new HMCLGameLauncher( gameInstance, - launchManifest.get(), + context.launchManifest, authInfo, launchOptions, launcherVisibility == LauncherVisibility.CLOSE diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/GameSettings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/GameSettings.java index 799afe2f3b..c20246d7be 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/GameSettings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/GameSettings.java @@ -388,6 +388,19 @@ public sealed abstract class GameSettings extends ObservableSetting { return detectedJava; } + /// Property name for disabling automatic replacement with `javaw.exe` on Windows. + public static final String PROPERTY_NOT_USE_JAVAW = "notUseJavaw"; + + /// Whether to keep the selected Java executable instead of replacing it with `javaw.exe`; defaults to `false`. + @SerializedName(PROPERTY_NOT_USE_JAVAW) + private final InheritableProperty notUseJavaw = newInheritableProperty(PROPERTY_NOT_USE_JAVAW, false); + + /// Returns the property disabling automatic replacement of a Windows Java executable with a sibling `javaw.exe` file. + /// If `true`, the selected executable is used unchanged. This property has no effect on other runtime platforms. + public InheritableProperty notUseJavawProperty() { + return notUseJavaw; + } + /// Property name for customized JVM options. public static final String PROPERTY_JVM_OPTIONS = "jvmOptions"; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/GameSettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/GameSettingsPage.java index b5592d7089..c535467a9f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/GameSettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/GameSettingsPage.java @@ -643,6 +643,11 @@ public final class GameSettingsPage extends StackPane jvmSettings ); { + var notUseJavawPane = createInheritableBooleanButton(GameSettings::notUseJavawProperty); + jvmSettings.getContent().add(notUseJavawPane); + notUseJavawPane.setTitle(i18n("settings.advanced.not_use_javaw")); + notUseJavawPane.setSubtitle(i18n("settings.advanced.windows_only")); + var noJVMArgsPane = createInheritableBooleanButton(GameSettings::noJVMOptionsProperty); jvmSettings.getContent().add(noJVMArgsPane); noJVMArgsPane.setTitle(i18n("settings.advanced.no_jvm_args")); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index d7deb3b77d..320864f6c6 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -1433,6 +1433,7 @@ settings.advanced.natives_directory=Native Library Path settings.advanced.natives_directory.custom.enabled=Use Custom Native Libraries settings.advanced.no_jvm_args=Do not add default JVM arguments settings.advanced.no_optimizing_jvm_args=Do not add default JVM optimization arguments +settings.advanced.not_use_javaw=Do not use javaw.exe settings.advanced.precall_command=Pre-launch Command settings.advanced.precall_command.prompt=Commands to execute before the game launches settings.advanced.process_priority=Process Priority diff --git a/HMCL/src/main/resources/assets/lang/I18N_ar.properties b/HMCL/src/main/resources/assets/lang/I18N_ar.properties index c20716521c..78b9afb941 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ar.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ar.properties @@ -176,6 +176,7 @@ addon.check_update.empty=جميع المودات محدّثة addon.check_update.failed_check=فشل التحقق من التحديثات. addon.check_update.failed_download=فشل تنزيل بعض الملفات. addon.check_update.file=الملف +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=المصدر addon.check_update.target_version=الإصدار المستهدف @@ -1432,6 +1433,7 @@ settings.advanced.natives_directory=مسار المكتبات الأصلية # settings.advanced.natives_directory.custom.enabled= settings.advanced.no_jvm_args=عدم إضافة وسيطات JVM الافتراضية settings.advanced.no_optimizing_jvm_args=عدم إضافة وسيطات تحسين JVM الافتراضية +# settings.advanced.not_use_javaw= settings.advanced.precall_command=أمر ما قبل التشغيل settings.advanced.precall_command.prompt=أوامر تُنفَّذ قبل تشغيل اللعبة settings.advanced.process_priority=أولوية العملية diff --git a/HMCL/src/main/resources/assets/lang/I18N_de.properties b/HMCL/src/main/resources/assets/lang/I18N_de.properties index 3e723ae408..9aa2fe9dd1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_de.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_de.properties @@ -174,6 +174,7 @@ addon.check_update.empty=Alle Dateien sind auf dem neuesten Stand addon.check_update.failed_check=Fehler beim Suchen nach Aktualisierungen. addon.check_update.failed_download=Fehler beim Herunterladen einiger Dateien. addon.check_update.file=Datei +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=Quelle addon.check_update.target_version=Zielversion @@ -1431,6 +1432,7 @@ settings.advanced.natives_directory=Pfad der nativen Bibliotheken settings.advanced.natives_directory.custom.enabled=Benutzerdefinierte native Bibliotheken verwenden settings.advanced.no_jvm_args=Standard-JVM-Argumente nicht hinzufügen settings.advanced.no_optimizing_jvm_args=Standard-JVM-Optimierungsargumente nicht hinzufügen +# settings.advanced.not_use_javaw= settings.advanced.precall_command=Pre-Launch-Befehl settings.advanced.precall_command.prompt=Befehle, die vor dem Spielstart ausgeführt werden sollen settings.advanced.process_priority=Prozesspriorität diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 778ee2d686..2a6c5374a1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -174,6 +174,7 @@ addon.check_update.empty=Todos los mods están actualizados addon.check_update.failed_check=No se ha podido comprobar si hay actualizaciones. addon.check_update.failed_download=No se han podido descargar algunos de los archivos. addon.check_update.file=Archivo +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=Fuente addon.check_update.target_version=Versión de destino @@ -1424,6 +1425,7 @@ settings.advanced.natives_directory=Ruta de la biblioteca nativa # settings.advanced.natives_directory.custom.enabled= settings.advanced.no_jvm_args=No añadir argumentos JVM por defecto settings.advanced.no_optimizing_jvm_args=No añadir argumentos de optimización de JVM +# settings.advanced.not_use_javaw= settings.advanced.precall_command=Comando pre-lanzamiento: settings.advanced.precall_command.prompt=El comando se ejecuta antes de que los juegos se lance settings.advanced.process_priority=Prioridad del proceso diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index 819101c5c0..3c474168e9 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -163,6 +163,7 @@ addon.check_update.current_version=Current addon.check_update.failed_check=更新のチェックに失敗しました addon.check_update.failed_download=一部のファイルのダウンロードに失敗しました addon.check_update.file=ファイル +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=Source addon.check_update.target_version=Target @@ -1228,6 +1229,7 @@ settings.advanced.natives_directory=ネイティブライブラリパス(例 # settings.advanced.natives_directory.custom.enabled= settings.advanced.no_jvm_args=デフォルトのJVM引数なし # settings.advanced.no_optimizing_jvm_args= +# settings.advanced.not_use_javaw= settings.advanced.precall_command=起動前コマンド settings.advanced.precall_command.prompt=ゲーム開始前に実行されます settings.advanced.process_priority=プロセスの優先度 diff --git a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties index e5ea348632..0bbd74c61a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties @@ -174,6 +174,7 @@ addon.check_update.empty=無改囊可迭更 addon.check_update.failed_check=檢囊迭更未成 addon.check_update.failed_download=有引案未成 addon.check_update.file=案 +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=源 addon.check_update.target_version=將至之版 @@ -1240,6 +1241,7 @@ settings.advanced.natives_directory=府庫之徑 (LWJGL) # settings.advanced.natives_directory.custom.enabled= settings.advanced.no_jvm_args=無添爪哇虛機之本通弦 # settings.advanced.no_optimizing_jvm_args= +# settings.advanced.not_use_javaw= settings.advanced.precall_command=令於戲前 settings.advanced.precall_command.prompt=將前戲啟而行 settings.advanced.process_priority=進程之次 diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 742132bd1c..531a8304a3 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -170,6 +170,7 @@ addon.check_update.empty=Все файлы актуальны addon.check_update.failed_check=Не удалось проверить обновления. addon.check_update.failed_download=Не удалось скачать некоторые файлы. addon.check_update.file=Файл +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=Источник addon.check_update.target_version=Целевая версия @@ -1364,6 +1365,7 @@ settings.advanced.natives_directory=Папка с нативными библи settings.advanced.natives_directory.custom.enabled=Использовать свои нативные библиотеки settings.advanced.no_jvm_args=Не добавлять аргументы JVM по умолчанию settings.advanced.no_optimizing_jvm_args=Не добавлять аргументы оптимизации JVM по умолчанию +# settings.advanced.not_use_javaw= settings.advanced.precall_command=Команда перед запуском settings.advanced.precall_command.prompt=Команды, которые необходимо выполнить перед запуском игры settings.advanced.process_priority=Приоритет процесса diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index dccfc124f5..70a6e5d123 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -176,6 +176,7 @@ addon.check_update.empty=Усі моди оновлені addon.check_update.failed_check=Не вдалося перевірити оновлення. addon.check_update.failed_download=Не вдалося завантажити деякі файли. addon.check_update.file=Файл +# addon.check_update.only_preview= # addon.check_update.preview= addon.check_update.source=Джерело addon.check_update.target_version=Цільова версія @@ -1387,6 +1388,7 @@ settings.advanced.natives_directory=Шлях до нативних бібліо settings.advanced.natives_directory.custom.enabled=Використовувати власні нативні бібліотеки settings.advanced.no_jvm_args=Не додавати типові аргументи JVM settings.advanced.no_optimizing_jvm_args=Не додавати типові аргументи оптимізації JVM +# settings.advanced.not_use_javaw= settings.advanced.precall_command=Команда перед запуском settings.advanced.precall_command.prompt=Команди для виконання перед запуском гри settings.advanced.process_priority=Пріоритет процесу diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties index eca65ed69c..d9a4c480fa 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties @@ -1245,6 +1245,7 @@ settings.advanced.natives_directory=本地库路径 (LWJGL) settings.advanced.natives_directory.custom.enabled=使用自定义本地库 settings.advanced.no_jvm_args=不添加默认的 Java 虚拟机参数 settings.advanced.no_optimizing_jvm_args=不自动添加 Java 虚拟机优化参数 +settings.advanced.not_use_javaw=不使用 javaw.exe settings.advanced.precall_command=游戏启动前执行命令 settings.advanced.precall_command.prompt=将在游戏启动前调用 settings.advanced.process_priority=进程优先级 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties index d3dbb11162..0c671b697c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties @@ -1239,6 +1239,7 @@ settings.advanced.natives_directory=本機庫路徑 (LWJGL) settings.advanced.natives_directory.custom.enabled=使用自訂本機庫 settings.advanced.no_jvm_args=不新增預設的 Java 虛擬機參數 settings.advanced.no_optimizing_jvm_args=不自動新增 Java 虛擬機最佳化參數 +settings.advanced.not_use_javaw=不使用 javaw.exe settings.advanced.precall_command=遊戲啟動前執行指令 settings.advanced.precall_command.prompt=將在遊戲啟動前呼叫使用 settings.advanced.process_priority=處理程式優先度 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java index 5ef1ad40ec..cc796534d3 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java @@ -33,6 +33,7 @@ public class LaunchOptions implements Serializable { private GameInstanceID instanceId; private Path gameDir; private JavaRuntime java; + private Path javaExecutable; private String versionName; private String versionType; private String profileName; @@ -85,6 +86,16 @@ public class LaunchOptions implements Serializable { return java; } + /// Returns the executable selected for launch, falling back to [JavaRuntime#getBinary()] if none is specified. + /// The path is used without automatic executable substitution or file validation. + public Path getJavaExecutable() { + if (javaExecutable != null) + return javaExecutable; + if (java != null) + return java.getBinary(); + return null; + } + /** * Will shown in the left bottom corner of the main menu of Minecraft. * null if use the id of launch version. @@ -336,6 +347,11 @@ public class LaunchOptions implements Serializable { return this; } + public Builder setJavaExecutable(Path javaExecutable) { + options.javaExecutable = javaExecutable; + return this; + } + public Builder setVersionName(String versionName) { options.versionName = versionName; return this; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java index 86d358044a..a9e3d2ce21 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -98,7 +98,7 @@ public class DefaultLauncher extends Launcher { if (StringUtils.isNotBlank(options.getWrapper())) res.addAllWithoutParsing(StringUtils.tokenize(options.getWrapper(), getEnvVars(nativeFolder))); - res.add(options.getJava().getBinary().toString()); + res.add(options.getJavaExecutable().toString()); res.addAllWithoutParsingAndReadExternal(options.getOverrideJavaArguments());