15. Finishing and Deploying Your Game

What We Will Cover


Illuminations

Questions from last class?

Questions about the final project?

15.1: Finishing Your Game

Learner Outcomes

At the end of the lesson the student will be able to:

  • State the most important requirement of your final game
  • Describe how you can prevent bugs in your code
  • Discuss how to detect and fix bugs in your code

15.1.1: The Last 10%

"The first 90% of a project takes 90% of the time, the last 10% takes the other 90% of the time."
-- Old Project Manager Saying

  • You will need to do lots of things to finish your game
  • These things include items such as:
    • More characters
    • More levels
    • More special effects
    • Splash screens
    • Menus and configuration settings
  • As you finish up, it is important to focus on the most important requirement: your games must work well
  • Before you start to add the extras, make sure your game feels solid and does not have any quirky behavior
  • Check all the user input options to make certain that the games responds correctly
  • If the user switches to another application in the middle of a game, you should pause the game
  • When the user exits the game, the game should actually exit
  • Eliminate all the bugs and quirky behavior that you can
  • If you cannot figure out a problem, you should get help from other students or from the instructor

Adding Special Visual Effects

  • Special effects can refine a game and add a "wow" factor
  • Some effects you might want to consider are:
    • Explosions
    • Flames
    • Lightning
    • Flickering lights
    • Rain, snow and other environment effects
    • More character animations such as running, stopping, standing ...
  • Also, you may want to consider making your game physics more realistic like we discussed previously

Adding Sound Effects

  • When polishing your game, do not forget to add plenty of sound effects
  • Sound effects are often only noticeable when they are missing
  • The sound effects you add depend on your game, of course
  • However, some of them you may need, or should think about, are listed below
  • These are only ideas to help you come up with your own checklist of sound effects
  • Once you have your list made up, use care in placing them in your game
  • Make sure you do not add so many simultaneous sounds that they are difficult to distinguish

Sound Effects Checklist

  • When the player character gets hurt (or dies)
  • When the player character jumps or falls
  • When the player scores some particular point
  • When a non-player character is hit or destroyed
  • When a lever is pulled or a door opens
  • When an item is picked up
  • When something flies by the player
  • When some background environment object should make a noise, like:
    • Humming machinery
    • Bubbling brooks
    • Crackling flames
    • Rustling wind
    • Chirping birds
    • Crashing waves
    • Dripping water
  • When you want to give the player hints, like a bad guy is about to fire a weapon
  • When the user is using controls, you may want to give feedback noises like clicks for button presses

Diminishing Returns

  • As you work on special effects, keep in mind that adding more effects has a diminishing return in entertainment value
  • This diminishing return is shown in the following diagram:

    From chapter 8: Chris Crawford on Game Design, by Chris Crawford

  • The first few effects, assuming that they add to the gameplay, are very rewarding
  • However, after a while it becomes just another gimmick

15.1.2: Making Your Game Work Well

  • Lets return the most important requirement: a robust and well-behaved game
  • The key to a game that works well is testing
  • You should write tests for each class (unit tests) and run your tests often
  • Make sure your tests cover as many cases and branches as you can

Unit Testing

  • One way to get good test coverage is to write unit tests
  • Unit tests are simple instructions that test your methods one at a time
  • Writing the tests often makes you think about whether the method is correct
  • When the method is correct and testable you have fewer bugs
  • When you change your method, you run the unit test to verify it still works correctly
  • More information:

Debugging

  • When you run tests, you will find programming errors
  • We all realize that there are three types of programming errors:
    • Syntax Errors
    • Run-time Errors
    • Logic Errors
  • Syntax errors are caught by the compiler and are the easiest to find and fix
  • However, we have to run the game to find the other types of errors
  • The hardest to find are the logic errors where we might make a mistake in the design or implementation
  • For example, our collision detection might not handle certain situations because we did not anticipate them in our design
  • Because we have to redesign part of the game, they are often the hardest to fix

15.1.3: Preventing Bugs

  • It may sound obvious, but the best way to debug is to not write bugs into your code
  • Being careful with your code and design can take less time than tracking down a strange bug or redesigning a section of your program
  • The following are some bug-prevention techniques that will help you limit the number of bugs you produce

Check Before Compiling

  • Do not “compile, run, and pray.”
  • When you write a section of code, check it over for anything you might have missed
  • Work through it by hand if you are not sure it will work
  • By preventing problems, you will spend much less time fixing bugs

Pay Attention to the API Documentation

  • Make sure you understand the specification of a method from the Java API
  • Check the parameters and make sure you pass in legal values
  • Check the values it returns and deal with them correctly
  • Check exceptions a method can throw and make sure your design can handle the exceptional situations
  • More information: Java API Specification

Write Readable Code

  • In general, you should write self-documenting code
  • Use meaningful and descriptive variable names
  • Ambiguous names are often a sign that you do not understand the code
  • Also, use constants rather than magic numbers
  • In addition, use indentations and format your code consistently
  • When code is formatted correctly, you can more easily spot errors
  • Use CheckStyle to verify your code is consistently formatted
  • More information:

15.1.4: Debugging Tips

  • While you can reduce the number of bugs you produce, you will eventually get bugs in your code
  • The following tips can help you fix them

Run from the Console

  • If you are getting exceptions, run from the console
    • Note that TextPad is set up to always run from the console
    • Most IDEs will show you the console output as well
  • Then look at the stack trace to find the exact line number of the bug
    • Most IDEs and editors will automatically jump to the line in error
    • For instance, with TextPad you just need to double-click the error message to jump to the reported problem in the code
  • Make sure you always fix the first bug in the list
  • Often the first error or warning causes all the rest of the errors and warnings
  • Reading any error or warning beyond the first may be a waste of time

Use println() Debugging

  • Using println() for debugging is a quick and easy way to narrow down the location of a bug
  • You add println() statements to the suspect area to display the values of the variables you are working with
  • By examining the values the variables contain, you can tell if there is a problem and deduce the cause of a problem

Print a Stack Trace

  • You may have noticed the following code pattern in my examples:
  • try {
        // ... code under test
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    
  • The reason for the e.printStackTrace() is to show how the code arrived at its current place
  • You can use the stack trace to determine what methods calls led up to the current situation
  • It lets you go backwards and check parameters and variables in the current and preceding methods
  • You can add the same line of code to your exceptions if they get thrown
  • Or you can print a stack trace without throwing or catching anything
  • new Throwable().printStackTrace();

Check for Thread Deadlock

  • One of the problems that can occur when you use threads is a deadlock
  • Deadlock is a situation where two or more threads cannot continue because each is waiting on another to do something
  • If you suspect deadlock, run the game from the console and wait for the deadlock to appear
  • Once it appears, return to the console and enter Ctrl+break on Windows (or Ctrl+\ on Mac OS X and UNIX)
  • In the console your will see the state of the threads, any locks acquired, and any deadlock detected
  • To show how the deadlock detection works, we can try to create a deadlock scenario using the Deadlock example from the Java Tutorial
  • After compiling the program, run it in a console window
  • If the program deadlocks as planned, then press Ctrl+break on Windows (or Ctrl+\ on Mac OS X and UNIX)
  • You will see a full thread dump from the JVM
  • If you do not get the example to deadlock, then you can run your game from the console and press Ctrl+break on Windows (or Ctrl+\ on Mac OS X and UNIX)
  • This will give you an example listing though you will not see the deadlock detector actually work
  • For more information on deadlock, see: Deadlock from Wikipedia

Learn to Use a Debugger

  • A debugger is a tool that lets you step though your source code one line at a time
  • While you step through the code, you can examine and change variables
  • Debuggers let you set breakpoints, which stops program execution and starts the tracing when a certain point is reached
  • They also have ways to examine threads and thread state
  • Debuggers may take a few hours to learn, but can save time in the long run if you do a lot of coding
  • IDEs have a debugger built in, which is one of their big attractions
  • If you do not use an IDE, I recommend the free graphical debugger: JSwat
  • If you prefer a command line interface, you can use the jdb debugger supplied with the JDK
  • For more information on using jdb, see:

Other Debugging Information

15.1.5: Analyzing Performance Problems

  • As your applications grow larger, you may run into performance problems
  • For instance, your program may run too slowly
  • Or you may notice that your application becomes slower as it runs
  • These problems are caused by a lack of computing resources: CPU cycles or memory
  • As a rule of thumb, 90% of the time is spent in executing 10% of the code
  • Optimizing 90% of the code will have little impact on overall performance
  • To improve performance, you need to find and improve the bottlenecks

Using JConsole to Measure Resource Usage

  • The first step in determining your application's bottlenecks is to measure the resource usage
  • One good way you can check and monitor resources is to use the JConsole tool
  • JConsole is a GUI tool for monitoring your application resources
  • When you invoke JConsole, you can monitor:
    • CPU usage
    • Heap memory usage
    • Number of loaded classes
    • Number of threads
  • Also, you can perform some management functions like invoking garbage collection
  • To use JConsole, you start your application running
  • Then you start JConsole at a command prompt like:
    jconsole
  • Alternatively, you can find and double-click jconsole.exe in the JDK bin folder
  • Once started, you can determine if your performance issues are due to a shortage of CPU cycles, memory or threads

Finding Where the Application Spends its Time

  • If your bottleneck seems to be the CPU, then you need to find out where your application is spending its time
  • One way to measure application time is to use a profiler
  • A profiler measures the frequency and duration of method calls as your program runs
  • This lets you find code bottlenecks by looking at the methods that take the most time overall
  • Sun provides a profiling tool with the JDK named hprof
  • You start hprof at a command prompt using a command like:

    java -agentlib:hprof=cpu=samples,depth=10,thread=y GameManager

    Where GameManager is the name of the class with the main() method that starts your program
  • Also, you can run hprof on a JAR file using a command like:

    java -agentlib:hprof=cpu=samples,depth=10,thread=y -jar hazardapp.jar

  • After your program starts, run it for awhile and then exit
  • hprof produces an output file named java.hprof.txt
  • You can look at this file in a text editor or you can use a graphical program like PerfAnal
  • Just download the PerfAnal jar file and start it with a command like:

    java -jar PerfAnal.jar java.hprof.txt

Finding Memory Leaks

  • If your applications becomes slower the longer it runs, your application may have a memory leak
  • Using Java, you do not have to directly manage memory allocation and deallocation
  • Instead, programs use the new operator to allocate objects on the heap
  • When an application no longer references an object, the JVM removes it using a process known as garbage collection
  • If your application tries to hold onto too many objects at one time, it can fill up the heap
  • For instance, you may have a method that adds objects to list or map, but forget to remove objects after you process them
  • When the heap gets completely full, your program throws an OutOfMemoryError
  • This is shown in the following example:
1
2
3
4
5
6
7
8
9
10
import java.util.*;

public class MemoryLeak {
    public static void main(String[] args) {
        List<Integer> l = new ArrayList<Integer>();
        for(int i=0; i<100000; i++) {
            l.add(new Integer(i));
        }
    }
}
  • Even if the heap does not completely fill, garbage collection can take longer when large numbers of objects are created and released
  • JConsole will show you if your application is leaking memory
  • If the memory graph rises steeply at some point and does not go back down to the same level when you press the Perform GC button, you probably have a memory leak
  • To track down the parts of your code leaking memory you can use hprof with a command like:

    java -agentlib:hprof=heap=dump,format=b,depth=10 GameManager

    Where GameManager is the name of the class with the main() method that starts your program
  • This command produces a binary file named java.hprof
  • To analyze the binary file, you use a program named jhat (Java Heap Analysis Tool)
  • The jhat program resolves the "snapshot" created by hprof and starts a local server application on port 7000
  • You then use a browser to examine the files by entering the address:
    http://localhost:7000
  • You will see a list of packages and class with some "Other Queries" at the bottom of the page
  • The Heap Histogram will list the objects on the heap and how much memory they use
  • You can follow the hyperlink and drill down to the instances (with or without subclasses)
  • If you drill down far enough, you can see the actual data in the objects and the stack trace of where they were allocated
  • In addition, you can look at instance counts for all your classes (with or without the platform libraries)
  • You can even create custom queries using Object Query Language (OQL)
  • When finished, type Ctrl-C to stop the jhat server

More Information

15.1.6: Summary

  • You will need to do many things to finish your game such as
    • More characters
    • More levels
    • More special effects
    • Splash screens
    • Menus and configuration settings
  • Special visual effects add to the overall game as well, such as:
    • Explosions
    • Flames
    • Lightning
    • Flickering lights
    • Rain, snow and other environment effects
    • More character animations such as running, stopping, standing ...
  • Also, you want to make your game physics look realistic like we discussed previously
  • One thing you will need in your game is plenty of sound effects
  • Oftentimes, sound effects are often only noticeable when they are missing
  • We went through some sounds effects possibility to help you determine what you need
  • However, keep in mind that while the first few effects add immensely to the game, but at some point you get a diminishing return
  • As you finish your game, it is important to focus on the most important requirement: your games must work well
    • Bugs are what generally take the "other 90% of the time"
  • The best way to produce bug-free code is to avoid writing bugs in the first place
  • We looked at some techniques for avoiding bugs, including:
    • Checking before compiling
    • Paying attention to the API documentation
    • Writing readable code
    • Writing tests and testing your code often
  • While you can reduce the number of bugs you produce, you will eventually get bugs in your code
  • We looked at some debugging tips and techniques including:
    • Running from the console
    • Using println() debugging
    • Printing a stack trace
    • Checking for thread deadlock
    • Learning to use a debugger
  • In addition, we looked at how to analyze performance problems

Check Yourself

  1. What is the most important requirement of your final game?
  2. How do you prevent bugs in your code?
  3. What are some techniques you like for finding the source of bugs in your code?
  4. What are some debugging techniques that you like to use?

Exercise 15.1

Take one minute to review the Check Yourself questions. We will review the questions after you are ready.

15.2: Deploying Your Game

Learner Outcomes

At the end of the lesson the student will be able to:

  • Deploy your games in a number of different ways
  • Discuss the pros and cons of deploying your game in various ways

15.2.1: Deployment Options

  • When you deploy your game, you want to make it as easy as possible for people to download and install
  • You want to let everyone who wants to play your game have an opportunity to do so
  • Java has a number of ways to deploy games, including many that are designed for deployment over the web
  • They include:
    • Desktop Applications
    • Executable JAR files
    • Application installers
    • Java applets
    • Java Web Start
  • We will look at these deployment options in the following sections

15.2.2: Creating a Well-Behaved Desktop Application

  • The most straight-forward way of deploying a game is as a desktop application
  • However, we want our desktop application to be well behaved standard window features like minimize and maximize buttons
  • In addition, we want features such as:
    • Pausing the game when minimized or not the active window
    • Turning off the sound when the game is not active
  • We will look at how to implement these features in this section

Creating the Application Container

  • To start with, we need to develop an application container for our game
  • As usual, we extend JFrame as the application container
  • Then we add our GameManager canvas to the application container
  • import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class HazardApp extends JFrame {
        public static final int WIDTH = 800, HEIGHT = 600;
        private static GameManager gm = GameManager.INSTANCE;
    
        public static void main(String[] args) {
            HazardApp frame = new HazardApp();
            gm.setPreferredSize(new Dimension(WIDTH, HEIGHT));
    
            frame.add(gm);
            frame.pack();
    
            gm.initGraphics();
            frame.setVisible(true);
            gm.startGame();
        }
        // More code to be added here
    }
    
  • We use an external game container so we can run our game in other containers as well
  • For example, we already run our game in Full-Screen Exclusive Mode (FSEM)
  • Later, we will look at how to run our game as an applet
  • Because our GameManager is a Canvas subclass, we will be able to run in any of these ways with no changes other than the game container

Exiting the Application

  • We will add several controls to our game so the user can exit
  • However, with an application, the user can press the X-button in the upper right-hand corner
  • The problem is that our game may be in the middle of its rendering operation when the user clicks the button
  • Graphics g = null;
    try {
        g = strategy.getDrawGraphics();
        draw(g);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        g.dispose();
    }
    
  • We should dispose of the graphics context before we exit the game
  • In addition, we want to pause the game if the window loses focus
  • Thus, we can no longer use the JFrame method:
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
  • Instead, we need to intercept the window-closing event and stop the game gracefully
  • To intercept the window closing event, we use the WindowListener interface
  • The WindowListener interface has seven methods as shown in the list below
  • We need to implement 3 of the 7 methods of the WindowListener interface
  • We could code all seven methods or use a WindowAdapter class
  • However, to save effort we can chose to subclass WindowAdaptor and override the 3 methods we are interested in using inside an inner class
  • The three methods we need to implement are shown in the WinHandler inner class shown below
  • private class WinHandler extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            gm.mute();
            gm.stopGame();
        }
    }
    
  • When the WindowClosing() method get called, we know that we need to shut down the game

Deactivating the Game

  • When the game window is not active, like when covered by anther window, we need to deactivate our game
  • We can do this using the window events as shown in this code:
    private class WinHandler extends WindowAdapter {
        // ...
    
        public void windowActivated(WindowEvent e) {
            gm.setPaused(false);
            gm.requestFocusInWindow();
            gm.unmute();
        }
    
        public void windowDeactivated(WindowEvent e) {
            gm.mute();
            gm.setPaused(true);
        }
    }
    
  • When the windowDeactivated() method gets called, we know we need to pause the game
  • Similarly, we need to resume the game when the windowActivated() method gets called
  • In addition, we need to request the focus for our game upon activation
  • When pausing, we need to mute any sound effects and music
  • Thus, we will need to add methods to the GameManager for muting and unmuting sounds:
    public void mute() {
        soundMuted = true;
        midiPlayer.setPaused(true);
    }
    
    public void unmute() {
        soundMuted = dialog.isSoundMuted();
        midiPlayer.setPaused(dialog.isMusicMuted());
    }
    
  • The complete code for our application container is listed below
  • Also, you can follow the link to see the updated GameManager

Methods of the WindowListener Interface

Method Description
windowActivated(WindowEvent e) Invoked when the Window is set to be the active Window.
windowClosed(WindowEvent e) Invoked when the Window is closed by calling dispose.
windowClosing(WindowEvent e) Invoked when the user attempts to close the window.
windowDeactivated(WindowEvent e) Invoked when a Window is no longer the active Window.
windowDeiconified(WindowEvent e) Invoked when a window is changed from a minimized to a normal state.
windowIconified(WindowEvent e) Invoked when a window is changed from a normal to a minimized state.
windowOpened(WindowEvent e) Invoked the first time a window is made visible.

HazardApp to Run a Well-Behaved Game

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class HazardApp extends JFrame {
    public static final int WIDTH = 800, HEIGHT = 600;
    private static GameManager gm;

    public static void main(String[] args) {
        HazardApp frame = new HazardApp();
        gm = new GameManager();
        gm.setPreferredSize(new Dimension(WIDTH, HEIGHT));

        frame.add(gm);
        frame.pack();

        gm.initGraphics();
        frame.setVisible(true);
        gm.startGame();
    }

    public HazardApp() {
        super("Student Hazards");
        addWindowListener(new WinHandler());
    }

    private class WinHandler extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            gm.mute();
            gm.stopGame();
        }

        public void windowActivated(WindowEvent e) {
            gm.setPaused(false);
            gm.requestFocusInWindow();
            gm.unmute();
        }

        public void windowDeactivated(WindowEvent e) {
            gm.mute();
            gm.setPaused(true);
        }
    }
}

Class GameManager with Methods for Muting Sounds

15.2.3: Executable JAR Files

  • Once you have an application container, you can package your game in an executable JAR file
  • A JAR file is the Java version of the Windows Zip file or the UNIX TAR/ZIP file
  • A JAR file lets you bundle multiple files into one single archive file
  • In addition, if a modern version of Java is installed on the users machine, the JAR will run by double-clicking under Windows
  • Thus, you can deploy your game as an executable JAR file
    • This is what you turn in to WebCT, among other things
  • One downside is that it is not obvious that the JAR file is executable
  • You can get around this problem easily by using a native-executable wrapper described below

Native-Executable Wrappers

  • A wrapper is a small native program that loads the JVM and then runs your program
  • You can code your own wrapper or use a third-party wrapper
  • Some free third-party wrappers (in no particular order) are:
  • Some wrappers have GUI interfaces for setup and some use only the command line
  • A wrapper usually starts by looking up the JRE
  • If the JRE is not present, some versions will install one if you included it in the wrapping
  • In addition, some wrappers will check for valid versions of the JRE

Adding a Splash Screen

  • Java 6 added the ability to display splash screens on start up
  • You can display a splash screen by updating the JAR file manifest:
    Manifest-Version: 1.0
    Main-Class: HazardFullScreen
    SplashScreen-Image: splash.jpg
    
    
  • Do not forget to include a blank line at the end of the file!
  • Then you create the JAR file using something like:

    jar -cvmf manifest-full.txt hazardfull.jar *.class images music soundFX splash.jpg

  • The advantage of adding the splash screen to the manifest is that the JAR can still work with Java 5
  • Java 5 will just ignore the unrecognized manifest entry
  • However, to run on Java 5, you will need to compile your game using a target of Java 5:
    javac -target 5 *.java
    

Executable JAR Files

More Information

15.2.4: Application Installers

  • A step above an executable wrapper is an installer program
  • An installer can install your application, create shortcuts and manage updates
  • You can either write your own installer or use an installer-generator program
  • Installer-generator programs include commercial programs like:
  • Free alternatives include:
  • Note that jelude, listed in the executable wrappers section, is an NSIS script

Java Aware Installer Generators

  • If you want an installer that will do more than the basic functions, you should look at those that are Java aware
  • A Java-aware installer-generator program potentially adds these benefits:
    • Install-time JRE detection and download
    • Generation of native-executable launchers
    • User-editable JVM parameter files
    • Redirection of stderr and stdout for saving logs and exception stack traces
    • Registration of Java applications as Windows services and Unix daemons
  • Java-aware installer-generators include InstallShield and InstallAnywhere listed above
  • Other commercial installer-generators that are Java-aware include:
  • Free Java-aware alternatives include:

More Information

15.2.5: Java Applets

  • Java applets are an easy way for someone to play your game
  • A user need only visit your web page and they can start playing
  • However, applets do have some potential problems and restrictions
  • The biggest problem with applets is that the user may not have a recent version of Java installed on their computer
  • To get around this, you can set up your applet HTML code to download the appropriate version
    • As long as the user agrees
  • Another problem is that applets have many security restrictions including:
    • Cannot read, write or delete files on the client system
    • Cannot run programs on the client system
    • Can only access a few properties of the client system such as:
      • Java version
      • Name of operating system
      • Version of operating system
      • Characters used to separate directories, paths and lines
    • Cannot make network connections to servers
      • Other than the one the applet was loaded from
  • Thus, you may need to recode parts of your game to get around these restrictions
  • However, you can package your game as a JAR file and the applet can read files from the JAR

Running Your Game as an Applet

  • If you decide to deploy your game as an applet, you will need an applet container class
  • The following code is a container for the example game
  • If you followed the specifications and created a GameManager class, it should work for your games with minor changes
  • In addition, you will need to create the appropriate HTML pages
  • If you are not familiar with creating applets, you should review the materials in More Information below
  • Also, shown below are links to two applet HTML pages showing the example game
  • You can modify these applets for your game

Class RunnerApplet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import javax.swing.*;

public class HazardApplet extends JApplet {
    private static GameManager gm;

    public void init() {
        gm = new GameManager();
        add(gm);
        gm.initGraphics();
    }

    public void start() {
        if (gm.isPaused()) {
            gm.setPaused(false);
        } else {
            gm.startGame();
        }
    }

    public void stop() {
        gm.mute();
        gm.setPaused(true);
    }

    public void destroy() {
        gm.stopGame();
        gm = null;
        System.gc();
    }
}

Applet HTML Pages

More Information

15.2.6: Java WebStart

  • Java Web Start is a deployment technology that can automatically download and install your games
  • All the users have to do is click a link on a web page, and the rest is automatic
  • If the Java Web Start engine is not present on the system, the user is prompted to download and install it
  • If you modify your game code, it downloads and installs the latest version
  • It is one of the easiest methods of game deployment

Steps for Deploying a Java WebStart Application

  1. After writing and testing the application, package it and all its resources as a JAR file.
  2. Create a public/private keypair for signing the JAR file.
  3. Sign the JAR file(s) with the private key.
  4. Create a deployment file (a JNLP file).
  5. Install the files and setup the server
  6. Test the installer on various client platforms, OSs, and browsers
    • Some of these test clients should NOT have JWS installed

Creating a Public/Private Keypair

  • The keytool generates and manages keypairs, which are collected together in a keystore
  • Each keypair is made up of a public key and private key, and an associated public-key certificate
  • You run the keytool from the command line using a command like:
  • keytool -genkey -keystore gamekeystore -alias Nobody
    
  • This creates a new key for the alias Nobody stored in the file gamekeystore
  • You are then prompted to enter a password and other information about yourself, including your name, organization, city, state, and country

Signing the JAR File

  • The jarsigner tool digitally signs a JAR with a private key
  • You run the jarsigner from the command line using a command like:

    jarsigner -keystore gamekeystore -signedjar hazardsigned.jar hazardfull.jar Nobody

  • If you do NOT want to preserve your original JAR file, you can shorten it like:

    jarsigner -keystore gamekeystore hazardfull.jar Nobody

  • The name of the new JAR can be anything you choose
  • Remember that you must sign all the JAR files for your game to use Java WebStart

Creating a JNLP File

  • After you have a signed JAR file, you need to create a JNLP (Java Network Launching Protocol) file
  • A JNLP file describes your game and what security permissions and resources (JAR files) it needs
  • You can see an example JNLP file listed below
  • The codebase is the path and the href is the name of the JNLP file itself
    • Note that the example uses a file:// codebase so the so the installation can be tested locally
    • You change this to the correct URL when installing on the server
  • The information tag lets you specify various data including two forms of textual description:
    • A one-line message
    • A longer paragraph (confusingly labeled with the attribute value short)
  • In addition, you specify the icon and splash-screen images using files like:
  • Any icon name is allowed and the image can be in either the GIF or the JPEG format
  • Both 32x32 and 64x64 versions of the icon are displayed but Java Web Start will resize the icon as needed
  • The splash screen is displayed while the application is loading
  • The offline-allowed tag states that the application can run when JWS detects that the network is unavailable
  • Permissions are set in the security tag, which you need for full-screen mode
  • The resources tag lets you specify the resources the game needs like the JAR files and Java version
    • The + sign specifies that you can use a later version as well
  • The application-desc tag lets you specify the main-class attribute
  • Note that JWS ignores the JAR manifest and you need to specify the main class in the JNLP file

Example JNLP Deployment File (hazard.jnlp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<jnlp
  spec="1.0+"
  codebase="http://www.edparrish.com/cs12gp/game/"
  <!--
  codebase="file:///C:/courses/cs12gp/game/"
  -->
  href="hazard.jnlp">
  <information>
    <title>Student Hazard's Game</title>
    <vendor>Edward Parrish</vendor>
    <homepage href="."/>
    <description>Student hazards's game</description>
    <description kind="short">
      A demo game for CS-12GP: Game Programming in Java
    </description>
    <icon href="icon.gif"/>
    <icon kind="splash" href="splash.jpg"/>
    <offline-allowed/>
  </information>
  <security>
      <!-- get all permissions so we can access
      fullscreen exclusive mode -->
      <all-permissions/>
  </security>
  <resources>
    <j2se version="1.5+" initial-heap-size="32m"/>
    <jar href="hazardsigned.jar"/>
  </resources>
  <application-desc main-class="HazardFullScreen"/>
</jnlp>

Setting Up the Web Server

  • You end up with the following files to place on the web server:
    • JNLP file (hazard.jnlp)
    • One or more digitally signed JAR files (hazardsigned.jar)
    • Icon file (icon.gif)
    • Splash screen file (splash.jpg)
  • You need to make sure the codebase in the JNLP matches the URL on the server
  • In addition, you need a web page that links to the file like this one: index.html
  • Once the files are installed, you still need to associate the JNLP files with the correct MIME type:
  • application/x-java-jnlp-file
  • This is required so that JWS can load the file instead of the web browser
  • If you are running your own web server, you probably know what to do
    • If not, you should the course CIS-164: Introduction to Managing and Securing a Web Server
  • If you have a shared hosting service, then check the documentation for adding MIME types or ask the web master to add it for you
  • If you cannot add the association in this way, then there is another solution for Apache web servers
  • You can place a file named .htaccess in the top directory of your web site that contains the line:
  • AddType application/x-java-jnlp-file .jnlp
  • It can be confusing to tell whether what you have changed is working
    • For instance, the browser usually puts the MIME response in cache
    • Thus you may need to clear the cache or restart the browser
    • An easier way is to run this program instead: GetContentType.java
  • You can enhance the Java Web Start in many other ways
  • For example, you can add JavaScript code to the web page to detect whether JWS is installed
  • Another example is to offer a one-click install of the Java runtime on Windows machines
  • How to do this is explained in the Creating the Web Page That Launches the Application which is part of the Java Web Start Guide

More Information

15.2.7: Summary

  • When you deploy your game, you want to make it as easy as possible for people to download and install it
  • Java has a number of ways to deploy games, including many that are designed for deployment over the web
  • We looked at the following techniques:
    • Desktop applications
    • Executable JAR files
    • Java Applets
    • Application installers
    • Java Web Start
  • Each technique has its own advantages and disadvantages
  • You need to chose the ones that are right for your game

Check Yourself

  1. What are the advantages and disadvantages of a windowed desktop application?
  2. What are the advantages and disadvantages of an executable JAR file?
  3. What are the advantages and disadvantages of Java applets?
  4. What are the advantages and disadvantages of application installers?
  5. What are the advantages and disadvantages of Java WebStart?
  6. Which deployment techniques seem like a good fit for your game?

Exercise 15.2

Take one minute to review the Check Yourself questions. We will review the questions after you are ready.

15.3: Finishing the Course

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss the final preparation for the project presentation
  • Advise the instructor on how to improve future courses

15.3.1: About the Final Project Presentation

Important Final Exam Information

Date and Time: 10:00am-12:50pm Wednesday, May 30 (change from posted)
Location: Room 2501 (regular classroom)

Before the Presentation

  • Submit your project to WebCT before the presentation:
  • Bring a written report on paper to give to the instructor before the presentation

Making the Presentation

  1. State your name and your project's name.
  2. Not everyone may know your name, especially our visitors. We all want to know both your name and your project's name.

  3. Briefly state your game concept.
  4. Pretend that you are presenting to a group of investors from whom you are asking for funds to further develop and market your game. You need to grab their attention in the first 30-45 seconds.

  5. Demonstrate your game, explaining aspects of the gameplay as you go.
  6. For example, you might give the storyline with the title screen. Then start the game and pause it often so you can explain important features. Point out as many of the cool features as possible so we can all enjoy them.

  7. Summarize the concept.
  8. When the game is over, or your time is up, then quickly summarize the game concept. Then pause for about 10 seconds to give us a chance to applaud!

Plan on keeping the game presentation to 10 minutes or less. Feel free to refer to or display your written report during the presentation.

After the Presentation

  • Feel free to leave (or stay) after your presentation
  • You can present to the instructor alone after the other presentations are through

15.3.2: Lecture Finale

  • During the semester we have covered many topics and learned much more about programming
  • With this knowledge we can develop some awesome games!
  • Your project will allow you to demonstrate what you have learned
    • There is no substitute for a working game!
  • I hope that everyone has enjoyed taking the course as much as I have enjoyed presenting it
  • I am always open to suggestions for improving the course

15.4: Open Lab

Learner Outcomes

At the end of the lesson the student will be able to:

  • Advance the state of their game project
  • At the end of the lecture, I will help students who want help on their game

Wrap Up

    Reminders

    Due Next: Final Project (5/30/07)

  • When class is over, please shut down your computer

Home | WebCT | Announcements | Schedule | Expectations | Course info
Help | FAQ's | HowTo's | Links

Last Updated: June 17 2007 @17:29:53