Deployment: native application bundles

Igor Nekrestyanov igor.nekrestyanov at
Fri Jun 15 23:07:06 PDT 2012

> Regarding the MSI installer, using WiX does make it easier but I'm 
> wondering if there would be some merit in trying to write our own MSI 
> creator using the Windows Installer SDK. I haven't used it myself yet 
> but I believe it can be used to create MSI's. This would have the 
> advantage of not needing extra software installed, and also would 
> allow us to customise closely to what we need specifically for Java 
> installations (e.g. provide our own configuration options in whatever 
> syntax or format we want - e.g. an 'app-profile.xml'). The 
> disadvantage of course is the extra work, but this may be something I 
> could look at in my POC side of it. Something to think about anyway.
Basic approach we are using is to adding support for "bundlers" to the 
toolchain. Bundler is something that can produce package out of set of 
app resources, JRE, etc.
Bundler may or may not have additional requirements (like run only on 
specific platform or require WiX, etc.)

When developer requests to "bundle" app we produce all bundles we can 
generate (by running all applicable bundlers).

JavaFX 2.2 will provide some set of bundlers embedded into packaging tools.

This approach allow to add new bundler or rewrite bundler later on if 
there will be better solution (e.g. WiX-less MSI bundler or cross 
platform deb bundler, etc).

As for WiX-less bundler specifically i think it might be nice to have 
but i do not see it as critical issue right now.
We are generating WiX config files based on templates and can expose any 
configuration parameters we need in whatever syntax we want.
Once we understand what is limiting with this approach we can decide on 
how we can get something better.
Using existing solution that works well for producing MSI allow us to 
focus on JavaFX specific problems and other bundlers.
> Regarding natives, if you are using an executable JAR I don't think 
> this will work (i.e. executable JARs don't support native included in 
> them), unless the developer does the old extract and include on path 
> trick. Better that the natives just get bundled into the installation 
> directory and not into the jar, I reckon. It's a bit of a messy area 
> (especially for auto-updates) so probably worth making sure we're 
> covered in this area fairly early on.
I think it do not understand the problem.
In my model i assume that application image is something you can run 
using java.exe like
     cd app-image/
     java -cp main.jar main.class
(where app image is your dist of build folder).

When you are running app from your IDE, debugger or command line it 
knows how to load native resources.
I expect same copy of app-image to be kept under app/ folder in the 
installed image.

Anyway, let me try to craft an example and we will see.
> Regarding the launching of the process, the way I do it also seems to 
> give it the process the name of the app the proper name (and not 
> 'java.exe'), which is a pleasant surprise. Do you use the same sort of 
> code as follows?
My windows launcher is fairly simple now. Here is relevant part:

>>     // Dynamically load the JVM
>>     HMODULE jvmLibHandle = LoadLibrary(jvmPath);
>>     if (jvmLibHandle == NULL) {
>>         DWORD dwErr = GetLastError();
>>         MessageBox(0, _T("Error loading jvm.dll"), jvmPath, 
>>         return FALSE;
>>     }
>>     //convert argument to ASCII string as this is what CreateJVM needs
>>     wcstombs_s(&outlen, jarASCII, (size_t) wcslen(jar) + 1, jar, 
>> (size_t) wcslen(jar) + 1);
>>     strcpy_s(classpath, MAX_PATH*2, "-Djava.class.path=");
>>     strcat_s(classpath, MAX_PATH, jarASCII);
>>     // Set up the VM init args
>>     jvmArgs.version = JNI_VERSION_1_2;
>>     //TODO: add support for custom JVM parameters
>>     options[0].optionString = classpath;
>>     jvmArgs.version = 0x00010002;
>>     jvmArgs.options = options;
>>     jvmArgs.nOptions = 1;
>>     jvmArgs.ignoreUnrecognized = TRUE;
>>     // Create the JVM
>>     // NB: need to use ASCII string as UNICODE is not supported
>>     createProc = (JVM_CREATE) GetProcAddress(jvmLibHandle, 
>> "JNI_CreateJavaVM");
>>     if (createProc == NULL) {
>>         MessageBox(0, _T("Failed to locate JNI_CreateJavaVM"), 
>> jvmPath, MB_ICONERROR | MB_OK);
>>         return FALSE;
>>     }
>>     if ((*createProc)(&jvm, &env, &jvmArgs) < 0) {
>>         // Should not happen
>>         // FIXME: report localized error
>>         return FALSE;
>>     }
>>     cls = env->FindClass("com/javafx/main/Main");
>>     if (cls != NULL) {
>>         mid = env->GetStaticMethodID(cls, "main",
>>             "([Ljava/lang/String;)V");
>>          if (mid != NULL) {
>>             jclass stringClass = env->FindClass("java/lang/String");
>>             jobjectArray args = env->NewObjectArray(0, stringClass, 
>> NULL);
>>             env->CallStaticVoidMethod(cls, mid, args);
>>         } else {
>>             MessageBox(0, _T("no main method"), _T("Expected to find 
>> com.javafx.main.Main.main()"), MB_ICONERROR | MB_OK);
>>         }
>>     } else {
>>         MessageBox(0, _T("no main class"), _T("Expected to find 
>> com.javafx.main.Main"), MB_ICONERROR | MB_OK);
>>     }
>>     if (env->ExceptionOccurred()) {
>>         MessageBox(0, _T("Failed due to exception."), _T("Exception 
>> thrown from com.javafx.main.Main.main()"), MB_ICONERROR | MB_OK);
>>         env->ExceptionDescribe();
>>     }
> I'd be keen to keep what I do in line with what you are doing where 
> possible.
> On Sat, Jun 16, 2012 at 4:59 AM, Igor Nekrestyanov 
> <igor.nekrestyanov at <mailto:igor.nekrestyanov at>> 
> wrote:
>     hi, thanks for all questions.
>     Please keep them coming (bugs and suggestions are very welcome too!),
>>     The Ensemble MSI install worked for me on Windows 7 no problems.
>>     I haven't tried building my own app as yet though.
>>     It installed into 'C:\Users\zonski\AppData\Local\Ensemble2'.
>>     Installing into Program Files is probably more correct on
>>     windows. Is this 'appdata' the intended final location, or is
>>     this just for getting it all running for now?
>     Original goal was to be able to install without requiring admin
>     permissions.
>     Both MSI and EXE installers are currently build to do this.
>     It is possible to customize install location and make it system
>     wide by tweaking WiX/Inno Setup template files.
>     Clearly we want to expose better APIs for customization but it is
>     not clear what are importnat config parameters and how to expose them
>     in more or less cross platform way, hence we decided that for 2u2
>     we will provide an easy way to build basic package and do minimal
>     customization
>     as well as (very) advanced way for advanced users.
>     Based on feedback we will figure out how to expand built-in
>     configuration APIs for future releases.
>     I am planning to post more about package customization options and
>     other tricks&tips but i am amateur blogger and slow typer, so it
>     will take me few days :)
>     Perhaps we should reconsider and produce EXE to be user level
>     installation and MSI to be system level by default.
>     I believe it is also possible to pass parameters to msiexec to
>     overwrite some of MSI settings (end this is not unusual in the
>     enterprise deployments).
>     However, i had not tried if it is possible to install this MSI
>     system wide (and i am not sure if my MSI expertise is deep enough
>     to craft MSI that can do both,
>     suggestions are very welcome).
>>     Is the source code available for this at all?
>     Sorry, it is part of deploy/packager module that is not open
>     sourced yet.
>>     If not, I'm very interested in how the 'exe' launcher code looks.
>>     Is this code you've written or part of one of the tools you've
>>     made use of? I'm particularly interested to see how it starts the
>>     app - does it just kick off another process on the executable jar
>>     via something like 'java -jar ensemble.jar' or does it try to run
>>     the Java app within it's own 'exe' process somehow (I'm assuming
>>     the later?).
>     yes, launcher will instantiate JVM in the launcher process.
>     Check out list of processes when sample app is running. There is
>     no java.exe but there is Ensemble.exe
>>     I notice also that the jfx DLLs have been copied straight into
>>     the 'jre/bin' directory.
>     Starting 7u6 JRE/JDK will include JavaFX as part of Java
>     installation.
>     So, nothing special here. It is just runtime image.
>>     Is this how you see all native dependencies playing out, i.e. if
>>     my application uses other native libraries how do I package them
>>     into the build and where will they be installed to in the
>>     extracted directory?
>     No, i do not think application resources will go into runtime.
>     Application resources will stay in the "app" folder (native libs too).
>     The approach here is to "bundle" app without requiring to rewrite it.
>     During the development cycle your build output should have copy of
>     application you can execute and debug (but it depends on
>     environment, i.e. java+javafx runtime).
>     Bundle is essentially
>          copy of this application + java runtime  + launcher
>     Having said that i had not tried to craft example with native
>     libraries myself. Will certainly try to do.
>>     One more question: when we say we have to build on the native
>>     platform to get the correct deployments, does that include 32bit
>>     vs 64bit? I'm guessing I could have a 32bit and 64bit JDK
>>     installation on the one machine and build a version of my app for
>>     each, but correct me if I'm wrong on this.
>     yes, two installations should do.
>     Currently ant task will try to use RUNNING version of java as
>     source for cobundle.
>     If it is not appropriate (e.g. java 6 that is not javafx cobundle)
>     then it bundled app will not be created.
>     In the future we may add option to specify which JDK to use as
>     import for bundle creation but for now we are taking shortcuts to
>     avoid exposing too much (kind of late in release).
>>     I assume there's no way for a single JDK installation to produce
>>     both 32 and 64bit versions? 
>     No, as currently JDK installations do not include both 32 and 64
>     bit bits. After all we are copying them into bundle.
>     -igor
>>     Very, very nice start to this all!
>>     Cheers,
>>     Dan
>>     On Fri, Jun 15, 2012 at 5:16 PM, Igor Nekrestyanov
>>     <igor.nekrestyanov at
>>     <mailto:igor.nekrestyanov at>> wrote:
>>         Hi,
>>         One thing we are adding to JavaFX packaging tools in 2.2 is
>>         ability to produce native application bundles:
>>         We are not seeing this as the only way to deploy JavaFX
>>         applications -- webstart, embedded applications
>>         and doubleclickable jars are first class citizens (and it
>>         would be great to explore other options).
>>         But we hope it might be good option for many deployment
>>         scenarios.
>>         Please give it a try and provide feedback (and report bugs of
>>         course),
>>         -igor

More information about the openjfx-dev mailing list