My stupid release 2002J For all the people which doesn’t have money to buy a good book Book Description The Java Cookbook is a comprehensive collection of problems, solutions, and practical examples for anyone programming in Java Developers will find hundreds of tried-andtrue Java "recipes" covering all of the major APIs as well as some APIs that aren't as well documented in other Java books The Java Cookbook, like the bestselling Perl Cookbook, covers a lot of ground, and offers Java developers short, focused pieces of code that can be easily incorporated into other programs The idea is to focus on things that are useful, tricky, or both The book includes code segments covering many specialized APIs like media and servlets and should serve as a great "jumping-off place" for Java developers who want to get started in areas outside of their specialization The book provides quick solutions to particular problems that can be incorporated into other programs, but that aren't usually programs in and of themselves Preface 11 Who This Book Is For 12 What's in This Book? 12 Platform Notes 14 Other Books 15 Conventions Used in This Book 17 Getting the Source Code 18 Acknowledgments 19 Chapter Getting Started: Compiling, Running, and Debugging 21 1.1 Introduction 21 1.2 Compiling and Running Java: JDK 22 1.3 Editing and Compili ng with a Color-Highlighting Editor 26 1.4 Compiling, Running, and Testing with an IDE 27 1.5 Using Classes from This Book 31 1.6 Automating Compilation with jr 32 1.7 Automating Compilation with make 33 1.8 Automating Compilation with Ant 34 1.9 Running Applets 36 1.10 Dealing with Deprecation Warnings 38 1.11 Conditional Debugging without #ifdef 40 1.12 Debugging Printouts 41 1.13 Using a Debugger 42 1.14 Unit Testing: Avoid the Need for Debuggers 44 1.15 Decompiling Java Class Files 46 1.16 Preventing Others from Decompiling Your Java Files 48 1.17 Getting Readable Tracebacks 49 1.18 Finding More Java Source Code 50 1.19 Program: Debug 52 Chapter Interacting with the Environment 53 2.1 Introduction 53 2.2 Getting Environment Variables 53 2.3 System Properties 55 2.4 Writing JDK Release-Dependent Code 56 2.5 Writing Operating System-Dependent Code 57 2.6 Using CLASSPATH Effectively 59 2.7 Using Extensions or Other Packaged APIs 61 2.8 Parsing Command -Line Arguments 62 Chapter Strings and Things 66 3.1 Introduction 66 3.2 Taking Strings Apart with Substrings 68 3.3 Taking Strings Apart with StringTokenizer 69 3.4 Putting Strings Together with + and StringBuffer 72 3.5 Processing a String One Character at a Time 73 3.6 Aligning Strings 74 3.7 Converting Between Unicode Characters and Strings 76 3.8 Reversing a String by Word or Character 78 3.9 Expanding and Compressing Tabs 79 3.10 Controlling Case 82 3.11 Indenting Text Documents 83 3.12 Entering Non-Printable Characters 85 3.13 Trimming Blanks from the End of a String 86 3.14 Parsing Comma-Separated Data 87 3.15 Program: A Simple Text Formatter 91 3.16 Program: Soundex Name Comparisons 93 Chapter Pattern Matching with Regular Expressions 96 4.1 Introduction 96 4.2 Regular Expression Syntax 98 4.3 How REs Work in Practice 100 4.4 Using Regular Expressions in Java 101 4.5 Testing REs Interactively 103 4.6 Finding the Matching Text 104 4.7 Replacing the Matching Text 105 4.8 Printing All Occurrences of a Pattern 106 4.9 Printing Lines Containing a Pattern 107 4.10 Controlling Case in match( ) and subst( ) 109 4.11 Precompiling the RE 109 4.12 Matching Newlines in Text 110 4.13 Program: Data Mining 112 4.14 Program: Full Grep 114 Chapter Numbers 118 5.1 Introduction 119 5.2 Checking Whether a String Is a Valid Number 121 5.3 Storing a Larger Number in a Smaller 122 5.4 Taking a Fraction of an Integer Without Using Floating Point 123 5.5 Ensuring the Accuracy of Floating-Point Numbers 124 5.6 Comparing Floating -Point Numbers 126 5.7 Rounding Floating-Point Numbers 127 5.8 Formatting Numbers 128 5.9 Converting Between Binary, Octal, Decimal, and Hexadecimal 130 5.10 Operating on a Series of Integers 131 5.11 Working with Roman Numerals 132 5.12 Formatting with Correct Plurals 136 5.13 Generating Random Numbers 137 5.14 Generating Better Random Numbers 138 5.15 Calculating Trigonometric Functions 139 5.16 Taking Logarithms 139 5.17 Multiplying Matrixes 140 5.18 Using Complex Numbers 142 5.19 Handling Very Large Numbers 144 5.20 Program: TempConverter 145 5.21 Program: Number Palindromes 149 Chapter Dates and Times 152 6.1 Introduction 152 6.2 Finding Today's Date 153 6.3 Printing Date/Time in a Specified Format 155 6.4 Representing Dates in Other Epochs 156 6.5 Converting YMDHMS to a Calendar or Epoch Seconds 157 6.6 Parsing Strings into Dates 157 6.7 Converting Epoch Seconds to DMYHMS 159 6.8 Adding to or Subtracting from a Date or Calendar 160 6.9 Difference Between Two Dates 161 6.10 Comparing Dates 162 6.11 Day of Week/Month/Year or Week Number 164 6.12 Calendar Page 165 6.13 High-Resolution Timers 167 6.15 Program: Reminder Service 170 Chapter Structuring Data with Java 172 7.1 Introduction 172 7.2 Data Structuring Using Arrays 173 7.3 Resizing an Array 174 7.4 Like an Array, but More Dynamic 176 7.5 Data-Independent Access with Iterators 177 7.6 Structuring Data in a Linked List 178 7.7 Mapping with Hashtable and HashMap 181 7.8 Storing Strings in Properties and Preferences 182 7.9 Sorting a Collection 184 7.10 Sorting in Java 1.1 188 7.11 Avoiding the Urge to Sort 189 7.12 Sets 190 7.13 Finding an Object in a Collection 191 7.14 Converting a Collection to an Array 193 7.15 Rolling Your Own Iterator 194 7.16 Stack 195 7.17 Multidimensional Structures 196 7.18 Finally, Collections 198 7.19 Program: Timing Comparisons 200 Chapter Object-Oriented Techniques 202 8.1 Introduction 202 8.2 Printing Objects: Formatting with toStri ng( ) 204 8.3 Overriding the Equals Method 205 8.4 Overriding the Hashcode Method 207 8.5 The Clone Method 209 8.6 The Finalize Method 211 8.7 Using Inner Classes 212 8.8 Providing Callbacks via Interfaces 213 8.9 Polymorphism/Abstract Methods 216 8.10 Passing Values 217 8.11 Roll Your Own Exceptions 220 8.12 Program: Plotter 220 Chapter Input and Output 224 9.1 Introduction 225 9.2 Reading Standard Input 229 9.3 Writing Standard Output 231 9.4 Opening a File by Name 232 9.5 Copying a File 233 9.6 Reading a File into a String 236 9.7 Reassigning the Standard Streams 237 9.8 Duplicating a Stream as It Is Written 238 9.9 Reading/Writing a Different Character Set 240 9.10 Those Pesky End-of-Line Characters 241 9.11 Beware Platform-Dependent File Code 241 9.12 Reading "Continued" Lines 242 9.13 Scanning a File 247 9.14 Binary Data 250 9.15 Seeking 251 9.16 Writing Data Streams from C 252 9.17 Saving and Restoring Serialized Objects 254 9.18 Preventing ClassCastExceptions with SerialVersionUID 255 9.19 Reading and Writing JAR or Zip Archives 257 9.20 Reading and Writing Compressed Files 260 9.21 Program: Text to PostScript 261 9.22 Program: TarList (File Converter) 264 Chapter 10 Directory and Filesystem Operations 276 10.1 Introduction 276 10.2 Getting File Information 276 10.3 Creating a File 279 10.4 Renaming a File 280 10.5 Deleting a File 281 10.6 Creating a Transient File 282 10.7 Changing File Attributes 284 10.8 Listing a Directory 285 10.9 Getting the Directory Roots 287 10.10 Making New Directories 288 10.11 Program: Find 288 Chapter 11 Programming Serial and Parallel Ports 292 11.1 Introduction 292 11.2 Choosing a Port 294 11.3 Opening a Serial Port 297 11.4 Opening a Parallel Port 301 11.5 Resolving Port Conflicts 304 11.6 Reading and Writing: Lock Step 307 11.7 Reading and Writing: Event-Driven 309 11.8 Reading and Writing: Threads 313 11.9 Program: Penman Plotter 315 Chapter 12 Graphics and Sound 320 12.1 Introduction 320 12.2 Painting with a Graphics Object 321 12.3 Testing Graphical Components 322 12.4 Drawing Text 323 12.5 Drawing Centered Text in a Component 323 12.6 Drawing a Drop Shadow 324 12.7 Drawing an Image 327 12.8 Playing a Sound File 331 12.9 Displaying a Moving Image with Video 332 12.10 Drawing Text with 2D 335 12.11 Printing: JDK 1.1 337 12.12 Printing: Java 339 12.13 Program: PlotterAWT 342 12.14 Program: Grapher 344 Chapter 13 Graphical User Interfaces 348 13.1 Introduction 348 13.2 Displaying GUI Components 349 13.3 Designing a Window Layout 351 13.5 Action Handling: Making Butto ns Work 354 13.6 Action Handling Using Anonymous Inner Classes 356 13.7 Terminating a Program with "Window Close" 357 13.8 Dialogs: When Later Just Won't Do 361 13.9 Getting Program Output into a Window 363 13.10 Choosing a File with JFileChooser 366 13.11 Choosing a Color 369 13.12 Centering a Main Window 371 13.13 Changing a Swing Program's Look and Feel 372 13.14 Program: Custom Font Chooser 376 13.15 Program: Custom Layout Manager 381 Chapter 14 Internationalization and Localization 387 14.1 Introduction 387 14.2 Creating a Button with I18N Resources 388 14.3 Listing Available Locales 389 14.4 Creating a Menu with I18N Resources 390 14.5 Writing Internationalization Convenience Routines 391 14.6 Creating a Dialog with I18N Resources 393 14.7 Creating a Resource Bundle 394 14.8 JILTing Your Code 395 14.9 Using a Particular Locale 396 14.10 Setting the Default Locale 397 14.11 Formatting Messages 398 14.12 Program: MenuIntl 400 14.13 Program: BusCard 402 Chapter 15 Network Clients 406 15.1 Introduction 406 15.2 Contacting a Server 408 15.3 Finding and Reporting Network Addresses 409 15.4 Handling Network Errors 410 15.5 Reading and Writing Textual Data 411 15.6 Reading and Writing Binary Data 414 15.7 Reading and Writing Serialized Data 416 15.8 UDP Datagrams 417 15.9 Program: TFTP UDP Client 419 15.10 Program: Telnet Client 423 15.11 Program: Chat Client 425 Chapter 16 Server-Side Java: Sockets 431 16.1 Introduction 431 16.2 Opening a Server for Business 431 16.3 Returning a Response (Stri ng or Binary) 434 16.4 Returning Object Information 437 16.5 Handling Multiple Clients 438 16.6 Network Logging 443 16.7 Program: A Java Chat Server 446 Chapter 17 Network Clients II: Applets and Web Clients 452 17.1 Introduction 452 17.2 Embedding Java in a Web Page 452 17.3 Applet Techniques 454 17.4 Contacting a Server on the Applet Host 456 17.5 Making an Applet Show a Document 459 17.6 Making an Applet Run a CGI Script 460 17.7 Reading the Contents of a URL 461 17.8 Extracting HTML from a URL 462 17.9 Extracting URLs from a File 464 17.10 Converting a Filename to a URL 466 17.11 Program: MkIndex 467 17.12 Program: LinkChecker 471 Chapter 18 Web Server Java: Servlets and JSP 478 18.1 Introduction 478 18.2 First Servlet: Generating an HTML Page 479 18.3 Servlets: Processing Form Parameters 482 18.4 Cookies 485 18.5 Session Tracking 488 18.6 Generating PDF from a Servlet 493 18.7 HTML Meets Java: JSP 499 18.8 JSP Include/Forward 503 18.9 JavaServer Pages Using a Servlet 504 18.10 Simplifying Your JSP with a JavaBean 505 18.11 JSP Syntax Summary 508 18.12 Program: CookieCutter 509 18.13 Program: JabaDot Web News Portal 510 Chapter 19 Java and Electronic Mail 520 19.1 Introduction 520 19.2 Sending Email: Browser Version 520 19.3 Sending Email: For Real 525 19.4 Mail-Enabling a Server Program 527 19.5 Sending MIME Mail 533 19.6 Providing Mail Settings 535 19.7 Sending Mail Without Using JavaMail 536 19.8 Reading Email 540 19.9 Program: MailReaderBean 544 19.10 Program: MailClient 548 Chapter 20 Database Access 559 20.1 Introduction 559 20.2 Text-File Databases 560 20.3 DBM Databases 565 20.4 JDBC Setup and Connection 568 20.5 Connecting to a JDBC Database 570 20.6 Sending a JDBC Query and Getting Results 573 20.7 Using JDBC Parameterized Statements 575 20.8 Using Stored Procedures with JDBC 579 20.9 Changing Data Using a ResultSet 579 20.10 Changing Data Using SQL 580 20.11 Finding JDBC Metadata 582 20.12 Program: JDAdmin 588 Chapter 21 XML 595 21.1 Introduction 595 21.2 Transforming XML with XSLT 597 21.3 Parsing XML with SAX 599 21.4 Parsing XML with DOM 601 21.5 Verifying Structure with a DTD 603 21.6 Generating Your Own XML with DOM 604 21.7 Program: xml2mif 606 Chapter 22 Distributed Java: RMI 609 22.1 Introduction 609 22.2 Defining the RMI Contract 610 22.3 RMI Client 612 22.4 RMI Server 613 22.5 Deploying RMI Across a Network 615 22.6 Program: RMI Callbacks 616 22.7 Program: RMIWatch 620 Chapter 23 Packages and Packaging 626 23.1 Introduction 626 23.2 Creating a Package 627 23.3 Documenting Classes with Javadoc 627 23.4 Archiving with jar 631 23.5 Running an Applet from a JAR 632 23.6 Running an Applet with a JDK 632 23.7 Running a Program from a JAR 636 23.8 Preparing a Class as a JavaBean 636 23.9 Pickling Your Bean into a JAR 640 23.10 Packaging a Servlet into a WAR File 641 23.11 "Write Once, Install Anywhere" 642 23.12 Java Web Start 642 23.13 Signing Your JAR File 648 Chapter 24 Threaded Java 650 24.1 Introduction 650 24.2 Running Code in a Different Thread 651 24.3 Displaying a Moving Image with Animation 654 24.4 Stopping a Thread 657 24.5 Rendezvous and Timeouts 660 24.6 Thread Communication: Synchronized Code 661 24.7 Thread Communication: wait( ) and notifyAll( ) 666 24.8 Background Saving in an Editor 672 24.9 Threaded Network Server 673 Chapter 25 Introspection, or "A Class Named Class" 682 25.1 Introduction 682 25.2 Getting a Class Descriptor 683 25.3 Finding and Using Methods and Fields 684 25.4 Loading and Instantiating a Class Dynamically 687 25.5 Constructing a Class from Scratch 689 25.6 Performance Timing 691 25.7 Printing Class Information 693 25.8 Program: CrossRef 695 25.9 Program: AppletViewer 700 Chapter 26 Using Java with Other Languages 707 26.1 Introduction 707 26.2 Running a Program 707 26.3 Running a Program and Capturing Its Output 710 26.4 Mixing Java and Scripts with BSF 713 26.5 Blending in Native Code (C/C++) 717 26.6 Calling Java from Native Code 723 26.7 Program: DBM 723 Chapter 27 Afterword 727 Colophon 728 10 While it is convenient (and efficient) to run JPython in the same JVM as the calling program, this is not by any means a requirement; for example, it is possible to use BSF with scripting languages written in some native language BSF and the scripting plug-in are responsible for dealing with whatever "plumbing" external connections or processes this requires In fact, BSF currently supports the languages listed in Table 26-1 Table 26-1 Languages supported by BSF Language JPython Jacl Bean Markup Language (BML) LotusXSL Description Java implementation of Python Java implementation/interface for Tcl Related language, from IBM NetRexx Netscape Rhino XML stylesheets (see Section 21.2) REXX variant JavaScript implementation Pnuts Microsoft Active Scripting Format (MASF) Scripting language for accessing Java APIs Microsoft analog of BSF BSF could also support MacOS Apple Scripting or almost any other language, though I don't know of an implementation at present Example 26-5 uses JPython to evaluate and print the value of 22/7, a crude approximation of Math.PI, using the management API's eval( ) function Example 26-5 BSFSample.java import com.ibm.cs.util.*; import com.ibm.bsf.*; import java.io.*; /** Sample of using Bean Scripting Framework with JPython */ public class BSFSample { public static void main(String[] args) { BSFManager manager = new BSFManager( ); // register scripting language String[] fntypes = { ".py" }; manager.registerScriptingEngine("jpython", "com.ibm.bsf.engines.jpython.JPythonEngine", fntypes); try { BSFEngine jpythonengine = manager.loadScriptingEngine("jpython"); // try an expression Object r = manager.eval("jpython", "testString", 0, 0, "22.0/7"); System.out.println("Result type is " + r.getClass().getName( )); System.out.println("Result value is " + r); } catch (Exception ex) { System.err.println(ex.toString( )); } 714 System.out.println("Scripting demo done."); return; } } This program prints the following output: $ java BSFSample 'import exceptions' failed; using string-based exceptions Result type is org.python.core.PyFloat Result value is 3.142857142857143 Scripting demo done $ The exceptions failure is probably due to my having installed JPython in a non-standard location and not setting the environment variable(s) needed to find it Further, the first time you run it, JPython spits out a bunch of nattering about your CLASSPATH, one line for each JAR file that it finds These can be a bit surprising when they pop up from a script, but JPython doesn't seem to know or care whether it's being run interactively or dynamically packageManager: processing new jar, "/usr/local/java/swingall.jar" The following longer example uses the LabelText bean from Section 23.8 and a push button to run a Python script that collects the text from the LabelText instance and displays it on the standard output Here is the little script, buttonhandler.py: print "Hello"; print bean.getText( ); When I ran this, I typed the famous words that Alexander Graham Bell apparently sent to his assistant Watson, and had the Java program send them to the Python script Sure enough, when I clicked on the button, I got this on the standard output (as shown in Figure 26-2): Script output: > Hello Mr Watson, come here < End of Script output Figure 26-2 BSFSample in action Nothing you couldn't in Java, of course, but in this example the LabelText bean is registered with the BSF as a bean, and the JButton's action handler runs a script that gets that text and displays it Example 26-6 shows the source code for the script-using program Example 26-6 BSFAction.java 715 import import import import import import com.ibm.cs.util.*; com.ibm.bsf.*; javax.swing.*; java.awt.*; java.awt.event.*; java.io.*; /** Longer sample of using Bean Scripting Framework with JPython */ public class BSFAction { protected String FILENAME = "buttonhandler.py"; protected BSFManager manager; protected BSFEngine jpythonengine; protected String language; protected String script; public static void main(String[] args) { new BSFAction( ); } BSFAction( ) { // Construct the Bean instance LabelText bean = new LabelText("Message to Python script"); try { manager = new BSFManager( ); // register scripting language String[] fntypes = { ".py" }; manager.registerScriptingEngine("jpython", "com.ibm.bsf.engines.jpython.JPythonEngine", fntypes); jpythonengine = manager.loadScriptingEngine("jpython"); // Tell BSF about the bean manager.declareBean("bean", bean, LabelText.class); // Read the script file into BSF language = manager.getLangFromFilename(FILENAME); script = IOUtils.getStringFromReader( new FileReader(FILENAME)); } catch (Exception ex) { System.err.println(ex.toString( System.exit(0); } )); System.out.println("Scripting setup done, building GUI."); final JFrame jf = new JFrame(getClass().getName( Container cp = jf.getContentPane( cp.setLayout(new FlowLayout( )); cp.add(bean); )); ); // add the LabelText JButton b = new JButton("Click me!"); cp.add(b); // and the button under it 716 b.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent evt) { try { // When the button is pressed, run the script System.out.println("Script output: >"); manager.exec(language, FILENAME, 0, 0, script); System.out.println("< End of Script output."); } catch (BSFException bse) { JOptionPane.showMessageDialog(jf, "ERROR: " + bse, "Script Error", JOptionPane.ERROR_MESSAGE); } } }); // A Quit button at the bottom JButton qb = new JButton("Quit"); cp.add(qb); qb.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent evt) { System.exit(0); } }); // Routine JFrame setup jf.pack( ); jf.setVisible(true); } } 26.4.4 See Also Information on the Bean Scripting Framework is currently located on IBM's alphaWorks web site, under http://oss.software.ibm.com/developerworks/projects/bsf/ JPython has been taken under a new umbrella and renamed Jython; see http://www.jython.org There are many other projects that aim to blend Java with other languages As a single example, check out the OmegaHat project's interface at http://www.omegahat.org/RSJava/ R, itself a clone of S (http://cm.bell-labs.com/cm/ms/departments/sia/S/) is the statistical package used to produce the charts back in Figure 5-1 This interface lets you use Java inside R or S, and also to call R or S from Java code 26.5 Blending in Native Code (C/C++) 26.5.1 Problem You wish to call native C/C++ functions from Java, either for efficiency or to access hardware- or system-specific features 26.5.2 Solution 717 Use JNI, the Java Native Interface 26.5.3 Discussion Java lets you load native or compiled code into your Java program Why would you want to such a thing? One reason might be to access OS-dependent functionality Another is speed: native code will likely run faster than Java, at least at present Like everything else in Java, this mechanism is subject to security restrictions; for example, applets are not allowed to access native code The native code language bindings are defined for code that has been written in the C or C++ language If you need to access a language other than C/C++, write a bit of C/C++ and have it pass control to other functions or applications, using any mechanism defined by your operating system Due to such system-dependent features as the interpretation of header files and the allocation of the processor's general-purpose registers, your native code may need to be compiled by the same C compiler used to compile the Java runtime for your platform For example, on Solaris you can use SunPro C, or maybe gcc On Win32 platforms, use Microsoft Visual C++ Version 4.x or higher (32 bit) For other platforms, see your Java vendor's documentation Also note that the details in this section are for Java 1.1's Java Native Interface (JNI) that differs in some details from 1.0 and from Microsoft's native interface The steps to call native code are summarized in the following sidebar and detailed below Ian's Basic Steps: Java Calling Native Code Write Java code that calls a native method Compile this Java code Create an h file using javah Write a C function that does the work Compile the C code into a loadable object Try it! The first step is to write Java code that calls a native method To this, use the keyword native to indicate that the method is native, and provide a static code block that loads your native method using System.loadLibrary( ) (The dynamically loadable module is created in Step 5.) Static blocks are executed when the class containing them is loaded; loading the native code here ensures it is in memory when needed! Object variables that your native code may modify should carry the volatile modifier The file HelloWorld.java , shown in Example 26-7, is a good starting point Example 26-7 HelloWorld.java /** * A trivial class to show Java Native Interface 1.1 usage from Java */ public class HelloWorld { 718 int myNumber = 42; // used to show argument passing // declare native class public native void displayHelloWorld( ); // Application main, call its display method public static void main(String[] args) { System.out.println("HelloWorld starting; args.length="+ args.length+" "); for (int i=0; iJava->C And," @echo "incidentally, a replacement for JDK program \"java\" itself!" @echo javafromc.all: javafromc javafromc: javafromc.o $(CC) -L$(LIBDIR) javafromc.o -ljava -o $@ javafromc.o: javafromc.c $(CC) -c $(INCLUDES) javafromc.c clean: rm -f core *.class *.o *.so HelloWorld.h clobber: clean rm -f javafromc And you're done! Just run the Java interpreter on the class file containing the main program Assuming that you've set whatever system-dependent settings are necessary (possibly including both CLASSPATH and LD_LIBRARY_PATH or its equivalent), the program should run as follows: C> java HelloWorld Hello from a Native Method "myNumber" value is 42 "myNumber" value now 43 Value of myNumber now 43 // from C // from C // from C // from Java Congratulations! You've called a native method However, you've given up portability; the Java class file now requires you to build a loadable object for each operating system and hardware platform Multiply {MS-Windows 95/98, MS-Windows CE, Me, and NT, MacOS, Sun Solaris, HP/UX, Linux, OpenBSD, NetBSD, FreeBSD} times {Intel, SPARC, PowerPC, HP-PA, Sun3} and you begin to see the portability issues Your native code can be used in server code and desktop applications, but is normally not permitted in web browsers Beware that problems with your native code can and will crash the runtime process right out from underneath the Java Virtual Machine The JVM can nothing to protect itself from poorly written C/C++ code Memory must be managed by the programmer; there is no automatic garbage collection of memory obtained by the system runtime allocator You're dealing directly with the operating system and sometimes even the hardware, so, "Be careful Be very careful." 26.5.4 See Also If you need more information on Java Native Methods, you might be interested in the comprehensive treatment found in Essential JNI: Java Native Interface by Rob Gordon (Prentice Hall) 722 26.6 Calling Java from Native Code 26.6.1 Problem You need to go the other way, calling Java from C/C++ code 26.6.2 Solution Use JNI again 26.6.3 Discussion In 1.1, JNI provides an interface for calling Java from C, with calls to: Create a JVM Load a class Find and call a method from that class (i.e., main) This lets you add Java to legacy code That can be useful for a variety of purposes, but entails treating Java code as an extension language (just define or find an interface like Applet or Servlet, and let your customers subclass from it) This is not discussed in detail here, but there's a full code example in the code archive in directory src/native1.1 26.7 Program: DBM This program lets you use the original Unix DBM (database access method) routines from Java DBM is actually emulated using the newer Berkeley Database (DB) routines, but the DBM interface is more traditional, and simpler DBM was used in Section 20.3 to provide a name-tologin database, which is similar to how many modern Unixes actually store name and password information That recipe also showed how to use it to display your Netscape history, even under MS-Windows I'll now show the Java version of the DBM library, DBM.java (see Example 26-10) Example 26-10 DBM.java import java.io.*; /** This class provides a dbm-compatible interface to the Unix-style * database access methods described in dbm(3) (which is on some Unixes * a front-end to db(3) * Each unique record in the database is a unique key/value pair, * similar to a java.util.Hashtable but stored on persistent medium, not * kept in memory Dbm was originally optimized for Unix for fast * access to individual key/value pairs */ public class DBM { /** Since you can only have one DBM database in use at a time due 723 * to implementation restrictions, we enforce this rule with a * class-wide boolean */ protected static boolean inuse = false; /** Save the filename for messages, etc */ protected String fileName; /** Construct a DBM given its filename */ public DBM(String file) { synchronized(this) { if (inuse) throw new IllegalArgumentException( "Only one DBM object at a time per Java Machine"); inuse = true; } fileName = file; int retCode = dbminit(fileName); if (retCode < 0) throw new IllegalArgumentException( "dbminit failed, code = " + retCode); } // Static code blocks are executed once, when class file is loaded // This is here to ensure that the shared library gets loaded static { System.loadLibrary("jdbm"); } protected ByteArrayOutputStream bo; /** serialize an Object to byte array */ protected byte[] toByteArray(Object o) throws IOException { if (bo == null) bo = new ByteArrayOutputStream(1024); bo.reset( ); ObjectOutputStream os = new ObjectOutputStream(bo); os.writeObject(o); os.close( ); return bo.toByteArray( ); } /** un-serialize an Object from a byte array */ protected Object toObject(byte[] b) throws IOException { Object o; ByteArrayInputStream bi = new ByteArrayInputStream(b); ObjectInputStream os = new ObjectInputStream(bi); try { o = os.readObject( ); } catch (ClassNotFoundException ex) { // Convert ClassNotFoundException to I/O error throw new IOException(ex.getMessage( )); } os.close( ); return o; } 724 protected native int dbminit(String file); protected native int dbmclose( ); /** Public wrapper for close method */ public void close( ) { this.dbmclose( ); inuse = false; } protected void checkInUse( ) { if (!inuse) throw new IllegalStateException("Method called when DBM not open"); } protected native byte[] dbmfetch(byte[] key); /** Fetch using byte arrays */ public byte[] fetch(byte[] key) throws IOException { checkInUse( ); return dbmfetch(key); } /** Fetch using Objects */ public Object fetch(Object key) throws IOException { checkInUse( ); byte[] datum = dbmfetch(toByteArray(key)); return toObject(datum); } protected native int dbmstore(byte[] key, byte[] content); /** Store using byte arrays */ public void store(byte[] key, byte[] value) throws IOException { checkInUse( ); dbmstore(key, value); } /** Store using Objects */ public void store(Object key, Object value) throws IOException { checkInUse( ); dbmstore(toByteArray(key), toByteArray(value)); } protected native int delete(Object key); public native byte[] firstkey( public Object firstkeyObject( return toObject(firstkey( } ) throws IOException; ) throws IOException { )); public native byte[] nextkey(byte[] key) throws IOException; public Object nextkey(Object key) throws IOException { 725 byte[] ba = nextkey(toByteArray(key)); if (ba == null) return null; return toObject(ba); } public String toString( ) { return "DBM@" + hashCode( } ) + "[" + fileName + "]"; } Notice how the methods toByteArray( ) and toObject( ), the inverses of each other, convert between an object and an array of bytes using ByteArrayStreams These provide the functionality of reading from or writing to a buffer that is in memory, instead of the usual buffer that has been read from or written to a disk file or socket 26.7.1 See Also A more complete and widely used implementation of DBM for Java is available from SleepyCat Software, the heirs-apparent to the Berkeley DBM software Their SleepyCat DBM can be downloaded for free, in source form, under the Berkeley (University of California at Berkeley) software license Check out http://www.sleepycat.com 726 Chapter 27 Afterword Writing this book has been a humbling experience It has taken far longer than I had predicted, or than I would like to admit And, of course, it's not finished yet Despite my best efforts and those of the technical reviewers, editors, and many other talented folks, a book this size is bound to contain errors, omissions, and passages that are less clear than they might be Please, let us know by email if you happen across any of these things There will be subsequent editions that incorporate changes sent in by readers just like you! It has been said that you don't really know something until you've taught it I have found this true of lecturing, and find it equally true of writing I tell my students that when Java was very young, it was possible for one person to study hard and know almost everything about Java When Java 1.1 came out, this was no longer true With Java 2, anybody who tells you they "know all about Java" should cause your "bogozity" detector to go off at full volume And the amount you need to know keeps growing How can you keep up? Java books? Java magazines? Java courses? Conferences? There is no single answer; all of these are useful to some people Sun's Java software division has several programs that you should be aware of: • JavaOne, their annual conference (http://java.sun.com/javaone/) • The Java Developer Connection, a free web-based service for getting the latest APIs, news, and views (http://developer.java.sun.com) • The Java Community Process (http://java.sun.com/aboutJava/communityprocess/), the home of open Java standardization and enhancement • Java Developer Essentials, a fee-based CD-ROM subscription to all the Java APIS, tools, and other material (http://www.sun.com/developers/tools/) As you know, the Java API is divided into packages A package is normally considered "core" if its package name begins with java, and an optional extension if its package name begins with javax But there is already one exception to this rule: javax.swing.* which is core I maintain a comprehensive listing of the major Java APIs produced and promulgated by the Java division of Sun Microsystems on my web site, at http://www.darwinsys.com/java/javaapi.html As you can see, there is no end of Java APIs to learn about And there are still more books to be written and read 727 Colophon Our look is the result of reader comments, our own experimentation, and feedback from distribution channels Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects The animal on the cover of Java Cookbook is a domestic chicken Domestic chickens (Gallus gallus) are descended from the wild red jungle fowl of India Domesticated over 8,000 years ago in the area that is now Vietnam and Thailand, chickens are raised for meat and eggs, and the males for sport as well (though cockfighting is currently against the law in many places) With their big, heavy bodies and small wings, these birds are well suited to living on the ground, and they can fly at most only short distances Their four-toed feet are designed for scratching in the dirt, where they find the elements of their usual diet: worms, bugs, seeds, and various plant matter A male chicken is called a rooster or cock, and a female is known as a hen The incubation period for a chicken egg is about three weeks; newly hatched chickens are precocial, meaning they have downy feathers and can walk around on their own right after emerging from the egg They're also not dependent on their mothers for food; not only can they procure their own, but they also can live for up to a week post-hatch on egg yolk that remains in their abdomen after birth The topic of chickens comes up frequently in ancient writings Chinese documents date their introduction to China to 1400 B.C., Babylonian carvings mention them in 600 B.C., and Aristophanes wrote about them in 400 B.C The rooster has long symbolized courage: the Romans thought chickens were sacred to Mars, god of war, and the first French Republic chose the rooster as its emblem Emily Quill was the production editor and copyeditor for Java Cookbook Claire Cloutier, Colleen Gorman, and Jane Ellin conducted quality control reviews, and Edith Shapiro, Sada Preisch, Lucy Muellner, Linley Dolby, and Matt Hutchinson provided production assistance Ellen TroutmanZaig wrote the index Hanna Dyer designed the cover of this book, based on a series design by Edie Freedman The cover image is a 19th-century engraving from the Dover Pictoral Archive Emma Colby produced the cover layout with Quark™XPress 4.1 using Adobe's ITC Garamond font Melanie Wang and David Futato designed the interior layout, based on a series design by Nancy Priest Mike Sierra implemented the design in FrameMaker 5.5.6 The heading font is Bitstream Bodoni, the text font is ITC New Baskerville, and the code font is Constant Willison The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand and Adobe Photoshop This colophon was written by Leanne Soylemez 728 ... Java SDK), the commands are javac to compile and java to run your program For example: C:javasrc>javac HelloWorld .java C:javasrc >java HelloWorld Hello, World C:javasrc> As you can see from... APIs that aren't as well documented in other Java books The Java Cookbook, like the bestselling Perl Cookbook, covers a lot of ground, and offers Java developers short, focused pieces of code... and/or if any for FTP? Check out http:/ /java. sun.com (oak got renamed to java and webrunner got renamed to hotjava to keep the lawyers happy) I downloaded HotJava and began to play with it At first