A JWS Installer for BugRunnerBugRunner is a basic 2D arcade game (see Chapter 11. I'll work with the version that uses the J3DTimer class, which means the deployment file must install the relevant Java 3D library. I can't assume it's present on the user's machine. Write the ApplicationThe installer version of the application shouldn't rely on nonstandard extensions or native libraries being present on the client machine. However, BugRunner uses the Java 3D timer, which is part of the Java 3D extension. The OpenGL Windows version of Java 3D is implemented across seven files:
Only j3dutils.jar and J3DUtils.dll are needed for the timer functionality as explained in Appendix A. They should be placed in the BugRunner/ directory to be locally accessible to the application. Java 3D should not be installed on your test machine. Figure B-1 shows the BugRunner/ directory prior to compilation. It contains all the Java files (unchanged from Chapter 11), j3dutils.jar, and J3DUtils.dll. The batch files are optional but reduce the tedium of typing long command lines. Since Java 3D isn't installed in a standard location checked by javac and java, the calls to the compiler and JVM must include additional classpath information. The compileBR.bat batch file contains this line:
The BugRunner.bat batch file has this:
There's no need to mention J3DUtils.dll, which will be found by the JAR as long as it's in the local directory. Once the program has been fully debugged, it should be packaged as a JAR. The BugRunner application consists of various classes, and the subdirectories Images/ and Sounds/. These should be thrown together into a single BugRunner.jar file. The makeJar.bat batch file contains the line:
Figure B-1. The BugRunner/ directoryThe manifest details in mainClass.txt are:
The manifest specifies the class location of main( ) and adds j3dutils.jar to the classpath used when BugRunner.jar is executed. This setup assumes that it's in the same directory as BugRunner.jar.
The application now consists of three files: BugRunner.jar, j3dutils.jar, and J3DUtils.dll. These should be moved to a different directory on a different machine and tested again. Double-clicking on BugRunner.jar should start it running. Alternatively, type:
Modify the Application for DeploymentSince the native library J3DUtils.dll is utilized by BugRunner, two tasks must be carried out. The DLL must be placed inside its own JAR:
The main( ) method of BugRunner, in BugRunner.java, must be modified to call System.loadLibrary( ) for each DLL:
The checking of the os.name property string gives the program a chance to report an error if the application is started by an OS that doesn't support the library. This coding style also allows the application to load different libraries depending on the OS name. For instance:
These changes to BugRunner.java mean it must be recompiled and re-JARed:
Create a Public/Private Keypair for Signing the ApplicationThe digital signing of a JAR requires two of Java's security tools: keytool and jarsigner. They're described in the security tools section of the J2SE documentation in <JAVA HOME>/docs/tooldocs/tools.html#security. keytool generates and manages keypairs, collected together in a keystore. Each keypair is made up of a public key and private key, and an associated public-key certificate. A simplified diagram showing a typical keypair is shown in Figure B-2. Figure B-2. The elements of a keypairThe two keys can be used to encrypt documents. Something encrypted with a private key can only be decrypted with the corresponding public key; if the encryption uses the public key, then only the private key can unlock it. The intention is that the public key is widely distributed, but users keep their private key secret. Determining the private key from examining the public key is impossible. A message sent to users can be encrypted with the public key, so only they can read it by applying their private key. A message from users to another person can be encrypted with the private key. The fact that the user's public key can decrypt the message means that it must have come from that user. The private key is being used as a digital signature. One of the problems with the public/private keys approach is how to distribute a public key safely. For instance, if I receive an email from "Stan Lee" giving me his public key, how do I know that it is from the famous Atlas/Timely editor? This is where the public-key certificate comes into play. A certificate is a digitally signed statement from a third party, perhaps my respected friend "Alan Moore," that is "Stan Lee's public key." Of course, the question of authenticity still applies, but now to the "Alan Moore" signature, which can be combated by signing it with the certificate of yet another person. This process leads to a chain of certificates, ending with a certificate that can be proved genuine in some unforgeable way (for example, by visiting the person and asking them). Whenever keytool generates a new keypair it adds a self-signed certificate to the public key. In effect, all my public keys contain certificates signed by me saying they're genuine. This is useless in a real situation, but it's sufficient for these demos. You'll see that JWS issues a dire warning when it sees a self-signed certificate but will let it pass if the client gives the okay. I'll discuss how to obtain better certificates later in this appendix. A new keypair is written to the keystore called MyKeyStore by typing the following:
The user is prompted for the keystore password, a lengthy list of personal information, and a password for the new keypair (see Figure B-3). The keypair's alias (name) is BugRunner in this example, though any name could be used. Better passwords should be thought up than those used in my examples; a good password uses letters, numbers, and punctuation symbols, and should be at least eight characters long. The keystore's contents can be examined with this command:
Sign Everything with the Private KeyYou're ready to use the jarsigner tool to start signing the JARs in the BugRunner application. Figure B-4 presents a simple diagram of what jarsigner does to a JAR. Figure B-3. Generate a new keypairFigure B-4. A JAR file signed with jarsignerjarsigner digitally signs a JAR with a private key. A digital signature has many useful characteristics:
The actual mechanics of creating a signed JAR are simple:
This signs foo.jar using the BugRunner keypair stored in MyKeyStore. jarsigner will prompt the user for the keystore and keypair passwords. A variant of this is to create a new signed JAR file rather than modify the existing one:
This leaves foo.jar unchanged and creates a signed version called foo_signed.jar.
For the BugRunner application, there are three JARs: BugRunner.jar, j3dutils.jar, and J3DUtilsDLL.jar. The latter two are signed this way:
This process means yet another reJARing of BugRunner since the manifest information in mainClass.txt must be changed to reference the signed filenames:
The jar command in makeJar.bat is unchanged:
After BugRunner.jar is regenerated and then it's signed:
Create a Deployment FileThe deployment file for the BugRunner application, BugRunner.jnlp, is shown in Example B-2. Example B-2. JNLP deployment file for BugRunner
The URL codebase value is commented out at this stage; instead, use a path to the local development directory. The information tag contains two forms of textual description: a one-line message and a longer paragraph (confusingly labeled with the attribute value short). The icon and splash screen images are named; they should be located in the BugRunner directory. The icon is the default size of 32 x 32 pixels, but other sizes are possible and several icons with different resolutions can be supplied. GIF or JPEG images can be used. Unfortunately, transparent GIF are rendered with black backgrounds, at least on Windows. The offline-allowed tag states that the application can run when JWS detects that the network is unavailable. all-permissions security is used, which requires that all the JARs named in the resources section are signed. The resources will be downloaded only if the client-side OS matches the os attribute. There's also an optional arch attribute to further constrain the installation. For example, the following is able to retrieve any one of five different versions of j3daudio.jar depending on the OS and architecture:
It may seem rather silly to have five different JARs when their contents should be identical because they're coded in Java. In practice, however, this approach avoids incompatibles that may have crept into the different versions. More details on how the Java 3D libraries can be divided into multiple resource tags are given in the "Marc's Web Start Kamasutra" forum thread (http://forum.java.sun.com/thread.jsp?forum=38&thread=166873). The j2se version tag in BugRunner.jnlp specifies that any version of J2SE or JRE from 1.4.0 on can execute the application. JWS will abort if it detects an earlier version when it starts the program. It's possible to specify initial settings for the JRE when it starts and to trigger an automatic download of a JRE if the client's version is incompatible. The following tags illustrate these features:
BugRunner.jnlp specifies that three JARs should be retrieved:
BugRunner.jar contains the application's main( ) method and J3DUtilsDLL.jar holds the native library. The JARs must be in the same directory as the JNLP file and must be signed. The resources tag is considerably more versatile than this example shows. For instance, it's possible to request that resources be downloaded lazily. This may mean that a resource is only retrieved when the application requires it at runtime (but JWS may choose to download it at installation time):
Resources may be grouped together into parts and subdivided into extensions. Each extension is in its own deployment file. Property name/value pairs, which can be accessed in code with System.getProperty( ) and System.getProperties( ) calls may appear inside the resources section. For example:
The application-desc tag states how the application is to be called and may include argument tags:
The development guide in the J2SE documentation explains many of these tags (<JAVA_HOME>/docs/guide/jws/developersguide/contents.html). An extensive JNLP tag reference page is located at http://lopica.sourceforge.net/ref.html. Deployment testingDeployment testing should be carried out by moving the relevant files to a different directory on a different machine. For BugRunner, there are six files: BugRunner.jnlp
bug32.gif BRBanner.gif
BugRunner.jar j3dutils_signed.jar J3DUtilsDLL.jar
The chosen directory must match the one used in the codebase attribute at the start of the deployment file. Double-clicking on BugRunner.jnlp should initiate JWS and the installation process, which is shown in Figure B-5. Figure B-5. BugRunner installationThe dialog box in Figure B-6 appears at the point when the application should start executing. Since BugRunner has requested <all-permissions/> access and the digital signature uses a self-signed public-key certificate, then JWS reports that "it is highly recommended not to install and run this code." This sort of message is deeply worrying to novice users. It can only be removed if you replace the self-signed certificate by a third-party certificate as outlined at the end of this appendix. Clicking on Details will show information obtained from the certificate, or chain of certificates, attached to the JAR. Clicking on Exit will stop JWS without executing Figure B-6. Execute at your perilthe application. Start will start the application and, depending on how JWS is configured, add a BugRunner item to the Windows Start menu and a BugRunner icon to the desktop. For more details about the application and how to configure JWS the application manager should be started. Figure B-7 shows the manager for JWS 1.4.2. Figure B-7. The JWS 1.4.2. application manager
Place Everything on a ServerIt's time to move the following six BugRunner files to a server:
BugRunner.jnlp must be modified to have its codebase use the server's URL:
The BugRunner/ directory is placed below jws/, which holds a JWS portal page called index.html. The directory structure is shown in Figure B-8. Figure B-8. The server directories used for JWSThe portal page (loaded from http://fivedots.coe.psu.ac.th/~ad/jws/) appears as shown in Figure B-9. Clicking on the BugRunner link will cause the application to be downloaded, with JWS showing the same dialogs as in Figures B-5 and B-6. Before starting this phase of the testing, any previous client-side installation of BugRunner should be removed via the JWS application manager. |
Monday, January 11, 2010
A JWS Installer for BugRunner
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment