NOGDUS $1670.00 has been donated to NOGDUS!
September 23, 2017, 12:30:30 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: TUTORIAL: Making Java applications OS friendly  (Read 19873 times)
0 Members and 1 Guest are viewing this topic.
RedSlash
Moderator
Offline Offline

Respect: 10
« on: November 15, 2008, 02:22:12 AM »

Java is a very useful tool for developing cross-platform programs. This nice thing about Java is that it can build cross-platform bytecode binaries, which can be executed on any systems running JRE. The only drawback to Java is that these binaries are usually distributed as JAR files and it feels unnatural for end-users to be launching JAR files instead of native EXEs.

This is a guide on deploying Java applications on Windows, Linux and Mac OS X by using native executable wrappers to make Java applications feel more like home. This is not a guide on building native Java executables, please see GCJ for that.

The idea is we're going to wrap Java JARs into native exes on each host system. I will be using the application 'JavaSoundDemo.jar' from this package http://java.sun.com/products/java-media/sound/samples/JavaSoundDemo.zip to demonstrate on how to make it OS friendly.

WINDOWS

In Windows, we like launching EXEs instead of JAR files. A google search will tell you about a bunch of utilities that will convert JARS to EXE. I'll show you how to do it yourself. Luckily, Java has the capability to launch JAR files appended on to EXE files since v1.5. What this means is that we can write a C program which would call Java to execute itself, and then tack a JAR file on the end of the exe to make a self running Java executable. First, lets write the wrapper in C:
Code:
#include <process.h>
#include <windows.h>
#include <string.h>

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR arg,int nShow)
{
char exe_name[4096], path[4096];
STARTUPINFO si;
PROCESS_INFORMATION pi;

/* Get the fullpath name of the executable */
int n = GetModuleFileName(hInst,exe_name,4096);
if(n >= 4096) {
MessageBox(NULL,"Pathname too long.","Error",MB_ICONERROR);
return -1;
}

/* determine pathname of executable */
strcpy(path,exe_name);
char *p = strrchr(path,'\\'); /* look for \ */
if(!p) {
char *p = strrchr(path,'/'); /* check for / just in case */
if(!p) {
MessageBox(NULL,"Failed to determine pathname.","Error",MB_ICONERROR);
  return -1;
}
}
*p = '\0';

/* Prepare the command "javaw.exe -jar /path/to/app.exe" */
char cmd[5200] = "javaw.exe -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel -jar ";
strcat(cmd,"\"");
strcat(cmd,exe_name);
strcat(cmd,"\"");

/* execute Java */
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);
if(!CreateProcess(NULL,cmd,NULL,NULL,FALSE,0,NULL,path,&si,&pi)) {
MessageBox(NULL,"JRE v5.0+ is required to run this program.","Java not detected.",MB_ICONERROR);
return -1;
}
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}

You can modify the code to do whatever you want, add a program icons, etc.. Note that we pass -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel to make the theme look like windows.

I'll be using a Windows cross compiler on Linux to compile the wrapper, but you can build this in Windows too, since the idea is the same.

Code:
$ sudo apt-get install mingw32

$ i586-mingw32msvc-gcc -mwindows -Os javaexewrap.c -o javaexewrap.stub

I've named it ' javaexewrap.stub' to avoid confusion that the wrapper exe is runnable. Now, we append the JAR file after the EXE to create a final executable:

Code:
$ cat javaexewrap.stub JavaSoundDemo.jar > JavaSoundDemo.exe

Now distribute JavaSoundDemo.exe to your friends and double-click! (Make sure they have Java installed.)



LINUX

If we wanted to distribute it as a single Linux EXE, we can use the exact same trick as with Windows. With Linux, shell scripts exes are the normal, so we don't exactly need to write a C program. First, create a shell script which calls Java to execute itself:

Code:
$ cat > JavaWrap <<EOF
#!/bin/sh

exec java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel -jar "\$0" "\$@"
exit -1

EOF

Again, we pass -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel to make the theme feel like GTK.

Now concatenate them together.
Code:
$ cat JavaWrap JavaSoundDemo.jar > JavaSoundDemo

$ chmod 755 JavaSoundDemo

And to run it:
Code:
$ ./JavaSoundDemo



and you can install it to /usr/local/bin or whatever.

MAC OS X

There is a tool in /Developer/Applications/Utilities called 'JAR Bundler'. It is so easy to use I won't even bother explaining. With JAR Bundler, you can distribute your Java application exactly like any other Mac applications and no one will be able to tell the difference. Especially, since Java 1.5 is installed by default on Leopard, the app will simply work, hassle free.




Logged
Richard Marks
Administrator
Offline Offline

Respect: 3425
« Reply #1 on: November 15, 2008, 10:09:36 PM »

That is amazing Redslash! I never knew any of what you covered! Grin
Thank you for posting such valuable information!
I look forward to learning more cool things from you! Cheesy
Logged

Tags:
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines
.: Theme by Richard Marks :.
Valid XHTML 1.0! Valid CSS!