Deploy OpenJFX 8 Apps To The Mac App Store [Part 1]
**[Update: 19.11.2013]: ** gradle script available that simplifies the process dramatically!
Java 8 is a major update from a language perspective and also from a platform perspective. It brings new APIs and significant syntax improvements such as lambda expressions. JavaFX brings support for 3D nodes, highly improved Swing integration, new controls and much more.
Many developers do not move to Java 8/JavaFX 8 as it has not been officially released yet and it is not allowed to use the EA builds for releasing applications (we can’t ship the EA runtime). The expected release date is March 2014.
Use JavaFX 8 Today!
But the great thing is that Java 8 and JavaFX 8 are fully open sourced now. This allows to create release builds of OpenJDK and OpenJFX (the open source versions of Java 8 and JavaFX 8). To test how well this works I recently submitted VPlot, an OpenJFX 8 app to the Mac App Store that makes use of the 3D integration that is now part of JavaFX 8.
Contents
In this part of the tutorial you will learn how to build your own OpenJDK 8 image including OpenJFX 8.
Compile OpenJDK 8 & OpenJFX 8
Requirements
- Mac OS >= 10.8
- XCode == 4.6.x
- X11/XQuartz (provides freetype for JDK & we use Xterm)
- Mercurial (version?)
- JDK >= 1.7.0_25
- Gradle >= 1.4 (currently tested with 1.4-1.6)
Step 1: Download OpenJDK 8 Sources
The OpenJDK project provides a good introduction to building OpenJDK. To really understand how to do it you should read it!
To get the code open a terminal and type
#> hg clone http://hg.openjdk.java.net/jdk8/jdk8 YourOpenJDK
#> cd YourOpenJDK
#> bash ./get_source.sh
This will take a while.
Step 2: Download And Run JSelect
Jselect is a tool that allows to easily configure JDK installation paths. Just download and unpack it. It can be started by executing the run.sh
script.
Now run JSelect and specify your JDK 7 installation in that will be used as bootstrap JDK to build OpenJDK and the OpenJDK source location.
In case of JDK 1.7.0.25 the path will be:
/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/
Now click Open CMD
. JSelect will open a Xterm window which displays the selected Java version.
Example output:
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
#>_
Step 3: Compile OpenJDK 8
Make sure to install Xcode 4.6.x
and to install its CLI (command line interface). If you have multiple version of Xcode it is necessary to select the correct one! This can be doe with the following command (example for version 4.6.3):
#> sudo xcode-select --switch /Applications/Xcode4.6.3.app/Contents/Developer
Now it is time to finally compile the JDK:
#> java -version
java version "1.7.0_25"
#> ./configure \
--with-debug-level=release \
--with-milestone="1" \
--with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/ \
--with-build-number=109
#> make clean images
NOTE: change the bootstrap jdk folder if you use a different version than
JDK 1.7.0.25
.
You may change the build number. I have chosen it to match the EA provided by Oracle.
NOTE: if you get compile errors it is likely that you didn’t select the correct Xcode version or that something went wrong with selecting it. In this case it might help to uninstall the CLI by typing
sudo pkgutil --forget com.apple.pkg.DeveloperToolsCLI
and to install it again afterwards.
Step 4: Using the new OpenJDK
To test and use the new JDK, we use JSelect again. Select the location of the JDK 8 image:
YourOpenJDK/build/macosx-x86_64-normal-server-release/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/
NOTE: YourOpenJDK has to match the location from above when you checked out the code
Now click Open CMD
. A terminal window will open. If it shows the correct version number then you know that the PATH variable points to the OpenJDK installation.
Example Output:
openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build 1.8.0-internal-miho_2013...)
OpenJDK 64-Bit Server VM (build 25.0-b54, mixed mode)
#>_
Step 4: Downloading OpenJFX
Make sure to use the Xterm window from [Step 4][].
On the OpenJFX page there is a good tutorial on how to build it. It just misses some details about how to build with OpenJDK 8 and choosing the correct Xcode version. You should definitely read it!
Before proceeding here it is important to choose the correct source branch. There is one called master
that matches the version used for the weekly JDK builds provided by Oracle. The next option is the controls
branch useful for working on bugfixes for controls etc. Finally, there is the graphics
branch. I have tested the master
and graphics
branch. Both worked great for me.
To clone the graphics
branch type
#> hg clone http://hg.openjdk.java.net/openjfx/8/graphics/rt rt-graphics
Also this will take some time.
Step 5: Configuring OpenJFX
The first thing to do is to create a file called gradle.properties
inside the rt-graphics
directory. You can also check the gradle.properties.template
file that contains all possible options plus documentation.
NOTE: in some tutorials people suggest to copy the
gradle.properties
file to the$HOME/.gradle
folder. Don’t do that! It is always better to keep the configuration as local as possible. If you think this is wrong that you probably know what you do. Go ahead đŸ™‚
The content of gradle.properties
should be
MACOSX_SDK_PATH = /Applications/Xcode4.6.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
BINARY_STUB=../stubs/b109/jfxrt.jar
This first line specifies that 10.7
shall be the OS X build sdk.
Note: on 10.9 the 10.7 sdk might not be available. In this case please select 10.8.
In the second line we specify the location of the binary stub jfxrt.jar
file (use one from recent Java 8 EA builds).
In build.gradle
we specify build numbers again:
jfx.build.jdk.version=1.8.0
jfx.build.jdk.buildnum=110
jfx.build.jdk.buildnum.min=1
Step 6: Building OpenJFX
Now it is time to build OpenJFX including native libraries:
#> gradle -PBUILD_NATIVES=true -PBUILD_WEBKIT=true clean sdk
Step 7: Copying OpenJFX To The OpenJDK Image
Disclaimer: I’m not a gradle expert!
I decided to create a custom gradle task to complete the final task. Create a file addToOpenjdk.gradle
with the following content (adjust paths to match your OpenJDK location):
task copyRTLibs(type: Copy) {
def JDK_PATH="YourOpenJDK/build/macosx-x86_64-normal-server-release/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/"
from 'build/mac-sdk/rt/lib'
into JDK_PATH+'/jre/lib'
}
task copyLibs(type: Copy) {
def JDK_PATH="YourOpenJDK/build/macosx-x86_64-normal-server-release/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/"
from 'build/mac-sdk/lib'
into JDK_PATH+'/lib'
}
task copyBin(type: Copy) {
def JDK_PATH="YourOpenJDK/build/macosx-x86_64-normal-server-release/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/"
from 'build/mac-sdk/bin'
into JDK_PATH+'/bin'
}
task addToOpenJdk() << {
System.out.println("JAVA: "+System.getProperty("java.version"));
tasks["copyRTLibs"].execute()
tasks["copyLibs"].execute()
tasks["copyBin"].execute()
}
Execute the task by typing
#> gradle addToOpenJdk
Conclusion & Next Steps!
Congratulation! You have just created your own fully functional OpenJDK 8 release! The next part will cover App Store submission.
Stay tuned and follow me on Twitter
To be continued…