E5EB Use the system encoding to generate the *.argfile by testforstephen · Pull Request #458 · microsoft/java-debug · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018-2021 Microsoft Corporation and others.
* Copyright (c) 2018-2022 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -16,6 +16,7 @@
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
Expand Down Expand Up @@ -134,11 +135,50 @@ protected CompletableFuture<Response> handleLaunchCommand(Arguments arguments, R
}
} else if (launchArguments.shortenCommandLine == ShortenApproach.ARGFILE) {
try {
Path tempfile = LaunchUtils.generateArgfile(launchArguments.vmArgs, launchArguments.classPaths, launchArguments.modulePaths);
launchArguments.vmArgs = " \"@" + tempfile.toAbsolutePath().toString() + "\"";
launchArguments.classPaths = new String[0];
launchArguments.modulePaths = new String[0];
context.setArgsfile(tempfile);
/**
* See the JDK spec https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html#java-command-line-argument-files.
* The argument file must contain only ASCII characters or characters in system default encoding that's ASCII friendly.
*/
Charset systemCharset = LaunchUtils.getSystemCharset();
CharsetEncoder encoder = systemCharset.newEncoder();
String vmArgsForShorten = null;
String[] classPathsForShorten = null;
String[] modulePathsForShorten = null;
if (StringUtils.isNotBlank(launchArguments.vmArgs)) {
if (!encoder.canEncode(launchArguments.vmArgs)) {
logger.warning(String.format("Cannot generate the 'vmArgs' argument into the argfile because it contains characters "
+ "that cannot be encoded in the system charset '%s'.", systemCharset.displayName()));
} else {
vmArgsForShorten = launchArguments.vmArgs;
}
}

if (ArrayUtils.isNotEmpty(launchArguments.classPaths)) {
if (!encoder.canEncode(String.join(File.pathSeparator, launchArguments.classPaths))) {
logger.warning(String.format("Cannot generate the '-cp' argument into the argfile because it contains characters "
+ "that cannot be encoded in the system charset '%s'.", systemCharset.displayName()));
} else {
classPathsForShorten = launchArguments.classPaths;
}
}

if (ArrayUtils.isNotEmpty(launchArguments.modulePaths)) {
if (!encoder.canEncode(String.join(File.pathSeparator, launchArguments.modulePaths))) {
logger.warning(String.format("Cannot generate the '--module-path' argument into the argfile because it contains characters "
+ "that cannot be encoded in the system charset '%s'.", systemCharset.displayName()));
} else {
modulePathsForShorten = launchArguments.modulePaths;
}
}

if (vmArgsForShorten != null || classPathsForShorten != null || modulePathsForShorten != null) {
Path tempfile = LaunchUtils.generateArgfile(vmArgsForShorten, classPathsForShorten, modulePathsForShorten, systemCharset);
launchArguments.vmArgs = (vmArgsForShorten == null ? launchArguments.vmArgs : "")
+ " \"@" + tempfile.toAbsolutePath().toString() + "\"";
launchArguments.classPaths = (classPathsForShorten == null ? launchArguments.classPaths : new String[0]);
launchArguments.modulePaths = (modulePathsForShorten == null ? launchArguments.modulePaths : new String[0]);
context.setArgsfile(tempfile);
}
} catch (IOException e) {
logger.log(Level.SEVERE, String.format("Failed to create a temp argfile: %s", e.toString()), e);
}
Expand Down
4555
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -36,16 +37,45 @@
import java.util.logging.Logger;
import java.util.stream.Collectors;

import com.microsoft.java.debug.core.Configuration;
import com.microsoft.java.debug.core.adapter.AdapterUtils;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;

import com.microsoft.java.debug.core.Configuration;
import com.microsoft.java.debug.core.adapter.AdapterUtils;

public class LaunchUtils {
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
private static Set<Path> tempFilesInUse = new HashSet<>();
private static final Charset SYSTEM_CHARSET;

static {
Charset result = null;
try {
// JEP 400: Java 17+ populates this system property.
String encoding = System.getProperty("native.encoding"); //$NON-NLS-1$
if (encoding != null && !encoding.isBlank()) {
result = Charset.forName(encoding);
} else {
// JVM internal property, works on older JVM's too
encoding = System.getProperty("sun.jnu.encoding"); //$NON-NLS-1$
if (encoding != null && !encoding.isBlank()) {
result = Charset.forName(encoding);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Error occurs during resolving system encoding", e);
}
if (result == null) {
// This is always UTF-8 on Java >= 18.
result = Charset.defaultCharset();
}
SYSTEM_CHARSET = result;
}

public static Charset getSystemCharset() {
return SYSTEM_CHARSET;
}

/**
* Generate the classpath parameters to a temporary classpath.jar.
Expand Down Expand Up @@ -82,7 +112,7 @@ public static synchronized Path generateClasspathJar(String[] classPaths) throws
* @return the file path of the generated argfile
* @throws IOException Some errors occur during generating the argfile
*/
public static synchronized Path generateArgfile(String vmArgs, String[] classPaths, String[] modulePaths) throws IOException {
public static synchronized Path generateArgfile(String vmArgs, String[] classPaths, String[] modulePaths, Charset encoding) throws IOException {
String argfile = "";
if (StringUtils.isNotBlank(vmArgs)) {
argfile += vmArgs;
Expand All @@ -100,7 +130,7 @@ public static synchronized Path generateArgfile(String vmArgs, String[] classPat
String baseName = "cp_" + getMd5(argfile);
cleanupTempFiles(baseName, ".argfile");
Path tempfile = createTempFile(baseName, ".argfile");
Files.write(tempfile, argfile.getBytes());
Files.writeString(tempfile, argfile, encoding);
lockTempLaunchFile(tempfile);

return tempfile;
Expand Down
0