Prepare yourself for Java-based entertainment For nearly 10 years, I’ve developed Java programs for the IT industry, written articles and books on Java, answered many Java-related questions, and taught Java to lots of students. Although I’ve worked hard learning, programming, and teaching Java, I’ve also had fun with this technology.Java Fun and Games shares some of the pleasure I’ve experienced while playing with Java. Each installment focuses on a specific topic that I’ve found to be entertaining and presents one or more Java programs I created while exploring that topic. As you journey through Java Fun and Games, you’ll encounter topics that range from dragging a checker around a checkerboard to creating sophisticated 3D particle systems. I hope you enjoy the journey.Because of my fondness for computer games, I’ll emphasize them in this column. In addition to presenting my own entertainment topics, I’d like to explore topics important to you. Feel free to suggest a topic you would like to see covered and I will consider it.Modus operandiEach installment will present one or more programs in the form of Java applets. (I have nothing against applications—I just want to focus on applets.) I use J2SE 1.4 to compile (via javac) the applet’s source code and run (via appletviewer) the applet’s executable code.For the most part, I won’t use a Web browser to run applets. If you want to run an applet in a Web browser, make certain your browser supports J2SE 1.4 (or a more recent version). For example, if you are using Version 6.0 of Microsoft’s Internet Explorer, select the Use Java 2 v1.4.0 for (or equivalent) checkbox. That way, Internet Explorer will use Java Plug-in 1.4 (or a more recent version) instead of its internal JVM when it encounters the <applet> tag. If you cannot access Java Plug-in from your Web browser, you will probably need to create Java 1.x-compatible classfiles (assuming the source code doesn’t contain Java features newer than Java 1.x, and assuming you are accessing built-in virtual machines that don’t recognize classfiles newer than version 1.x). Create Java 1.x-compatible classfiles by compiling their source codes with javac’s target option, as follows: javac -target 1.1 ClassName.java In the command line above, -target 1.1 tells javac to create a classfile compatible with Java 1.1 (which should be recognized by most built-in virtual machines). Also, ClassName.java is just a placeholder for the applet’s source file.Break out of the sandboxSome applets will need to access the filesystem (to read/save game stats, for example). The JVM’s security manager forbids this kind of activity. However, there are two techniques for getting around this: one technique for appletviewer and one technique for a Web browser. Before I discuss these techniques, examine Listing 1’s FileIO.java source code. Listing 1. FileIO.java // FileIO.javaimport java.awt.*; import java.awt.event.*;import java.io.*;public class FileIO extends java.applet.Applet { private static String FILENAME = "stats.dat"; private String name; private int score; public void init () { // Create status TextArea component. final TextArea taStatus = new TextArea (10, 40); // Create a Panel for organizing Button components. Panel p = new Panel (); // Create a Load Button that loads game stats. Button btnLoad = new Button ("Load game stats"); // Establish a file-loading action listener. btnLoad.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent e) { DataInputStream dis = null; try { FileInputStream fis; fis = new FileInputStream (File.separator +FILENAME); dis = new DataInputStream (fis); name = dis.readUTF (); score = dis.readInt (); taStatus.setText ("name = " + name + ", " + "hi score = " + score); } catch (IOException e2) { taStatus.setText (e2.toString ()); } finally { if (dis != null) try { dis.close (); } catch (IOException e2) { taStatus.setText (e2.toString ()); } } } }); // Add Load Button to Panel. p.add (btnLoad); // Create a Save Button that saves game stats. Button btnSave = new Button ("Save game stats"); // Establish a file-saving action listener. btnSave.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent e) { DataOutputStream dos = null; try { FileOutputStream fos; fos = new FileOutputStream (File.separator + FILENAME); dos = new DataOutputStream (fos); dos.writeUTF ("John Doe"); dos.writeInt (50000); taStatus.setText ("Name and " + "score saved"); } catch (IOException e2) { taStatus.setText (e2.toString ()); } finally { if (dos != null) try { dos.close (); } catch (IOException e2) { taStatus.setText (e2.toString ()); } } } }); // Add Save Button to Panel. p.add (btnSave); // Set applet's layout manager to BorderLayout. setLayout (new BorderLayout ()); // Add Button panel to north region of applet. add (p, BorderLayout.NORTH); // Add status TextArea to south region of applet. add (taStatus, BorderLayout.SOUTH); } } Listing 1 describes a simple applet that demonstrates file I/O in an applet context. When a user clicks the Save Game Stats button, the applet saves a name and score to a data file. When the user clicks Load Game Stats, the applet loads the previously-saved name and score from the data file. With either button click, information appears in a status text area. Compile FileIO.java by invoking the command line below: javac FileIO.java Assuming successful compilation, you’ll end up with three classfiles: FileIO.class, FileIO.class, and FileIO.class. Before you can execute FileIO.class (the main classfile), you need an HTML file with an appropriate <applet> tag. To save you the bother of creating your own HTML file, I’ve prepared FileIO.html: Listing 2. FileIO.html <applet code=FileIO.class width=250 height=250> </applet> Policy filesExecute FileIO.class with appletviewer FileIO.html. The applet appears. Try clicking the Load Game Stats and Save Game Stats buttons. In response, you’ll notice a security exception: attempting to read or write a file from an applet is a violation of an applet’s default security policy. However, appletviewer’s default security policy does allow applets, loaded from a CODEBASE with file as the protocol, to read files in the CODEBASE directory (and subdirectories of this directory) and avoid a security exception—FileIO can only avoid the security exception during a file read if this applet is started from the root directory because the path passed to the FileInputStream constructor begins with File.separator. To prevent this exception, first create a policy file that grants all permissions to FileIO. Listing 3’s my.policy file does just that:Listing 3. my.policy grant { permission java.security.AllPermission; }; Now tell the JVM to recognize this policy file when appletviewer runs. The following command line accomplishes this task: appletviewer -J-Djava.security.policy=my.policy FileIO.html If all goes well, you should see an applet window similar to what is shown in Figure 1. Caution Granting all permissions to an applet is serious business. Unless you or a trusted friend created the applet, it’s not a good idea to grant all permissions to that applet. Signed jar filesThe policy file technique does not apply to Web browsers. Before you can execute FileIO in a Web browser, you first store that applet’s classfiles in a jar file and digitally sign that jar file.Signing a jar file requires a certificate. Although you can purchase a certificate when you want to distribute an applet commercially, I will show you how to create a free self-signed certificate (which you only use for testing). Complete the following steps to create a jar file, to create a self-signed certificate, and to sign that jar file with the certificate:Create the jar file: Execute jar cvf FileIO.jar *.class. You end up with a FileIO.jar jar file.Create a new key in a new keystore: Execute keytool -genkey -keystore myKeyStore -alias me. Alias “me” is arbitrary. It reminds you that the certificate based on the keystore is self-signed so you don’t accidentally put it into production.The keytool prompts you for information about the new key: It asks you for a password to protect the keystore. Then it asks you for your name, department, organization, city, region, and country. This information will go into the new keystore file—myKeyStore, in this example.Create a self-signed test certificate based on the keystore: Execute keytool -selfcert -alias me -keystore myKeyStore. Enter the keystore password when prompted.Sign the jar file with the testing certificate: Execute jarsigner -keystore myKeyStore FileIO.jar me. Enter the keystore password when prompted.The jarsigner program updates the jar file’s META-INF directory to contain certificate information and digital signatures for each entry in the archive. If all goes well, you end up with a signed FileIO.jar file.Note I recommend studying the tools documentation section of the J2SE documentation to learn more about jar, keytool, and jarsigner. Before executing the applet in a Web browser via the signed jar file, create an appropriate HTML file whose <applet> tag includes an archive attribute identifying the jar file. Listing 4’s FileIO2.html should do nicely. Listing 4. FileIO2.html <applet archive=FileIO.jar code=FileIO.class width=250 height=250> </applet> It’s time to execute the applet. Assuming FileIO.jar and FileIO2.html are located in the c:temp directory on a Windows machine, start the Web browser and enter c:tempFileIO2.html into that browser’s address bar. After a few moments, a dialog box should appear. That dialog box, as shown in Figure 2, presents a security warning and asks you to grant permission to run the applet.Figure 2. The Java Security Warning dialog box identifies a signed applet. Click on thumbnail to view full-sized image.Click either the Grant This Session button or the Grant Always button to proceed. If you’re curious, click the View Certificate button to view the details of the self-signed certificate that you previously created. Figure 3 shows the applet embedded in the Firefox browser. ReviewGet ready for a journey into my world of Java-based entertainment. Each installment of Java Fun and Games focuses on a specific topic that I’ve found to be entertaining, and presents one or more Java programs I created while exploring that topic. Those programs take the form of applets. Some of the applets will need to access the filesystem (to read/save game stats, for example). Because filesystem access is forbidden by the JVM’s security manager, policy files and signed jar files are required to circumvent security concerns. Use policy files to run file-access applets with appletviewer. But to run them in a Web browser, used signed jar files.Next time, I will show you how to drag a checker around a checkerboard.Jeff Friesen is a freelance software developer and educator specializing in C, C++, and Java technology. JavaSoftware DevelopmentComputers and PeripheralsTechnology Industry