Sunday, October 21, 2012

Jar Bundler - MAC OS X

I used to bundle all the jar files using JarBundler we get with Xcode. However, this is not working with JDK 7. Previously, I used it with JDK 1.6 (Apple Java 6) and then made a package file with Package Maker. Since JDK 7 is from Oracle, it cannot be used with Apple's tools like Xcode. Oracle cannot support or use, tools like Xcode or JarBundler as they use non-public APIs.

Therefore, apps using JDK 7 must be bundled with appbundler or javafxpacker. But according to Oracle "JavaFX applications can only be packaged on Mac as desktop applications and cannot be deployed on Mac, because there is no standalone JRE or JavaFX Runtime". Similarly, Launch4j version for Mac could only be used to create .exe files and cannot be deployed on Mac.

So how to do it? It seems the only option is appbundler (http://java.net/projects/appbundler).


In the terminal with the appbundler, you may get the following error ($ant bundle-button):

BUILD FAILED
/Users/me/Downloads/components-ButtonDemoProject/build.xml:16: java.nio.file.NoSuchFileException: /Users/nus/Downloads/components-ButtonDemoProject/Info.plist
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:520)
at sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:252)
at java.nio.file.Files.copy(Files.java:1225)
at com.oracle.appbundler.AppBundlerTask.copy(AppBundlerTask.java:566)
at com.oracle.appbundler.AppBundlerTask.copyRuntime(AppBundlerTask.java:357)
at com.oracle.appbundler.AppBundlerTask.execute(AppBundlerTask.java:290)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:390)
at org.apache.tools.ant.Target.performTasks(Target.java:411)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
at org.apache.tools.ant.Main.runBuild(Main.java:809)
at org.apache.tools.ant.Main.startAnt(Main.java:217)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)


It happens because JAVA_HOME is not set properly. Therefore, it can be set by in the terminal:
export JAVA_HOME=`/usr/libexec/java_home --version 1.7.0_10`
or
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home

1.7.0_10 is the JDK version I am using.

Thus, now I am getting BUILD SUCCESSFUL when run $ant bundle-button
You will get .app now.


Reference:
http://docs.oracle.com/javafx/2/installation_2-1/javafx-installation-mac.htm
http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/packagingAppsForMac.html

Sunday, October 14, 2012

Issue - JFileChooser on Mac OS X

These days I am converting a java code written in a Windows system to MAC OS X Lion(10.7.X). Though we know java is platform independent, with MAC OS I am getting various issues. I am having JDK 1.7.

The current problem I am having is with JFileChooser. According to Oracle, file chooser GUI is used for navigating the file system, and then either choosing a file or directory from a list, or entering the name of a file or directory. To display a file chooser, you usually use the JFileChooser API to show a modal dialog containing the file chooser.

So what is the problem I am facing. I am unable to select files with JFileChooser, even if I had set the selection mode as FILES_AND_DIRECTORIES. Even if the files are shown, in file chooser window the file names appear in gray. Thus, even if a file is selected and clicked save, actually a file is not selected. The sample code segment is shown below.

Code...
JFileChooser chooser = new JFileChooser()chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );

I tried various options to solve it, but could not get it to work. :(

Found the solution!! You need to change the default Look and Feel (LAF or L&F) for MAC.

At the beginning you have to set to JAVA LAF.

try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } catch(Exception e) { System.out.println("Error setting Java LAF: " + e); }

It is working now. :) You can try to change into other LAFs and see how it appears.

receive buffer of socket java.net.DatagramSocket@49cfbdab was set to 20MB, but the OS only allocated 3.36MB

Have you seen this warning in NetBeans??? You need to increase the size of receive buffer.

WARNING: receive buffer of socket java.net.DatagramSocket@49cfbdab was set to 20MB, but the OS only allocated 3.36MB. This might lead to performance problems. Please set your max receive buffer in the OS correctly (e.g. net.core.rmem_max on Linux)
Oct 10, 2012 2:36:08 PM org.jgroups.logging.JDKLogImpl warn
WARNING: receive buffer of socket java.net.MulticastSocket@65ad4b68 was set to 25MB, but the OS only allocated 3.36MB. This might lead to performance problems. Please set your max receive buffer in the OS correctly (e.g. net.core.rmem_max on Linux)


Even though, you can ignore this warning, as suggested by NetBeans it is better to handle it. I am using a MAC OS X. So the changes to max buffer will be done via the Terminal.

The Steps are shown below.

Open Terminal.

supz:~# sudo nvram boot-args="ncl=131072"

supz:~# sudo shutdown -r now

After the restart, enter the following lines shown below.

supz:~# sudo sysctl -w kern.ipc.maxsockbuf=33554432

kern.ipc.maxsockbuf: 8388608 -> 33554432

supz:~# sudo sysctl -w net.inet.udp.recvspace=16777216

net.inet.udp.recvspace: 42080 -> 16777216

MAC OS X - InetAddress.getLocalHost() throws UnknownHostException

I am currently looking at some socket programming code which works in windows, but not in MAC OS X 10.7. I am using JDK 1.7. Previously this worked well in JDK 1.6.

The issue is with InetAddress.getLocalHost()
it throws java.net.UnknownHostException when I used with getHostAddress or getHostName.

The workaround is, edit host files.

Open Terminal and type the line shown below to edit in etc/hosts.
sudo nano /private/etc/hosts

Enter password.

In etc/hosts, (use arrow keys to move around) add a new line with  IP address <space> and hostname

Here, you can get the hostname by typing 'hostname' in terminal

To save control+o, then enter and to exit control+x

Now back in terminal, flush the cache by
dscacheutil -flushcache

Now, there should not be any error.

Sometimes you get both hostname and IP with getLocalHost(). Therefore, from getLocalhost() extract only the substring with the IP.

Steps are:

  1. First convert the inetAddress you get with getLocalHost to String. 
  2. Then get the substring with the IP (Original String will be in the form of <host_name>/<IP>) e.g. String ip_addr
  3. Convert back the IP substring to inetAddress to be used in Socket. InetAddress.getName(ip_addr)

More information @ http://java.net/jira/browse/MACOSX_PORT-564