Search code examples
javamacos

How to make Java Mac App that doesn't require installing Java


I want to make a Mac Application using Java code I wrote, and I want to make it that the person using it doesn't require Java to be installed on their own computer.

Is there a way to create a Mac Application so it can run on any mac, whether they have Java installed or not?


Solution

  • Either bundle a JVM or compile native

    You have a choice of three ways to deliver a local Java-based app to a Mac user.

    • User installs a JDK or JRE on their machine. (Or I.T. sysadmin person does so.)
    • App comes bundled with a JVM for a specific OS and specific chip architecture.
    • App is compiled to native code for a specific OS and specific chip architecture.

    Install JDK/JRE

    In a controlled enterprise environment such as a corporation or school, it may be practical to install a JDK or JRE on every Mac.

    If you are writing JavaFX apps, you could install an edition of a JDK/JRE that comes bundled with the necessary OpenJFX libraries. Vendors offering JDK/JRE products bundled with OpenJFX include Azul Systems and BellSoft.

    Your Java app can then execute by using the already-installed JVM.

    By the way, in such a controlled environment, OpenWebStart is a way to deliver and launch a local Java app by using the convenience of a web browser.

    In contrast, Oracle has abandoned the approach of expecting common consumer machines to come equipped with Java pre-installed. For details, see the Oracle white paper, Java Client Roadmap Update. So expecting individuals to have Java installed is not practical.

    Bundle JDK/JRE

    You can build your app in such a way as to include a JDK/JRE for a specific kind of machine, meaning a specific operating system and a specific chip architecture.

    For Macs, that means you need one build for Macs with Intel (x86) chips, and another build for Macs with Apple Silicon (ARM, AArch64) chips. You would need to to either supply two separate versions of your app, one for each child, or perhaps a “fat binary” that includes two JDKs/JREs for both chips. The fat binary approach was supported by Apple (and its originator, NeXT Inc.) in previous chip transitions, but I’ve not verified is this is the case now in the Intel to Apple Silicon transition.

    Modern tooling helps with embedding a JDK/JRE. See jlink and jpackage. See Packaging Tool User's Guide. As of Java 9, the Java Platform Module System enables including only the parts of the JDK/JRE actually used by your particular app. Unused parts are omitted, making for a smaller-sized final app artifact.

    Compile native

    The last way uses GraalVM technology to compile your code to native code specific to the targeted runtime machine. Instead of compiling to bytecode for a conventional JVM to interpret and optionally JIT-compile at runtime, full compilation to native machine language is performed when you build your app. This approach is cutting-edge, perhaps bleeding-edge. So research carefully and test thoroughly if you dare to consider this novel approach.

    With both of the last two approaches, you have the option of distributing through the Apple App Store.