Skip to content

Bugfix: Replace removed sun.misc Base64 classes with java.util.Base64 - #942

Open
bdthombre wants to merge 1 commit into
brainstorm-tools:masterfrom
bdthombre:fix-java9-base64
Open

Bugfix: Replace removed sun.misc Base64 classes with java.util.Base64#942
bdthombre wants to merge 1 commit into
brainstorm-tools:masterfrom
bdthombre:fix-java9-base64

Conversation

@bdthombre

Copy link
Copy Markdown

Fixes #941

Problem

sun.misc.BASE64Decoder and sun.misc.BASE64Encoder are JDK-internal classes that were removed in Java 9. Matlab versions shipping a newer JRE (R2026a uses Java 11) cannot even parse the files that import them:

Line 298: Error: File: import_label.m Line: 27 Column: 8
Unable to find or import 'sun.misc.BASE64Decoder'. Imported names must end with '.*' or be fully qualified.

Call stack:
>import_anatomy_fs.m at 298
>import_anatomy.m at 78
>bst_call.m at 28
>tree_callbacks.m>@(h,ev)bst_call(@import_anatomy,iSubject,0) at 575

Because an import is resolved when the function is parsed, even the two files that never use the decoder crash. This breaks importing any anatomy with FreeSurfer/CAT12 labels, reading and writing GIFTI surfaces, and the snapshots in HTML reports.

Changes

Added bst_base64() in toolbox/misc, so the Java dependency lives in a single place:

bytes = bst_base64('decode', str);    % str  : char array (line breaks allowed)
  str = bst_base64('encode', bytes);  % bytes: int8/uint8 vector (or Java byte[])

It uses java.util.Base64 (Java >= 8), and falls back to matlab.net.base64decode/encode (Matlab >= R2016b) and then to the old sun.misc classes, so older installations keep working unchanged.

To keep the behaviour identical to the previous code, the helper:

  • tolerates line breaks and white spaces in the encoded string (as decodeBuffer did),
  • returns int8 when decoding (as decodeBuffer did), so the existing typecast() and dunzip() calls are unchanged,
  • strips the line breaks when encoding (this was done by the callers before).

Updated callers:

File Change
toolbox/io/import_label.m removed the unused import
toolbox/io/in_tess_gii.m removed the unused import
toolbox/io/in_gii.m decoding of Base64Binary / GZipBase64Binary data arrays
toolbox/io/out_tess_gii.m encoding of the vertices and faces
toolbox/process/bst_report.m encoding of the PNG snapshots

Testing

Matlab R2026a Update 4 (Java 11.0.32), macOS:

  • Base64 round-trip on 5000 random bytes, on float32 arrays, on known test vectors (Brainstorm <-> QnJhaW5zdG9ybQ==), and on CRLF-wrapped input: all exact
  • in_gii / in_tess_gii on a GZipBase64Binary surface (external/ImaGIN/private/SEEG_cortex_hip_amy_8196.surf.gii): 7861 vertices, 15359 faces decoded correctly
  • Full in_tess_gii -> out_tess_gii -> in_tess_gii round-trip: faces identical, vertex max difference 0
  • FreeSurfer anatomy import through the GUI, which was the original failure, now completes

Happy to adjust the naming or the location of the helper if you prefer something else.

…e64`

`sun.misc.BASE64Decoder` and `sun.misc.BASE64Encoder` are internal JDK classes
that were removed in Java 9. Matlab versions shipping a newer JRE (e.g. R2026a,
Java 11) fail to even parse the files that import them:

    Error: File: import_label.m Line: 27 Column: 8
    Unable to find or import 'sun.misc.BASE64Decoder'.

This breaks importing any anatomy with FreeSurfer/CAT12 labels, reading and
writing GIFTI surfaces, and the snapshots in HTML reports.

Added `bst_base64()` in toolbox/misc, which uses `java.util.Base64` (Java >= 8)
and falls back to `matlab.net.base64decode/encode` (Matlab >= R2016b) and then
to the old `sun.misc` classes, so older installations keep working.
Like the previous decoder, it tolerates line breaks and white spaces in the
encoded string, and it strips the line breaks when encoding.

Updated the callers:
 - import_label.m, in_tess_gii.m: removed the unused imports
 - in_gii.m: decoding of Base64Binary / GZipBase64Binary data arrays
 - out_tess_gii.m: encoding of the vertices and faces
 - bst_report.m: encoding of the PNG snapshots

Tested with Matlab R2026a (Java 11): Base64 round-trip on random bytes, on
known test vectors and on line-wrapped input; and read/write round-trip of a
GZipBase64Binary .gii surface (7861 vertices, 15359 faces) returning identical
vertices and faces.
@rcassani

Copy link
Copy Markdown
Member

@bdthombre thank you for your contribution!

This is issue has been already reported in the forum:

In those cases we pointed the user to install JDK8 and set Matlab to use it.
This was solution was given because Brainstorm supports versions of Matlab as old as 10 years, and JDK8 is the version that is supported for all of these (including R2026a): https://www.mathworks.com/support/requirements/openjdk.html

The proposed wrapper in this PR can help with this, so the user will not need to manually install and set JDK8. Indeed, I made a proof-of-concept that was not merged: rcassani@e5dfb01

We will thoroughly test the proposed changes, this may take a bit because there are multiple places where Brainstorm uses the JDK. Moreover, Brainstorm runs in multiple versions of Matlab, different OS and CPU architectures. In the mean while you can setup JDK8 manually.


I think this is an issue only for Matlab macOS, and not only for 2026a, but earlier versions (as per the forum posts). AFAIK in Linux and Windows, Matlab is still shipped with JKD8.

@bdthombre

bdthombre commented Aug 25, 2026

Copy link
Copy Markdown
Author

Thanks. Please do what is best for your project, locally this solution is working without any issues so far since then for me, just to keep you informed. If any issues comes I'll post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anatomy import fails on Matlab R2026a: 'sun.misc.BASE64Decoder' removed in Java 9

2 participants