Creating a Java launcher to enable dark mode
To run a Java application in dark mode from the command line currently requires using
a Java launcher (typically, a program whose name is java
)
that itself opts-in to dark mode. Because any application launched by this launcher will
run in dark mode when the system is configured to use dark mode, it is best
to have a separate launcher used only for launching dark mode aware applications.
A Java launcher can opt-in to dark mode by being built against the macOS 10.14 SDK. If rebuilding the launcher is not possible or not convenient, an alternative described here is patching the existing launcher to make it look like it was linked against the 10.14 SDK. Again, the recommendation is to make a copy of the launcher executable for this purpose. It may be most convenient to make a copy of the entire JDK containing the patched launcher, for programs like IntelliJ IDEA that allow a project to choose the JDK used to execute a program.
Patching a Java launcher requires a hex editor, such as Hex Fiend.
The file to edit is Contents/Home/bin/java
in an Oracle JDK.
Again, be sure to copy this file before modifying it.
The modification involves changing a field in the executable that represents
the SDK version. The existing SDK version is probably 10.9
, and the goal is
to change that to 10.14
. The field is a two byte field, but only the
byte corresponding to the minor version needs to be changed.
The first step is to find the field. Use the otool
program to dump the
loader defined fields in the executable:
otool -l javaThe output will include something like this:
Load command 8 cmd LC_UUID cmdsize 24 uuid B8D1A98A-FDA3-388D-B1A3-90E83666847B Load command 9 cmd LC_VERSION_MIN_MACOSX cmdsize 16 version 10.7 sdk 10.9The SDK in this executable is
10.9
. It needs to be 10.14
.
Also note the UUID in Load Command 8.
Next, open the file in a hex editor and search for the UUID. The UUID is distinctive. Searching for the first four hex digits is probably sufficient.
Approximately 16 bytes after the UUID is the SDK field. The SDK version is represented
as two bytes, in this case, 09
and 0A
,
hex for 9
and 10
, corresponding to 10.9
.
Select the 09
byte and alter it to 0E
(14).
Save the file. Then run otool
again to make sure it now says SDK 10.14
. On some macOS releases, it may be necessary to code sign the executable to permit it to be run.