Installer problem on Mac OS 10.4?

I have a problem getting my Java installer to work on Macintosh. I used install4j. It installs my game alright, but when I try (actually my friend tried it, but he is not very computer savvy, so I am not able to get him to give me more information) to run it, it starts javaws, starts to load my game but gets stuck at the security screen where you have to accept the certificate. It somewhat just closes down??? The process dies and the game never starts?

Could somebody with a Mac try to get the game to work? Or at least able to tell me what is wrong? Why does it just close down after the certificate is accepted? What happens? I do not have a Mac with OS 10.4, so I cannot test it.

The download is here (it is just about 600kb and expects you to have java 1.5 installed):
http://www.aevumobscurum.com/original/download/AevumObscurum_Main_macos_V1.dmg

Don’t use an installer on Mac OS X. Make an Application Bundle.

Search on java.net or java.sun.com and I’m sure you will find the articles that explain how.

I think that’s what I did? install4j created a Mac OS X application bundle for me.

Is there anybody here with a macintosh that can help me out? Test it?

I can help test.
If the end users has to run an installer to create the application bundle then it still isn’t the “mac way”. The end user should simply have to mount a disk image or unzip the app and drag it to where they want it.

Yep, just checked the disk image and confirmed that it contains an installer app, not the game app. That’s not what you want.

Alright then! Thanks for the replay. Install4j lets me create 4 types of Macintosh “installers”:

  1. Mac OS X single bundle (.dmg)
  2. Mac OS X folder (.dmg)
  3. Mac OS X single bundle archive (.zip)
  4. Mac OS X folder archive (.zip)

Are you talking about 2./3./4. What I gave you was 1. Which one is the preferred way for Macintosh? Sorry for my ignorance, but I really like to get it to work for Macintosh ;D

Looks like Install4J is useless in this case for Mac… I expected as much. I’ve used other installers (InstallAnywhere) and they are basically the same. Total overkill for the Mac platform.

For most simple applications (anything that doesn’t need to install OS Hooks or configure other applications with plugins or system-wide shared libraries, etc.) you simply don’t want to have an installer at all on the Mac.

You want to distribute your application as a single folder that can be dragged and dropped onto the users hard drive, wherever they want it. That folder is laid out with a particular structure so that it is recognized by the OS as an Application Bundle. As such the Mac “Finder” will not navigate into the folder when it is double clicked, but will instead launch the application.

Here is a great article that tells you how to make Application Bundles:
http://java.sun.com/developer/technicalArticles/JavaLP/JavaToMac3/index.html

The only thing you need to make a complete bundle on any platform is a copy of the JavaApplicationStub file. Though technically you can work around that too if you use a shell script (embedded in the bundle inplace of JavaApplicationStub) to start your app.

Alright, one of the following should be it then? Can you let me know which one is the one?
http://www.aevumobscurum.com/original/download-tool/Test1.dmg
http://www.aevumobscurum.com/original/download-tool/Test2.tgz
http://www.aevumobscurum.com/original/download-tool/Test3.tgz

I would assume you are looking for Test1.dmg?

Test2.tgz is good.

Test1 is still an installer on a disk image… same as the original.

Test2 would be better if it was an Application Bundle in a disk image instead of tar’ed and zip’ed, but it’s better than an installer.

Test3 is messy - it has an app bundle, but then a bunch of files and directories outside of the app bundle. Normally things like the License.txt file would simply be beside the app bundle on the disk image so they can be read before dragging the bundle to the HD, but you don’t usually want to see anything other than an app bundle in you applications folder on a Mac, not a (non-bundle) subdirectory per app.

There are some other things to consider between #2 and #3 though… Non-admin users probably won’t have rights to write data to folders inside the app bundle… unless you do something clever. I’m not sure if have separate dirs like with #3 fixes that or not though. The “right” way to handle data that must be updated by the app is to write those files to ~/Library/Application Support/Your App Name/ (being in the user’s home folder those files would be per-user… /Library/Application Support/Your App Name/ would be used for system-wide data files. But there is also /Library/Caches/YourApp and ~/Library/Caches/YourApp … if you are just caching downloaded data or something.

As you can see there are a few options and it isn’t always clear which is best… I’m not sure which of those system-wide folders would be writable all the time for example. I think /Users/Shared is sometimes used for globally writable space.

Ah… I just launched the app and see that the bundle is really just a stub that launches the app via web start… maybe web start will handle all the details… Though I notice that after the stub has started the Web Start process you only see the Web Start icon in the dock, not your application’s icon. It seems to work though.

Thanks for all the hard work! I guess I will provide both the *.tgz file you suggested, as well as the previously mentioned installer. Let people choose.

My friend told me the game would not start using the installer. After he accepts the certificate, nothing happens. Do you have the same problem?

[quote]Ah… I just launched the app and see that the bundle is really just a stub that launches the app via web start… maybe web start will handle all the details… Though I notice that after the stub has started the Web Start process you only see the Web Start icon in the dock, not your application’s icon. It seems to work though.
[/quote]
Yes, it’s just a stub. That way, the game “updates” itself automatically! Just using the jnlp functionality rather than reinventing the wheel myself. The web start process should show the game icon, after the game window comes up. This does not happen?

That’s the code I use in case you are interested:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.JOptionPane;

/**
 * Allows to run a webstart application.
 *
 * @author  Christoph Aschwanden
 * @since  March 30, 2006
 */
public final class WebstartRunner {

  
  /**
   * Private to prevent instantiation of this class.
   */
  private WebstartRunner() {
    // does nothing.
  }
  
  /**
   * Runs the inputted jnlp file. 
   * 
   * @param jnlp  The location of the online jnlp to run.
   * @param localVersion  The version of the installer we are running to start the jnlp.
   */
  public static void run(String jnlp, int localVersion) {
    // find if OS is windows
    String osName = System.getProperty("os.name").toLowerCase();
    boolean windowsOS = osName.indexOf("windows") > 0;
    
    // find Java home directory
    String javaHome = System.getProperty("java.home");
    String fileSeparator = System.getProperty("file.separator");
    
    // set quoting style (windows only can use quotes)
    String quote = windowsOS ? "\"" : "";
    
    // check if version is still good
    String jnlpPath = jnlp.substring(0, jnlp.lastIndexOf("/") + 1);
    String requiredVersionFile = jnlpPath + "RequiredWebstartRunner.version";
    try {
      // find remote version
      URL url = new URL(requiredVersionFile);
      URLConnection connection = url.openConnection();
      BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      String line = reader.readLine();
      int remoteVersion = Integer.parseInt(line);
      
      // check if still valid
      if (remoteVersion > localVersion) {
        // tell newer version available
        JOptionPane.showMessageDialog(null
            , "A new version of the Aevum Obscurum game client is available!\n"
            + "Please go to http://www.aevumobscurum.com for information and download.\n"
            + "\n"
            + "\n"
            , "Aevum Obscurum: New Version Available."
            , JOptionPane.ERROR_MESSAGE);

        // need to redownload!
        System.out.println("Redownload of installer required. New version available");
      }
      else {
        // build list of commands
        String[] cmd = new String[2];
        cmd[0] = quote + javaHome + fileSeparator + "bin" + fileSeparator + "javaws" + quote;
        cmd[1] = jnlp;
        
        // set property!
        System.setProperty("runtime.start.method", "install4j");
        System.setProperty("runtime.start.version", "" + localVersion);
        
        // and execute command!
        try {
          Runtime.getRuntime().exec(cmd);
        }
        catch (IOException e) {
          System.err.println("Cannot start the webstart file (" + jnlp + "): " + e);
        }
      }
    }
    catch (IOException e) {
      // server down or file not found - connection cannot be established
      JOptionPane.showMessageDialog(null
          , "The connection to the Aevum Obscurum server could not be established.\n"
          + "Please try again later or go to http://www.aevumobscurum.com for further "
          + "information.\n"
          + "\n"
          + "We apologize for any inconvenience this might cause you.\n"
          + "\n"
          + "\n"
          , "Error Connecting to Aevum Obscurum Server"
          , JOptionPane.ERROR_MESSAGE);
      
      // output error to console
      System.err.println("IO exception (" + requiredVersionFile + "): " + e);
    }
  }
  
  /** 
   * The main method which will be called.
   *
   * @param args  The arguments for the webstart runner. 
   *              args[0] should be the location of the .jnlp file to run. 
   *              args[1] the version of the installer.
   */
  public static void main(String[] args) {
    run(args[0], Integer.parseInt(args[1]));
  }
}


No the game appeared to be working properly.

[quote][quote]Ah… I just launched the app and see that the bundle is really just a stub that launches the app via web start… maybe web start will handle all the details… Though I notice that after the stub has started the Web Start process you only see the Web Start icon in the dock, not your application’s icon. It seems to work though.
[/quote]
Yes, it’s just a stub. That way, the game “updates” itself automatically! Just using the jnlp functionality rather than reinventing the wheel myself. The web start process should show the game icon, after the game window comes up. This does not happen?
[/quote]
No. There is a generic webstart or Java icon left after the stub exits and Web Start has launched the game.

BTW, the icon graphic should be 128x128 for it to look it’s best on the Mac.