Skip to content

Commit

Permalink
Add getNativeEncoding() API
Browse files Browse the repository at this point in the history
With https://openjdk.java.net/jeps/400 implemented in Java 18,
"file.encoding" system property became meaningless and can't be used
anymore to determine system native encoding.

Unfortunately, that property was widely used in Eclipse API's and was
the standard way to get default system encoding. So both
org.eclipse.ui.WorkbenchEncoding.getWorkbenchDefaultEncoding() and
org.eclipse.core.resources.ResourcesPlugin.getEncoding() were using this
property and need now a proper replacement.

The new API tries first to get the value of the "native.encoding"
property (populated by Java 18), and if not there, uses internal
"sun.jnu.encoding" property (used in all supported Java versions).
In case neither property is set, Charset.defaultCharset() is used as
fallback solution.

See eclipse-platform/eclipse.platform.resources#154
  • Loading branch information
iloveeclipse committed Jun 10, 2022
1 parent c235267 commit 10d5236
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion bundles/org.eclipse.core.runtime/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Version: 3.25.0.qualifier
Bundle-Version: 3.26.0.qualifier
Bundle-SymbolicName: org.eclipse.core.runtime; singleton:=true
Bundle-Vendor: %providerName
Bundle-Activator: org.eclipse.core.internal.runtime.PlatformActivator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.net.URL;
import java.nio.charset.*;
import java.util.*;
import org.eclipse.core.internal.runtime.*;
import org.eclipse.core.runtime.content.IContentTypeManager;
Expand Down Expand Up @@ -484,6 +485,7 @@ public final class Platform {

private static final String LINE_SEPARATOR_VALUE_LF = "\n"; //$NON-NLS-1$
private static final String LINE_SEPARATOR_VALUE_CRLF = "\r\n"; //$NON-NLS-1$
private static Charset defaultCharset;

/**
* Private constructor to block instance creation.
Expand Down Expand Up @@ -1462,4 +1464,47 @@ public static boolean inDebugMode() {
public static boolean inDevelopmentMode() {
return PlatformActivator.getContext().getProperty("osgi.dev") != null; //$NON-NLS-1$
}

/**
* Retrieves the <b>native</b> system encoding ({@link Charset}) based on the
* system locale.
* <p>
* In case the detection of native encoding fails, returns
* {@link Charset#defaultCharset()}, which is always {@code UTF-8} on Java 18
* and later.
*
* @return the {@link Charset}, never null
* @see <a href="https://openjdk.java.net/jeps/400">JEP 400</a>
* @since 3.26
*/
public static Charset getNativeEncoding() {
Charset result = defaultCharset;
if (result == null) {
// JEP 400: Java 18 populates this system property.
String encoding = System.getProperty("native.encoding"); //$NON-NLS-1$
try {
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 (IllegalCharsetNameException | UnsupportedCharsetException e) {
if (isRunning()) {
getLog(Platform.class).error("Unable to read system native encoding", e); //$NON-NLS-1$
} else {
e.printStackTrace();
}
}
if (result == null) {
// This is always UTF-8 on Java >= 18.
result = Charset.defaultCharset();
}
defaultCharset = result;
}
return result;
}
}

0 comments on commit 10d5236

Please sign in to comment.