8254920: Application launched with jpackage produced .exe crashes JVM

Reviewed-by: asemenyuk, almatvee, kizune
This commit is contained in:
Andy Herrick 2020-11-06 16:14:36 +00:00
parent 5dfb42fc68
commit 952abea47b
4 changed files with 115 additions and 5 deletions

View File

@ -137,6 +137,8 @@ void launchApp() {
const tstring launcherPath = SysInfo::getProcessModulePath();
const tstring appImageRoot = FileUtils::dirname(launcherPath);
const tstring runtimeBinPath = FileUtils::mkpath()
<< appImageRoot << _T("runtime") << _T("bin");
std::unique_ptr<Jvm> jvm(AppLauncher()
.setImageRoot(appImageRoot)
@ -146,6 +148,10 @@ void launchApp() {
<< _T("runtime"))
.createJvmLauncher());
// zip.dll may be loaded by java without full path
// make sure it will look in runtime/bin
SetDllDirectory(runtimeBinPath.c_str());
const DllWrapper jliDll(jvm->getPath());
std::unique_ptr<DllWrapper> splashDll;
if (jvm->isWithSplash()) {

View File

@ -52,6 +52,7 @@ public final class Executor extends CommandArguments<Executor> {
public Executor() {
saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE));
removePath = false;
}
public Executor setExecutable(String v) {
@ -83,6 +84,11 @@ public final class Executor extends CommandArguments<Executor> {
return setExecutable(v.getPath());
}
public Executor setRemovePath(boolean value) {
removePath = value;
return this;
}
/**
* Configures this instance to save full output that command will produce.
* This function is mutual exclusive with
@ -289,6 +295,11 @@ public final class Executor extends CommandArguments<Executor> {
builder.directory(directory.toFile());
sb.append(String.format("; in directory [%s]", directory));
}
if (removePath) {
// run this with cleared Path in Environment
TKit.trace("Clearing PATH in environment");
builder.environment().remove("PATH");
}
trace("Execute " + sb.toString() + "...");
Process process = builder.start();
@ -414,6 +425,7 @@ public final class Executor extends CommandArguments<Executor> {
private Path executable;
private Set<SaveOutputType> saveOutputType;
private Path directory;
private boolean removePath;
private static enum SaveOutputType {
NONE, FULL, FIRST_LINE, DUMP

View File

@ -273,14 +273,15 @@ public final class HelloApp {
String... args) {
AppOutputVerifier av = getVerifier(cmd, args);
if (av != null) {
av.executeAndVerifyOutput(args);
// when running app launchers, clear users environment
av.executeAndVerifyOutput(true, args);
}
}
public static Executor.Result executeLauncher(JPackageCommand cmd,
String... args) {
AppOutputVerifier av = getVerifier(cmd, args);
return av.executeOnly(args);
return av.executeOnly(true, args);
}
private static AppOutputVerifier getVerifier(JPackageCommand cmd,
@ -351,7 +352,11 @@ public final class HelloApp {
}
public void executeAndVerifyOutput(String... args) {
getExecutor(args).dumpOutput().execute();
executeAndVerifyOutput(false, args);
}
public void executeAndVerifyOutput(boolean removePath, String... args) {
getExecutor(args).dumpOutput().setRemovePath(removePath).execute();
final List<String> launcherArgs = List.of(args);
final List<String> appArgs;
@ -365,8 +370,11 @@ public final class HelloApp {
verifyOutputFile(outputFile, appArgs, params);
}
public Executor.Result executeOnly(String...args) {
return getExecutor(args).saveOutput().executeWithoutExitCodeCheck();
public Executor.Result executeOnly(boolean removePath, String...args) {
return getExecutor(args)
.saveOutput()
.setRemovePath(removePath)
.executeWithoutExitCodeCheck();
}
private Executor getExecutor(String...args) {

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.jpackage.test.TKit;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.PackageType;
import jdk.jpackage.test.Functional;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.JavaTool;
import jdk.jpackage.test.Executor;
/*
* @test
* @summary jpackage with --runtime-image
* @library ../helpers
* @key jpackagePlatformPackage
* @build jdk.jpackage.test.*
* @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
* @compile RuntimeImageTest.java
* @run main/othervm/timeout=1400 -Xmx512m jdk.jpackage.test.Main
* --jpt-run=RuntimeImageTest
*/
public class RuntimeImageTest {
@Test
@Parameter("0")
@Parameter("1")
@Parameter("2")
public static void test(String compression) throws Exception {
final Path workDir = TKit.createTempDirectory("runtime").resolve("data");
final Path jlinkOutputDir = workDir.resolve("temp.runtime");
Files.createDirectories(jlinkOutputDir.getParent());
new Executor()
.setToolProvider(JavaTool.JLINK)
.dumpOutput()
.addArguments(
"--output", jlinkOutputDir.toString(),
"--compress=" + compression,
"--add-modules", "ALL-MODULE-PATH",
"--strip-debug",
"--no-header-files",
"--no-man-pages",
"--strip-native-commands")
.execute();
JPackageCommand cmd = JPackageCommand.helloAppImage()
.setArgumentValue("--runtime-image", jlinkOutputDir.toString());
cmd.executeAndAssertHelloAppImageCreated();
}
}