diff options
9 files changed, 54 insertions, 17 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java index 8de7ba6c1d..171d80c3da 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java @@ -19,7 +19,6 @@ import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; @@ -182,7 +181,7 @@ public class FSTest { FS.readPipe(fs.userHome(), new String[] { "/bin/sh", "-c", "exit 1" }, - Charset.defaultCharset().name()); + SystemReader.getInstance().getDefaultCharset().name()); } @Test(expected = CommandFailedException.class) @@ -192,7 +191,7 @@ public class FSTest { FS.readPipe(fs.userHome(), new String[] { "this-command-does-not-exist" }, - Charset.defaultCharset().name()); + SystemReader.getInstance().getDefaultCharset().name()); } @Test diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 3acceab098..74762a9021 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -440,6 +440,7 @@ lockOnNotHeld=Lock on {0} not held. lockStreamClosed=Output to lock on {0} already closed lockStreamMultiple=Output to lock on {0} already opened logInconsistentFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: {} > {}, but diff = {}. Aborting measurement at resolution {}. +logInvalidDefaultCharset=System property "native.encoding" specifies unknown character set: {} logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement. logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}. logXDGConfigHomeInvalid=Environment variable XDG_CONFIG_HOME contains an invalid path {} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java index ce3ad2239a..dbfd415943 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java @@ -12,13 +12,13 @@ package org.eclipse.jgit.hooks; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.nio.charset.Charset; import java.util.concurrent.Callable; import org.eclipse.jgit.api.errors.AbortedByHookException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.ProcessResult; +import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.TeeOutputStream; /** @@ -171,7 +171,8 @@ public abstract class GitHook<T> implements Callable<T> { getStdinArgs()); if (result.isExecutedWithError()) { handleError(new String(errorByteArray.toByteArray(), - Charset.defaultCharset().name()), result); + SystemReader.getInstance().getDefaultCharset().name()), + result); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 76340dabb3..3d5d0607e7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -468,6 +468,7 @@ public class JGitText extends TranslationBundle { /***/ public String lockStreamClosed; /***/ public String lockStreamMultiple; /***/ public String logInconsistentFiletimeDiff; + /***/ public String logInvalidDefaultCharset; /***/ public String logLargerFiletimeDiff; /***/ public String logSmallerFiletime; /***/ public String logXDGConfigHomeInvalid; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 31a05933c8..dd656e5f2b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -23,7 +23,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import java.nio.charset.Charset; import java.nio.file.AccessDeniedException; import java.nio.file.FileStore; import java.nio.file.Files; @@ -1507,7 +1506,7 @@ public abstract class FS { try { v = readPipe(gitExe.getParentFile(), new String[] { gitExe.getPath(), "--version" }, //$NON-NLS-1$ - Charset.defaultCharset().name()); + SystemReader.getInstance().getDefaultCharset().name()); } catch (CommandFailedException e) { LOG.warn(e.getMessage()); return null; @@ -1527,7 +1526,7 @@ public abstract class FS { w = readPipe(gitExe.getParentFile(), new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$ "--edit" }, //$NON-NLS-1$ - Charset.defaultCharset().name(), env); + SystemReader.getInstance().getDefaultCharset().name(), env); } catch (CommandFailedException e) { LOG.warn(e.getMessage()); return null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index 946d81c73a..1c113617f8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -17,7 +17,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; -import java.nio.charset.Charset; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileStore; import java.nio.file.FileSystemException; @@ -119,8 +118,8 @@ public class FS_POSIX extends FS { new String[] { "sh", "-c", "umask" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ null, null); try (BufferedReader lineRead = new BufferedReader( - new InputStreamReader(p.getInputStream(), Charset - .defaultCharset().name()))) { + new InputStreamReader(p.getInputStream(), SystemReader + .getInstance().getDefaultCharset().name()))) { if (p.waitFor() == 0) { String s = lineRead.readLine(); if (s != null && s.matches("0?\\d{3}")) { //$NON-NLS-1$ @@ -150,7 +149,8 @@ public class FS_POSIX extends FS { try { String w = readPipe(userHome(), new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - Charset.defaultCharset().name()); + SystemReader.getInstance().getDefaultCharset() + .name()); if (!StringUtils.isEmptyOrNull(w)) { gitExe = new File(w); } @@ -168,7 +168,8 @@ public class FS_POSIX extends FS { try { String w = readPipe(userHome(), new String[] { "xcode-select", "-p" }, //$NON-NLS-1$ //$NON-NLS-2$ - Charset.defaultCharset().name()); + SystemReader.getInstance().getDefaultCharset() + .name()); if (StringUtils.isEmptyOrNull(w)) { gitExe = null; } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index d44dc32d14..ff094f6975 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -13,7 +13,6 @@ package org.eclipse.jgit.util; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.Files; @@ -150,8 +149,10 @@ public class FS_Win32 extends FS { String w; try { w = readPipe(userHome(), - new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - Charset.defaultCharset().name()); + new String[] { "bash", "--login", "-c", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "which git" }, // //$NON-NLS-1$ + SystemReader.getInstance().getDefaultCharset() + .name()); } catch (CommandFailedException e) { LOG.warn(e.getMessage()); return null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java index df9c6c78fe..93bf847196 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java @@ -1160,7 +1160,7 @@ public final class RawParseUtils { // Try the default character set. A small group of people // might actually use the same (or very similar) locale. - Charset defcs = Charset.defaultCharset(); + Charset defcs = SystemReader.getInstance().getDefaultCharset(); if (!defcs.equals(cs) && !defcs.equals(UTF_8)) { try { return decode(b, defcs); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java index 54fd539f67..16e2577911 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -17,6 +17,9 @@ import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; @@ -198,6 +201,8 @@ public abstract class SystemReader { private AtomicReference<FileBasedConfig> jgitConfig = new AtomicReference<>(); + private volatile Charset defaultCharset; + private void init() { // Creating ObjectChecker must be deferred. Unit tests change // behavior of is{Windows,MacOS} in constructor of subclass. @@ -439,6 +444,35 @@ public abstract class SystemReader { } /** + * Retrieves the default {@link Charset} depending on the system locale. + * + * @return the {@link Charset} + * @since 6.0 + * @see <a href="https://openjdk.java.net/jeps/400">JEP 400</a> + */ + public Charset getDefaultCharset() { + Charset result = defaultCharset; + if (result == null) { + // JEP 400: Java 18 populates this system property. + String encoding = getProperty("native.encoding"); //$NON-NLS-1$ + try { + if (!StringUtils.isEmptyOrNull(encoding)) { + result = Charset.forName(encoding); + } + } catch (IllegalCharsetNameException + | UnsupportedCharsetException e) { + LOG.error(JGitText.get().logInvalidDefaultCharset, encoding); + } + if (result == null) { + // This is always UTF-8 on Java >= 18. + result = Charset.defaultCharset(); + } + defaultCharset = result; + } + return result; + } + + /** * Returns a simple date format instance as specified by the given pattern. * * @param pattern |