java-native-access/jna · critical · RuntimeException
UTF-16LE charset is not supported
Error message
UTF-16LE charset is not supported
What it means
WTypes.BSTR.setValue() encodes the Java string as UTF-16LE via String.getBytes("UTF-16LE"). Every compliant JVM must provide this charset, but if the encoding lookup throws UnsupportedEncodingException the library wraps it in this RuntimeException. It indicates a fundamentally broken JVM charset configuration rather than a data problem.
Solutions
- Use a standard, up-to-date JVM (Temurin/Oracle/Amazon Corretto) instead of a stripped custom runtime.
- Check for custom CharsetProvider implementations on the classpath and remove/fix them.
- Reinstall/verify the JDK/JRE installation.
- Catch the RuntimeException only as a last resort — it signals an unrecoverable environment problem.
Example fix
// before
BSTR bstr = new BSTR("value"); // throws on broken JVM
// after
if (Charset.isSupported("UTF-16LE")) {
BSTR bstr = new BSTR("value");
} else {
throw new IllegalStateException("JVM missing UTF-16LE charset");
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!Charset.isSupported("UTF-16LE"))
throw new IllegalStateException("JVM lacks UTF-16LE charset; use a standard JRE"); Type guard
static boolean utf16leSupported() {
try { return Charset.forName("UTF-16LE") != null; }
catch (Exception e) { return false; }
} Try / catch
try {
BSTR b = new BSTR(value);
} catch (RuntimeException e) {
throw new IllegalStateException("Broken JVM charset environment", e);
} Prevention
- Use standard, current JVM distributions.
- Do not ship custom CharsetProvider SPIs unless necessary.
- Verify charsets in a startup self-check.
When it happens
Trigger: Constructing a BSTR (or calling setValue) on a JVM whose charset provider fails to resolve "UTF-16LE" — essentially only with a broken/exotic JRE, a faulty CharsetProvider, or a severely corrupted Java installation.
Common situations: Running on a stripped-down/custom JVM build lacking standard charsets; broken java.nio.charset.spi.CharsetProvider registration on the classpath; corrupted JRE runtime files.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Could not set proxy blanket.
- DACL is invalid
- destDir must be a directory.
- Error loading DLLCallback class
- Expected GetTokenInformation to fail with…
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/826ff9c18675bd9c.
Report an issue: GitHub.
Appendix: source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/WTypes.java:148
/**
* @deprecated Users should not change the value of an allocated {@link BSTR}.
*/
@Deprecated
public void setValue(String value) {
if(value == null) {
value = "";
}
try {
byte[] encodedValue = value.getBytes("UTF-16LE");
// 4 bytes for the length prefix, length for the encoded data,
// 2 bytes for the two NULL terminators
Memory mem = new Memory(4 + encodedValue.length + 2);
mem.clear();
mem.setInt(0, encodedValue.length);
mem.write(4, encodedValue, 0, encodedValue.length);
this.setPointer(mem.share(4));
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException("UTF-16LE charset is not supported", ex);
}
}
public String getValue() {
try {
Pointer pointer = this.getPointer();
if(pointer == null) {
return "";
}
int stringLength = pointer.getInt(-4);
return new String(pointer.getByteArray(0, stringLength), "UTF-16LE");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException("UTF-16LE charset is not supported", ex);
}
}
@Override
public String toString() {View on GitHub (pinned to d036ad9781)