From pvdl@best.com Wed May 06 19:19:21 1998
Path: news.nic.utwente.nl!news.cs.utwente.nl!Cabal.CESspool!bofh.vszbr.cz!newsfeed.wli.net!ptdnetP!newsgate.ptd.net!newshub.northeast.verio.net!news1.best.com!nntp1.ba.best.com!not-for-mail
From: pvdl@best.com (Peter van der Linden)
Newsgroups: comp.lang.java.programmer,comp.lang.java.help,comp.lang.java.gui,comp.answers,news.answers
Subject: Java Programmers FAQ
Supersedes: <6id7e6$gu$1@shell15.ba.best.com>
Followup-To: poster
Date: 6 May 1998 10:19:21 -0700
Lines: 6027
Approved: news-answers-request@MIT.EDU
Message-ID: <6iq62p$ehl$1@shell15.ba.best.com>
NNTP-Posting-Host: shell15.ba.best.com
X-Trace: 894475163 22452 pvdl  206.184.139.132
Summary: This posting answers frequently-asked questions by Java programmers
Xref: news.nic.utwente.nl comp.lang.java.programmer:156830 comp.lang.java.help:26461 comp.lang.java.gui:15571 comp.answers:27127 news.answers:45148

Archive-name: computer-lang/java/programmers/faq
Posting-Frequency: weekly
Last-modified: 1998/5/6
URL: http://www.afu.com/javafaq.html
Copyright: (c) 1997,1998 Peter van der Linden
Maintainer: Peter van der Linden

Frequently Asked Questions (with answers) for Java programmers

           _____________________________________________________
  ________|                                                     |________
  \       |   Java Programmers FAQ        http://www.afu.com    |       /
   \      |      Copyright (c) 1997-98 Peter van der Linden     |      /
   /      |_____________________________________________________|      \
  /___________)                                              (__________\

The Java FAQs here are intended for people who already have some programming
experience, maybe not in Java though.

Go to the FAQ home page at http://www.afu.com for other Java information and
downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to
faqme AT afu.com.

------------------------------------------------------------------------

Please support Java Portability.

The biggest value of Java is its portability.

   * Portability makes it easier for companies to change/upgrade operating
     systems and platforms.
   * Portability makes it easier for Java programmers to transfer their
     skills to new employers.

Microsoft does not want users to easily move their software to different
platforms. So they made unauthorized changes to Java to try to undermine
portability. The changes are described by an independent Java users
organization at http://www.javalobby.org/action/msjava-diffs.htm.

A Federal judge issued a preliminary injunction against Microsoft in March
1998, prohibiting them from selling their incompatible J++ product as Java.

Here is a link to http://www.interhack.net/people/cmcurtin/rants/
write-once-run-anywhere/write-once-run-anywhere.html explaining why Java
portability is important.

The best way for programmers to support portable Java is to reject
non-standard tools from the only company pushing them: Microsoft. As a Java
programmer please join the Java Lobby, an independent organization dedicated
to representing non-vendor interests in Java. It's free, and you can sign up
by visiting http://www.javalobby.org for details. Other ways to encourage
portable java:

   * Use development environments from other vendors, or convert Microsoft
     Visual J++ to use Sun's JDK, following the instructions at
     http://www.orbiter.demon.co.uk/
   * Use Netscape Communicator (not Internet Explorer)
   * If forced to use Internet Explorer, use the Java Plug-In to get a
     standard Java system inside it.
   * Use a JVM from GNU, Kaffe or Sun (not Microsoft's J++ SDK)

Free standard Java compilers and Java Plug-In can be downloaded from
http://java.sun.com.
Free standard Java Virtual Machines can be downloaded from
http://www.kaffe.org. and http://www.oryxsoft.com/projects/gvm and
http://www.redhat.com/linux-info/jolt
Free Java AWT software can be downloaded from
http://www.biss-net.com/biss-awt.html and the files are all at
ftp.java-linux.org (the linux site) too.
Free Java software can be downloaded from
http://www.gnu.org/software/java/java.html

------------------------------------------------------------------------

0. A WORD FROM OUR SPONSOR

   *

1. LOOKING FOR INFORMATION

   * Is Java "open" or "proprietary?
     How do you refer someone to the FAQ?
     Where can I look at the definitive Java Language Spec?
     Where can I find a full list of Java books and book reviews?
     What if my question is not answered in this FAQ?
     How do I check on known bugs in JDK 1.1?
     Is there a Java port to Windows 3.1?
     Where can I find information on the Java 3D API?
     What are the good folks at project Gnu doing with java?
     Where can I find information about Java Certification?
     Where can I find a Java style guide on naming conventions?
     Where can I find information about future Java APIs?
     How can I find links to recent news about Java?
     What computers have Java ports?

2. COMPILERS, ETC.

   * Why did I get an OutOfMemory error when porting?
     Why do I get a Statement not reached error?
     Is there a lex and yacc?
     Where can I find a byte code Obfuscator?
     Which program is used to create .zip files?
     Can I compile a Java .class file to a binary?
     How can I performance profile my Java code?
     I get a javadoc when looking at JDK classes
     How do I recompile everything?
     What is java.lang.UnsatisfiedLinkError?
     Why do I get an error in accessing a private outer method?

3. LANGUAGE ISSUES

   * Why doesn't my hello world program work?
     How can I program linked lists if Java doesn't have pointers?
     What is the true story about how parameters are passed in Java?
     How, then, can I pass an object to a method, and have the method change
     the reference?
     Why is String a final class?
     What happened to private protected"
     I extended the class called Frotz, and...?
     About Java floating point
     may not have been initialized"> Variable may not have been initialized
     Why do I get this compiler error message (Statement expected, Type
     expected)?
     Why do I get this compiler error: No constructor matching?
     Why do I get the compiler warning "Can't access protected method
     clone..."?
     How do I transform a char into the corresponding int value?
     Are constructors inherited?
     How do I allocate a multidimensional array?
     What are the tradeoffs between importing packages versus using Fully
     Qualified Name?
     What are class literals?
     How do I copy the contents of an array to another array?
     Is there a fast way to set all elements of an array?
     Is there a shortcut for Math acos, cos, sin, etc?
     Why does b>>>=1 give the same result as b >>=1?
     How do I compare two Strings?
     How can I be type-safe without creating a multitude of subclasses?
     Why is there a standard JNI?
     What are the naming conventions in Java?
     What are the differences between an interface and an abstract class?
     How do static methods interact with inheritance?
     How do I get unsigned ints?

4. AWT and Related Topics

   * 4.0 AWT
        o Why do I get this when using JDK 1.1 under X: (Font problem)?
          (links to be continued...)

     4.1 APPLETS
     4.2 BROWSERS
     4.3 SWING

5. CORE LIBRARIES
6. I/O
7. NETWORKING & DISTRIBUTED OBJECTS
8. MULTI-MEDIA
9. SECURITY
10. Java IDIOMS
11. FOR C and C++ AFFICIONADOS
12. FURTHER RESOURCES
13. MOST COMMON JAVA NOVICE PROBLEMS
14. FOR WINDOWS USERS
15. Java GOTCHA'S

-------------------------------------------------------------------------

0. A WORD FROM OUR SPONSOR

Learning Java

This Java FAQ is maintained as a service to the Java community. Please
consider these books from the FAQ author when you are looking for a
programming text.

   * "Just Java 1.1" Programming in Java, for people who can already program
     in another language. More info at
     http://www.amazon.com/exec/obidos/ISBN%3D0137841744

     "Not Just Java" Java explained for managers. More info at
     http://www.amazon.com/exec/obidos/ISBN=0138646384

Sample chapters are on Sun Microsystems webpage at
http://www.sun.com/971124/cover-linden/.
                             -------------------

1. Looking For Information

   * 1.0 Is Java "Open" or "Proprietary"?
        o A. Java is a freely-available open specification. Sun Microsystems
          publishes the Java specifications and public interfaces as open
          specifications that can be independently implemented by anyone
          without charge (termed a "clean-room" implementation in industry
          jargon).

          Specifically, Sun includes a perpetual, irrevocable, free and
          royalty-free license in the front of the Addison-Wesley books
          containing the specification.

          Further, by submitting Java specifications to be ISO/IEC
          standards, Sun is giving up some control in exchange for the world
          being able to refer to a Java specification that is guaranteed to
          be open by ISO/IEC's charter and rules. Sun promised ISO that it
          will abide by ISO's rules for developing a standard, in particular
          it will take account of industry input. Just as with other ISO
          standards, "open" does not mean that anyone who suggests any new
          feature will get it into the Java standard; Sun has the casting
          vote in the future evolution of Java, but it does not own the
          specification nor the sole right to implement to it. On the
          spectrum of "single vendor proprietary technology" to "open to all
          to implement", Java lies much more towards the open end than the
          single vendor end.

          Sun Microsystems has invested significant time and money to create
          its Java implementation. Sun has licensed its source code to more
          than 140 companies and organizations who want to build it into a
          commercial product of their own, including competitor Microsoft.
          Sun has also allowed free download and use of the Java
          implementation (binary executables) by anyone. Over 2 million
          computer users have downloaded the JDKbinaries for free in the
          twelve month period to December 1997.

          The relative openness of Java contrasts with systems that are only
          available from one vendor, whose interfaces are developed in
          secret, without an open process for others to participate, and
          whose owners do not allow competing implementations of the same
          API. Typically, such systems also feature "private" APIs that are
          published late or not published at all, to allow the single vendor
          to gain a competitive advantage for their other products.
          Typically such proprietary systems do not make the source code
          available for inspection by all.

          Some programmers want to see the Java source for free. They say
          that nothing is truly open without the source code. Sun allows
          this. If you aren't planning on incorporating Java into a
          commercial product, or doing any sort of external redistribution,
          there is an Internal Noncommercial Use Source License available at
          no charge. Please see URL
          http://java.sun.com/nav/business/source_form.html

     1.1 What is the best way to refer someone to the FAQ when they ask
     question I know is answered there?
        o A. The Java Programmers FAQ (at http://www.afu.com) answers your
          question in section N.n. ...

          This gives them the answer, and shows them where to go for future
          questions It also demonstrates that the FAQ can answer their
          questions, supplying an incentive to go there next time. It's
          regarded as elementary politeness to look for the FAQ of a
          newsgroup and read it, before posting any questions.

          In general, FAQs for any newsgroup are available by looking at
          past postings in a group, or by searching Deja News (see Q 1.4),
          or via anonymous FTP at directories under ftp://rtfm.mit.edu The
          pathnames are called things like
          /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ
          which may help you get to the right one directly, as it takes some
          time to get a directory listing there. Alternatively, you can look
          for newsgroup names on the same ftp site by going to the same site
          and looking under /pub/usenet-by-hierarchy/. That has
          subdirectories such as alt/, ba/, ca/, comp/, and subdirectories
          under them such as /pub/usenet-by-hierarchy/comp/lang/ and so on.
          This helps you explore the world of newsgroups with FAQs.

          If you do not have anonymous FTP access, you can access the
          rtfm.mit.edu archives by mail server as well. Send an E-mail
          message to mail-server@rtfm.mit.edu with "help" in the body for
          more information. "RTFM" stands for "Read The effing Manual" --
          you must expect to put in some time and effort to master a new
          area of study.

     1.2 Where can I look at the definitive Java Language Specification?
        o A. This is available online at:
             + http://java.sun.com/docs/books/jls/html/index.html (Java 1.0)

          and the Java 1.1 inner classes spec at:
             + http://java.sun.com/products/jdk/1.1/docs/guide
               /innerclasses/spec/innerclasses.doc.html

          and the other Java 1.1 update at:
             + http://java.sun.com/docs/books/jls/html/1.1Update.html

          It is also available as a book in printed form (details at
          website). Also see the "Clarifications and Amendments"
          http://java.sun.com/docs/books/jls/clarify.html.

          You can also see the virtual machine (execution environment)
          specification at
          http://docs.sun.com:80/ab2/java1/@Ab2CollToc?subject=java

     1.3 Where can I find a full list of Java books and book reviews?
        o A. http://www.flathill.com/languages/java/
          and
          http://www.javaworld.com/javaworld/books/jw-books-index.html

     1.4 What if my question is not answered in this FAQ?
        o A. Go to http://www.dejanews.com/home_ps.shtml
             + Under "Newsgroups" enter "comp.lang.java.programmer" (or
               whatever)
             + Under "Subject" enter "Frotteur" (or other topic you find
               pressing)
             + Click "Create Filter"
             + It will go to a new document, and you should click the link
               labeled

               nnn Documents (nnn is some number).

          The chances are that you will find several answers to your
          question. Some may not be complete or completely accurate however.
          That is the nature of Usenet, and free information. If you still
          don't have an answer, then post your question on the most
          appropriate of the newsgroups. Don't spam the newsgroups by
          posting to multiple groups. Knowledgeable posters tend to ignore
          questions like that.

          Also look at http://sunsite.unc.edu/java/cgi-bin/query
          and look at http://asknpac.npac.syr.edu/ for Java newsgroup search

          http://www.javaworld.com/search.html can search the Javaworld
          newspaper

     1.5 How do I check on known bugs in JDK 1.1?
        o A. Look at the Java Developer Connection at
          http://java.sun.com/jdc.

          Note that only bugs that Sun deems "important" are listed there.
          The criteria for "important" are not published. After you have
          checked whether the bug is already listed, you can submit a bug
          report through:
          http://java.sun.com:80/cgi-bin/bugreport.cgi

          You can also send in an RFE (Request For Enhancement) or
          ease-of-use issue there. You can even vote on the priority you
          would assign to a particular bug fix! Join the Java developer
          connection (it's free) by going to http://java.sun.com/jdc Then
          browse webpage
          http://developer.javasoft.com/developer/bugParade/#votes

     1.6 Is there a Java port to Windows 3.1?
        o A. Yes, several. IBM's ADK1.02 is available at the following
          locations:
             + http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html
               http://www.alphaworks.ibm.com/formula

          Netscape Navigator for Win3.1 has Java support. Java will never be
          well-supported under Win3.1 because Win3.1 lacks the basic
          features expected of a modern OS (primarily lengthy filenames and
          multithreading support). See also Q1.13.

          You could also consider JavaSoft's JavaPC kit that converts a PC
          into a thin client Java system. Details are at
          http://java.sun.com/products/javapc/index.html. It is probably
          more for business users than personal PCs.

          Unlike the 16-bit versions of Netscape Navigator and Microsoft
          Internet Explorer, which provide a Java Virtual Machine that is
          only compliant with the JDK 1.02 API, the JavaPC software allows
          IS managers to deploy JDK 1.1 compatible Java applications on PCs
          running DOS and Windows 3.x.

     1.7 Where can I find information on Java 3D?
        o A. The Java 3D FAQ at
          http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html may have the
          answers you're looking for. It contains general information about
          Java 3D, as well as programming tips.

     1.8 What are the folks at project Gnu doing with Java?
        o A. Guava (the Gnu Java compiler) can be found at
             + http://http.cs.berkeley.edu/~engberg/guavac/

          Kaffe (a JVM) can be found at
             + http://www.kaffe.org

          See also http://www.oryxsoft.com/projects/gvm and
          http://www.hungry.com/products/japhar (Now one merged project).

     1.9 Where can I find information about Java Certification?
        o A. Sun is sponsoring an examination which programmers worldwide
          can take. Those passing can use the designation "Sun certified
          Java Programmer". There is also a second level test, involving
          writing a program to spec, and taking a further test. That results
          in the qualification "Sun Certified Java Developer". You can find
          out all about the exam at:
             + http://www.sun.com/service/suned/

          and then search for "sun certified java". It costs $150 to sit the
          Java Programmer exam. It is not trivial to pass the Java
          certification exam. It requires understanding the objectives of
          the test, and the material that is tested for. These are given,
          along with sample questions, at the URL mentioned above.

     1.10 I'm looking for a Java style guide on naming conventions.
        o A. Check out the section "Naming Conventions" in the language
          specification
             + http://java.sun.com/docs/books/jls/html/6.doc.html#11186

          Also take a look at Doug Lea's draft coding standard -
             + http://gee.cs.oswego.edu/dl/html/javaCodingStd.html

          See also Q3.25 for some basic rules of thumb.

     1.11 Where can I find information about future Java APIs?
        o A. JavaSoft has followed a policy of creating new APIs in
          consultation with leading industry participants, then posting the
          draft specification for public review and comments. Check the
          JavaSoft roadmap of new APIs and products at
          http://Java.sun.com:80/products/api-overview/index.html
          Also, some APIs that are under consideration, possibly for JDK 1.2
          are at:
             + http://java.sun.com/products/jdk/preview/docs/

     1.12 How can I find links to recent news about Java?
        o A. http://lightyear.ncsa.uiuc.edu/~srp/java/javanews.html This
          site contains links to late-breaking online news stories about
          Java. Highly recommended. Also http://www.roaster.com/news/ is a
          good Java news source.

          This site is a source of independent news and commentary on the
          computer industry, including Java.
          http://www.pjprimer.com/media.html. (You have to subscribe
          ($10/year, 30 day free trial).

     1.13 What computers have Java ports?
        o A. A list of JDK ports is available from
             + http://java.sun.com/cgi-bin/java-ports.cgi

     1.14 What IDEs (Integrated Development Environments) are there?
        o A. Some popular IDEs include:
           Apptivity 2.0 (Progress) http://www.apptivity.com
           CodeWarrior Professional http://www.metrowerks.com
           GRASP (product is free)  http://www.eng.auburn.edu/grasp
           Java WorkShop 2.0 (Sun)  http://www.sun.com/workshop/java
           Javelin, Visual Object
           Development for Java     http://www.stepahead.com.au
           JBuilder (Borland)       http://www.borland.com/jbuilder
           JDE for emacs            http://sunsite.auc.dk/jde/
           Kawa 2.52.01 (Webcetera) http://www.tek-tools.com/kawa
           PARTS alpha (ObjectShare)http://www.objectshare.com
           PowerJ ? (Sybase)        http://www.sybase.com/products/powerj
           SilverStream             http://www.silverstream.com
           Super Mojo (Penumbra)    http://www.penumbrasoftware.com
           SuperCede 2.0 (Asymetrix)http://www.supercede.com
           teikade 1.8R2 (PFU Ltd)  http://www.pfu.co.jp/teikade
           Together Java ? (?)      http://www.oi.com
           Visaj 1.0.1 (Imperial SW
           Tech)                    http://www.imperial-software-tech.co.uk
           VisualAge 1.0 (IBM)      http://www.software.ibm.com/ad/vajava
           Visual Cafe 2.1
           (Symantec)               http://cafe.symantec.com
           Visual J++ (Microsoft)   (non-standard; not recommended)
           Xelfi 0.94               http://www.xelfi.com

     1.15 What is "San Francisco"?
        o A. San Francisco is the code name for a very large Java project
          led by IBM, and involving other companies. The project is to
          provide a Java framework for data processing applications. The
          basic classes are provided for general ledger, sales order,
          inventory management, etc etc, and these classes can be extended
          and customized for particular industries (vertical markets).

          IBM's SF project competes with products from companies like SAP
          and Baan. Of course, the SF project is multi-platform and uses
          Java beans and GUI interfaces. More information on SF is available
          at http://www.ibm.com/Java/Sanfrancisco

     1.16 What large Office-style applications have been written in Java?
        o A. Well, the first one to consider is IBM's San Francisco project,
          mentioned in the answer to Q1.15. There is also Lotus's e-suite -
          a suite of Java applets and beans including a spreadsheet and a
          word processor. These became available in March 1998. Another
          office suite in Java is Applix Anyware at
          http://www.applix.com/anyware/index.htm. Applix became available
          in downloadable demo form in April 1998.

          However the niche for single user office productivity applications
          is pretty well already dominated by Microsoft products, and it is
          unrealistic to think that Java software will unseat shrink-wrapped
          software simply because it is written in Java. This is why Corel
          replanned its Java rewrite of Corel Office before taking it to
          FCS. When Corel did that, it also increased its investment in Java
          from 33% of R&D budget to 50%, at the expense of Windows.

          Most of Java development is taking place for custom applications
          internal to a company. Most programmers of any kind have never
          worked on MS Office, but work on internal applications, and so it
          is with Java. These projects don't have the high profile of major
          vendor's products, but they are the mainstay of the industry.

                             -------------------

2. COMPILERS, ETC.

   * 2.1 Why did I get an OutOfMemory error when porting working code from
     jdk 1.02 to 1.1
        o A. The preset memory limit has changed. It went down to 16Mb so as
          not to penalize low memory machines. You can adjust it with
             + java -mx32m Frotz

          to get a 32Mb extent.

          Also see the Runtime methods freeMemory() and totalMemory().

     2.2 Why do I get a "Statement not reached" error from javac for no
     apparent reason?
        o A. JDK1.0 has a limit of 63 words of storage for local variables
          in any method. longs and doubles require two words of storage, and
          all other primitive types and all reference types require one
          word. If you assign values to more than 63 words of local
          variables, you will get a "Statement not reached" error on the
          statement after you assign to the variable that contains the 64th
          word. In JDK 1.1, the low limit was removed.

     2.3 Is there a lex and yacc or preferably a flex and bison equivalent
     for Java?
        o A. There is a lex equivalent called JavaLex and a yacc equivalent
          called CUP.

          LALR(1) parser
             + JavaLex and JavaCup:
               http://www.cs.princeton.edu/~appel/modern/java/

          LL(k) parser
             + JavaCC: http://www.suntest.com/JavaCC/

     2.4 Where can I find a byte code obfuscator?
        o A. http://www.primenet.com/~ej/
          http://www.math.gatech.edu/~mladue/HoseMocha.java

          Some people have reported problems using these with JDK 1.1.

          This obfuscator has been updated to be fully compatible with JDK
          1.1: http://www.monmouth.com/~neil/Obfuscate.html

          Obfuscators are intended to foil decompilers. Decompilers
          translate byte code back into Java source code. Mocha was the
          first and most well known of the decompilers; it's no longer
          supported. There is a decompiler (written in C++) at
          http://web.unicom.com.cy/~kpd/jad.html Because it is in C++, there
          are different versions for every architecture (hah!) There are
          also commercial products, such as SourceAgain from
          http://www.ahpah.com

          There's a very good Java Code Engineering and Reverse Engineering
          FAQ page at http://Meurrens.ML.org/ip-Links/Java/codeEngineering/.

     2.5 Which program is used to create .zip files compatible with the
     java* programs? (eg classes.zip, moz3_0.zip)
        o A. Use the jar-tool from JDK1.1(.1):
             + jar [ options ] [manifest] destination input-file
               [input-files]

          E.g.:
             + jar cvf myJarFile.jar *.class

          creates a compressed archive
             + jar cvfO myJarFile.zip *.class

          creates it fullsize (uncompressed) (note the 'O'-option used for
          JDK1.0.2)

          On Unix you can also use:
             + zip -rn ".class" my_file.zip *

          Info-ZIP home page: http://www.cdrom.com/pub/infozip/
          Latest source code:
          ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip

          Netscape's command line version of its JAR packager and signing
          tool is called "zigbert". They also have a signing tool with GUI
          written in Java. More info at:
             + http://developer.netscape.com/software/signedobj/jarpack.html

          If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a
          Jar)
             + 1. zip your files uncompressed (can use WinZip 6.2 up);
                  + Unix command: zip -r0 classes.zip <directories>

               2. Make sure the main class has no parent directory inside
               the archive, (in other words, don't build an archive with
               foo/bar/myMain.class, unless your myMain is in a package
               called foo.bar. Instead start it at myMain.class). Your
               packages must be placed in the archive using their
               corresponding filesystem pathnames.

               3. Put the archive in the same directory as the .html page;

               4. Put something like the following tag in the .html file:
                  + <APPLET CODEBASE="."
                    ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip
                    CODE="my_main_class.class"
                    WIDTH=600 HEIGHT=250>
                    </APPLET>

          From JDK 1.1 on, an example of the applet tag used with a jar file
          is
             + <APPLET ARCHIVE=myfile.jar
               CODE=myapplet.class
               WIDTH=600 HEIGHT=250>
               </APPLET>

          These lines will use an applet called myapplet that can be found
          in the jarfile myfile.jar. An example applet tag of a jar file
          used to hold classes in packages is

          <APPLET ARCHIVE="myclasses.jar"
                   CODE="linden.net.MyApplet.class"
                   WIDTH=480
                   HEIGHT=120>
          </APPLET>

          You can supply several jar filenames in a comma-separated list.
          Jar files are in compressed PKZIP format.

     2.6 Can I compile a Java program to a binary executable, .exe on a PC?
        o A. Some companies make products that do this. See the webpages for
          Symantec http://www.symantec.com, Supercede www.supercede.com, and
          Tower Technology http://www.twr.com. The first two are targetted
          to Windows. Tower Technology supports several flavors of Unix.
          Also, there is a native Java compiler from IBM, known as the HPJ
          (High Performance Java) compiler. One user has reported that it
          created a 2Mb executable from a 12K java file, and did not run any
          faster. If you want to create a native executable to make
          executable use and distribution easy, consider a Jar file instead.

          Compiling to native code takes away the most significant benefit
          of Java: portability of executables. Further, if you want your
          Java DLL (or .exe) to interact with C++, you'll have to specify
          which specific C++ compiler and/or actually compile some sort of
          linkage via the appropriate C++ compiler. Because C++ does not
          have a standard ABI there is a big problem with interoperability.
          Every C++ compiler uses a different object model, a different way
          of laying out class members, and a different way of "mangling"
          names for the linker.

          C is much simpler. The only question here is how structures are
          "packed" (i.e., are integers aligned on four-byte bounds?). All
          the C++ compilers can interact with C code, thanks to 'extern "C"'
          declarations.

          Consider carefully why you want to compile to a native executable,
          and whether there is a Java way to accomplish your goal. There may
          be a good reason for compiling to native code, but it needs to be
          thought through.

     2.7 How can I performance profile my Java code?
        o A. java -prof MyClass

          produces some basic output in a file called java.prof, showing the

          number of times methods were invoked. The output lines are of the
          form:

              # of calls     method called      called by        time spent

          On a Unix system, you can sort the file with something like
             + sort -r +82 <java.prof > java.sort

          More and better Java tools are a third party opportunity. One Java
          profiler is JProbe Profiler, available from
          http://www.klg.com/jprobe. JProbe is said to be easy to use.
          Another profiler is OptimizeIt, available from
          http://www.optimizeit.com. Each of these profilers has performance
          tuning, which shows which methods took how much time, and also
          memory tuning, which shows what objects are in memory and how they
          were allocated. Both are important things to know. The latest
          version of the CodeWarrior IDE http://www.metrowerks.com has a
          time-based profiler for Java code. Java Workshop from Sun also has
          a time-based profiler.

     2.8 When I use javadoc and I click on any java class included in the
     jdk why do I get this message?
     Netscape is unable to find the file or directory named:
        o /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html

          A. References to the JDK classes assume that *all* generated html
          files are in the same directory and, in fact, that all files for
          all classes referenced are generated at the same time. There is no
          way to generate files incrementally and have them all reference
          each other, as you would like.

          As long as you have source for everything involved (including the
          JDK and all third-party classes), you can list all of your
          packages and all of the others on the javadoc command line and
          generate the whole set at once, but it is burdensome. Of course,
          if you receive any libraries as .class files, even this workaround
          will not suffice.

          Also javadoc will not generate the image files - you need to get
          them from the images directory under the JDK API documentation
          files. You can just copy the entire directory into your own doc
          directory. javadoc is a very nice concept, with a few
          implementation flaws.

     2.9 I'm working on a project with lots of classes and I use the JDK. A
     recompile from scratch takes forever when I do it a class at a time.
     How do I recompile everything?
        o A. The first way is
             + javac *.java

          Another way is
             + javac -depend tip.java

          where "tip.java" is a class "at the tip of the iceberg", i.e. that
          depends on (uses) all the other classes. Typically, this may be
          your main class. However, "-depend" is known to be buggy and
          cannot be relied upon. It also doesn't issue compile commands in
          parallel to make use of multi-processor systems.

          Without the "-depend" option, the standard "javac files" doesn't
          look beyond the immediately adjacent dependencies to find classes
          lower down the hierarchy where the source has changed.

          The -depend options searches recursively for depending classes and
          recompiles it. This option doesn't help when you have dynamically
          loaded classes whose names cannot be determined by thecompiler
          from the dependency graph. E.g. you use something like
             + Class.forName(argv[0]);

          The author of the code using those classes should make sure that
          those classes are mentioned in a Makefile.

     2.10 Why do I get the java.lang.UnsatisfiedLinkError when I run my Java
     program containing Native Method invocations?
        o A. Your program is not able to find your shared library or DLL.

          On Windows 95/NT, make sure that the DLL exists in a path that is
          included within the PATH environment variable. (This need is true
          for both standard (untrusted) applications and trusted applets. At
          least, if you use the Java Plug-in to give yourself standard Java
          inside a browser).

          On Solaris, make sure that the environment variable
          LD_LIBRARY_PATH includes the path of your shared library.

     2.11 An anonymous class can't seem to access a private outer method.
     Why is that?
        o A. It's a known bug in the JDK 1.1.4. The code is:

          public class MyDialog {

            void Setup() {
              addWindowListener( new WindowAdapter() {
                    public void windowClosing(WindowEvent e) {
                           myCloseWindow(); } }
                   );     // anon inner class
              }

            void CloseWindow() {   // outer method
              dispose();
              }
          }

          This code sends javac into an infinite loop. The workaround is to
          make the private method non-private, or to make the inner class a
          named class.

     2.12 What are the major Java releases and their contents?
        o A. There have been two Java releases from Sun so far, plus a
          number of bugfix (dot-dot) releases. The releases are:
             + JDK 1.0.2
               This was the release FCS in May 1996. It had some security
               fixes over JDK 1.0.
             + JDK 1.1
               This release introduced a new event model in the window
               system. It also made JDBC support and beans support a
               standard feature. It changed and standardized the native code
               interface to JNI. It also introduced inner classes.
             + JDK 1.2
               This release (due Fall 1998) made the Swing library a
               standard feature. Swing is a set of rich platform-independent
               graphical components.

                             -------------------

3.LANGUAGE ISSUES

   * 3.1 Why doesn't my "hello world" program work?
        o A. Common causes of failure are:
             + First, did you write an applet or an application? If an
               applet, you must make sure that you did extend the
               java.applet.Applet class. You must declare your class that is
               extended from Applet as "public". If you don't, unfortunately
               some browsers will still run the code, while others won't.
             + Your class name and the file name must match exactly, even
               letter case. If your class is HelloWorld, your source file
               must be HelloWorld.java
             + In JDK 1.0.2 the $CLASSPATH environment variable should
               include "." the current dir.

          In JDK 1.1, users are no longer required to set the CLASSPATH to
          point to the classes.zip file, and in fact the README advises
          users not to set it.

          From JDK 1.1.2 on, it is generally an ERROR if the user sets the
          CLASSPATH to include classes.zip. CLASSPATH is only needed to
             + point to the roots of the programmers own packages,
             + use rmic
             + use unbundled packages like Swing in JDK 1.1
             + point to native code libraries.

          If you're not doing any of these, do not set CLASSPATH. If you
          have set it, unset it.

     3.2How can I program linked lists if Java doesn't have pointers?
        o A. Of all the misconceptions about Java, this is the most
          egregious. Far from not having pointers, in Java, object-oriented
          programming is conducted exclusively with pointers. In other
          words, objects are only ever accessed through pointers, never
          directly. The pointers are termed "references" and they are
          automatically dereferenced for you.

          Java does not have pointer arithmetic or untyped casting. By
          removing the ability for programmers to create and modify pointers
          in arbitrary ways, Java makes memorymanagement more reliable,
          while still allowing dynamic data structures. Also note that Java
          has NullPointerException, not NullReferenceException.

          A linked list class in Java might start like this:
             + public class linkedlist {
               public linkedlist head;
               public linkedlist next;
               public Object data;
               public linkedlist advanceToNext(linkedlist current) { ...
               ... }

          Another choice for a linked list structure is to use the built-in
          class java.util.Vector which accepts and stores arbitrary amounts
          of Object data (as a linked list does), and retrieves it by index
          number on demand (as an array does). It grows automatically as
          needed to accommodate more elements. Insertion at the front of a
          Vector is a slow operation compared with insertion in a linked
          list, but retrieval is fast. Which is more important in the
          application you have?

     3.3What is the true story about how parameters are passed in Java? Is
     is by value or by reference?
        o A. All parameters (values of primitive types, & values that are
          references to objects) are passed by value [JLS sect 8.4.1].
          However this does not tell the whole story, as objects are always
          manipulated through reference variables in Java. Thus one can
          equally say that Objects are passed by reference (and the
          reference variable is passed by value). This is a consequence of
          the fact that variables do not take on the values of "objects" but
          values of "references to objects" as described in the previous
          answer.

          Bottom line: primitive type arguments (int, char, etc) _do not_
          change when the corresponding parameter is changed. The fields of
          object type arguments _do_ change when the corresponding parameter
          fields are changed.

     3.4 How, then, can I pass an object to a method, and have the method
     change the reference so it points to a different object back in the
     calling code?
        o A. There are two ways. The obvious way is "just add another level
          of indirection" -- wrap the object in another class, whose purpose
          is simply to be passed as a parameter, allowing the nested object
          reference to be modified.

          The second alternative is a clearer variant of this. Pass in a
          single element array. Since arrays are objects, this works.
             + void jfoo(Object ref[]){
                   ref[0] = new Object();
               }

               ...

               Object kludge[] = new Object[1];
               kludge[0]= myObj;
               jfoo(kludge);
               if (kludge[0] == myObj) ...
               else ...

          Note that changing a global variable/object inside a method is an
          egregious programming practice -- it usually violates basic OOP
          constructs.

     3.5Why is String a final class? I often want to override it in some
     way.
        o A. There are several reasons.

          The simplest is that being final guarantees that instances of
          String are immutable. (The String class implements immutable
          objects, but if it were not final it would be possible to write a
          subclass of String which permitted instances to be changed.) But
          that's an unsatisfying answer,
          because the real question is "Why must Strings be immutable?"

          One reason is efficiency. It's easier to optimize accesses to an
          object that is known to be immutable. Strings are very commonly
          used, even used behind the scenes by the Java compiler. Efficiency
          gains in the String class can yield big dividends. If no one can
          change a String, then
          you never have to worry about who else has a reference to your
          String.

          A more compelling reason is security. Before String was changed to
          be final (while Java 1.0 was still in beta) there was a race
          condition which could be used to subvert security restrictions. It
          had to do with having one thread change a pathname while another
          thread was about to open it.

          There are other ways to solve these problems, but making String
          final is the one that the designers chose.

     3.6What happened to "private protected"?
        o A. It first appeared in JDK 1.0 FCS (it had not been in the
          Betas). Then it was removed in JDK 1.0.1. It was an ugly hack
          syntax-wise, and it didn't fit consistently with the other access
          modifiers. It never worked properly: in the versions of the JDK
          before it was removed, calls to private protected methods were not
          dynamically bound, as they should have been. It added very little
          capability to the language. It's always a bad idea to reuse
          existing keywords with a different meaning. Using two of them
          together only compounds the sin.

          The official story is that it was a bug. That's not the full
          story. Private protected was put in because it was championed by a
          strong advocate. It was pulled out when he was overruled by
          popular acclamation.

     3.7 I extended the class called Frotz, and the compiler is giving me an
     error message "No constructor Frotz()" in the child class. Why?
        o A. When you define a constructor for a class, unless you
          explicitly call the superclass' constructor at the start, a call
          to the superclass' parameterless constructor is implicitly
          inserted. The problem you're seeing is what happens when the
          superclass doesn't *have* a parameterless constructor. The
          solution is usually to call the correct version of the superclass'
          constructor with the right parameters.

     3.8 Why does <unexpected> happen inJava floating point?
        o A. There are several unexpected things that seem to bite
          programmers with floating point. Invariably this is a result of
          the programmer not being fully conversant with FP, rather than
          some fault in Java.

          If you seem to be having problems with floating point, your
          problem probably stems from the fact that floating-point
          arithmetic is inherently imprecise. You can expect up to 7 digits
          of precision with floats and 16 digits with doubles. However, that
          does not mean that a number that can be exactly represented in 7
          digits decimal, can be exactly represented as a binary floating
          point number. On the contrary, that is usually not the case.

          Additionally, when Java converts floating point numbers to a
          String, as is done when they are output, enough digits are printed
          so the number can be read back in with no loss of precision. For
          this reason, you may see more "inaccuracies" in floating point
          output than you are used to. This policy actually gives you more
          consistent results than on a system where floating point output is
          deliberately rounded to make the output "pretty".

          There is a limitation of FP in JDK 1.0 (fixed in JDK 1.1). Namely,
          when you output a floating point number in Java 1.0, the result is
          system-dependent and contains no more than six digits after the
          decimal point. This bug is fixed in Java 1.1.

          For more information and detailed specifications on how Java deals
          with floating point, see the following URLs:
             +

     http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities

     http://java.sun.com/doc/language_specification/javalang.doc.html#1466
     http://java.sun.com/doc/language_specification/javalang.doc.html#5899

   *
        o If you want the rounded floating point output that most languages
          have, use the new java.text package of Java 1.1 to limit the
          number of digits that are output. If you need more precision than
          about 16 digits, use the BigInteger and BigDecimal classes of Java
          1.1.

     3.9 may not have been initialized">Why do I get the compiler error
     message
        o urltest.java:8: Variable test may not have been initialized.
             + URL test;
               try { test = new URL("http://osprey.avs.dec.com");
               } catch (MalformedURLException e) {
                     System.out.println("bad URL:" + e.getMessage());
               }
               System.out.println("this is url " + test);

          A. If an exception is raised in the try clause, test will not be
          given a value, yet you are using it in the catch clause. The
          solution is to declare test with an explicit initial value of
          null.

     3.10 Why do I get this compiler error message?
        o public static void main(String[] args) {
          ^
          Statement expected.
          public static final float Conversion_Factor = 39.37;
          ^
          Type expected.

          A. A. Argument declarations and variable declarations inside
          methods are never given the "public", or "static" keywords. They
          are not public or static because they are local to a method. (They
          used not to be allowed the "final" keyword either, but there was
          not good reason for that restriction and it was dropped in JDK
          1.1). Move your public or static declarations outside the method.
          They are usually put at the beginning of the class.

     3.11 Why do I get this compiler error message?
        o MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
          found in class MyCheckbox.

          bp1 = new MyCheckbox(this);
          ^
          1 error

          A. The first thing to check is whether you gave a return value to
          the constructor, like this:
             + public void MyCheckbox( Container parent )

          If you did, the compiler will think it is an ordinary method, not
          a constructor. This is a very common mistake, and quite hard to
          spot.

     3.12 Why do I get the compiler error message

T.java:96: Can't access protected method clone in
class java.lang.Object.  OtherT is not a subclass of
the current class.

   *
        o A. The method clone() is protected. It is protected because
          cloning is an operation which the object might want to restrict
          access to. If Object.clone() was declared as public, the object
          could never decide to make it more restrictive later. By declaring
          it protected, the object has the choice of making it less
          restrictive.

          This means that a method can clone its own objects, but a method
          cannot clone objects of another class, unless you do something
          like:

          class SomeObject implements Cloneable {
           public Object clone()
                      throws CloneNotSupportedException {
           return super.clone();
           }
          }

          [i.e. override clone to make it public, and call the superclass
          clone].

          class Foo {
           Bar bar;

           Foo (Bar b) {
           try {bar = (Bar) b.clone();}
           catch (Exception e) {}
          }
          ...

          class Bar implements Cloneable {
           public Object clone()
                 throws java.lang.CloneNotSupportedException{
           return super.clone();
           }
          }

     3.13 How do you transform a char into the corresponding int value, that
     represents the code value of the char?
        o A. char c = 'A';
          int i = c;

          Going the other way is just
             + c = (char) i;

          This question crops up so frequently because the BASIC language
          uses functions to map characters into ints, ASC( 'A' ) => 65
          causing BASIC programmers to seek the corresponding Java
          functions. Pascal and Ada have similar functions, and no doubt
          other languages too.

     3.14 If I extend a class with a subclass, are the constructors
     inherited?
        o A. "Constructor declarations are not members. They are never
          inherited and therefore are not subject to hiding or overriding."
          The default constructor is not inherited, but provided (see
          Section 8.6.7, JLS).

          If you don't give your child class any constructors, a default
          no-arg constructor that invokes the superclass' constructor is
          provided for you. If the superclass doesn't have a no-arg
          constructor, see 3.7

     3.15 How do I allocate a multidimensional array?
        o A. There are several ways. If you want a rectangular array, you
          can allocate the space for the array all at once. The following
          creates a 4x5 array:
             + int arr[][] = new int[4][5];

          If you want each row to have a different number of columns, you
          can use the fact that a two-dimensional array is actually an array
          of arrays. The following code allocates a triangular array:
             + int arr[][] = new int[4][]; // allocate the four row arrays
               for (int i = 0; i < 4; i++) // initialize each of the four rows
               arr[i] = new int[i + 1]; // row i has i + 1 columns

          Note that if you allocate an array of any kind of object (as
          opposed to primitive type), all the references will be null by
          default. These null references can result in NullPointerExceptions
          if you try to dereference them.

          In other words, after doing:
             + int arr[] = new int[4];

          you can say "if (arr[2] == 0)"

          But after doing
             + Integer Iarr[] = new Integer[4];

          you must fill in the object reference before using it, with e.g.
             + Iarr[2] = myInt;

          or
             + Iarr[2] = new Int(27);

          before you can say "if (Iarr[2].equals(myInt))"

     3.16 Does it make a difference to the class file in any way, if I
     import a package versus use the full name, i.e.
        o import java.rmi.server.*;
          RemoteObject ro;

     versus:
        o java.rmi.server.RemoteObject ro;

          A. No, it makes no difference to the class files. Import is just a
          shorthand for quoting the full name package and class name (as in
          the examples in the question). Importing a class does not cause
          the class to be loaded at run time. There is no run time penalty
          for using the * form of import. The class file will contain the
          name of the packages it uses, and the loader will look for those
          classes as needed at runtime.

          The different forms of import may or may not make a difference to
          compile time. Such a difference is likely to be negligible, and
          should not be a factor in which form of import you use.

          Some people say that stating which classes you are importing can
          help program readability. In a program with many * import
          statements, it may take a programmer time to find which package an
          obscure class is imported from. If you explicitly list each class
          you import at the top of the
          program, you document which package each class you use comes from.
          These people suggest that you use
             + import java.rmi.server.RemoteObject;

          in preference to:
             + import java.rmi.server.*;

          Other people say that it is clearer still to use the full package
          and class name, at the point where you use classes in other
          packages. These people suggest that you use:
             + java.rmi.server.RemoteObject ro;

          But that gets a little lengthy when you instantiate:
             + java.rmi.server.RemoteObject ro
                 = new java.rmi.server.RemoteObject();

          You always have the option of stating the full package and class
          name, whether you use import or not.

          Another good reason not to use the * form is when you are
          importing two packages that have classes of the same name and you
          want to use only one of those classes. E.g.
             + import com.sun.*;
               import com.ms.*;

          where there is a class called SerialPort in both those packages.
          If you use the * form of import, you import both of the SerialPort
          classes and then must fully qualify the class each time you use
          it, to say which of the two you mean.

          In Java 1.0, if you import a class that has the same name as a
          class defined in that source file, you will get an error that the
          class names clash. In Java 1.1, the local class will be used when
          the package name is not given; use the package name of the
          imported class to use it.

          The best advice is to write the program so that it is as readable
          as possible. Where you have a group of well known classes, as in
          java.awt, there is no reason not to use "import java.awt.*;"

     3.17 What are "class literals"?
        o A. A feature introduced in JDK 1.1. They are literals of type
          "Class" that hold a value representing any class. There are even
          values to represent "void" and an array, like this:

          Class myCl1 = Character.class;
          Class myCl2 = Void.class;
          Class myCl3 = Object.class;
          Class myCl4 = String[].class;
          Class myCl5 = int[][].class;

          You might use it like this:

          Class cl = thing.getClass();
          if (cl.equals(myCl1))
           System.out.println("It's a Character class");

          A class literal
             + Component.class

          is the equivalent of
             + Class.forName("java.awt.Component")

          The second can throw an exception, but the first cannot. If you
          don't know the name of the class when you write the code, you
          cannot use the first form.

     3.18 How do I copy the contents of an array (with primitive type
     contents) to another array?
        o A. Use the method java.lang.System.arraycopy(Object src, int
          src_position, Object dst, int dst_position, int length);

          Note that there is no corresponding method to clear an array to
          0.0, 0, null, false, '\u0000' etc (except for allocating a new
          array, which will have the default initializations). This has lead
          several people to suggest the old COBOL trick of "initialize by
          rollup". In initialize by roll-up, the programmer sets the first
          element of the array to the desired value, and then moves elements
          array[0 to n-1] to array[1 to n]. Under some old IBM COBOL
          compilers, code was generated to move element 0 to 1, then 1 to 2,
          and so on, "rolling up" the desired value through the array.
          Although it went outside the boundaries of defined behavior in
          COBOL, on S/360 computers and their successors. this could compile
          into a single machine instruction. The roll-up behavior was
          documented by IBM, and the technique was common enough that it was
          worth optimizing the trick in microcode.

          In any event, initialization by roll-up is defined not to work in
          Java. If the src and dst arguments refer to the same array object,
          then the copying is performed as if the components at positions
          srcOffset through srcOffset+length-1 were first copied to a
          temporary array with length components and then the contents of
          the temporary array were copied into positions dstOffset through
          dstOffset+length-1 of the argument array.

          If you simply want to clear the same array to the same value many
          times, create two arrays. Fill one with the reset value, then use
          System.arraycopy to copy it into the work array each time you need
          to clear the work array.

     3.19 What is a fast way to set all elements of an array to a given
     value without duplicating the (possibly large) array?
        o A. Using a loop that does it one by one is probably 20 to 40 times
          slower than good-old memset() in C.

          A fast way on many VM's is to set the first byte of the array,
          then use System.arraycopy repeatedly to fill the next byte, the
          next two bytes, the next four bytes, the next eight bytes, etc.
          (Note these are not overlapping slices, so the issue raised in
          Q3.18 does not arise).

          public static void bytefill(byte[] array, byte value) {
           int len = array.length;
           if (len > 0)
           array[0] = value;
           for (int i = 1; i < len; i += i)
           System.arraycopy( array, 0, array, i,
           ((len - i) < i) ? (len - i) : i);
          }

          This is faster on Sun's VM than a simple loop, and probably faster
          even under JITCs because it only performs log2(array.length)
          bounds-checks at most. This is a clever code idiom applying the
          binary chop algorithm to arrays whose size is not a power of 2.

     3.20 Is there some declaration that I can use to make "acos", "cos",
     "sin", etc. (from java.lang.Math) recognizable in my own class, so I
     don't have to prefix "Math." to them?
        o A. No. There is no good alternative. There are several bad
          alternatives:
             + You could wrap the functions in your own class.
                  + double sin(double x) {
                        return Math.sin(x);
                    } // etc. for each function

               If your class does not extend another class, you could make
               it extend Math, to bring the namespace in, but this is very
               poor OOP style.

               If the Math class provided a public constructor -- which it
               does not -- you could instantiate a local copy of Math with a
               shorter name, e.g. "M". There is a cheating way to do this
               which works because all the methods are static. Declare

               java.lang.Math  M = null;

               angle = M.cos(i);

               Please don't do this.

               If java.lang.Math were not final and your class did not
               extend another class, you could have your class extend Math,
               to bring the namespace in. However, the final prevents this
               and it is very poor OOP style to use inheritance to obtain a
               trivial name abbreviation (rather than to express a type
               hierarchy).

          The import stament only imports packages, subpackages, and
          classes. Members of classes are not imported, so
             + import java.lang.Math.*;

          doesn't work.

     3.21 Why does b >>>= 1 give me the same result as b >>= 1?
        o A. First of all, note that ">>" is a "signed" or "arithmetic"
          shift, namely, it replicates the sign bit on the left as it
          shifts.

          The ">>>" operator is an "unsigned" or "logical" shift; it does a
          shift right and zero fill. However, there are a couple of places
          where ">>>" looks like it does a signed shift!

          The issue occurs when you have a non-canonical type, byte, or
          short, with a negative value, e.g.
             + byte b = -15; // 0xF1
               b = (byte) b >>> 4; // why isn't b 0x0f ?

          The initial expectation is that an unsigned shift right of 0xF1
          would successively be (in binary) 0111_1000 then 0011_1100 then
          0001_1110 then 0000_1111

          But that doesn't happen. The rules of arithmetic in Java say that
          all operands are converted at least to int before the operation
          (and possibly to a more capacious type). That means our byte is
          promoted to an int, so instead of shifting 0xf1, we are shifting
          0xfffffff1. If you shift right unsigned 4 places, you get
          0x0fffffff. When you cast that to a byte it becomes 0xff, or -1.

          The bottom line is that the final result is the same as if you'd
          performed the signed shift because the unsigned shift applied to
          the intermediate int, not to the original byte. This anomaly means
          that ">>>" is useless for negative bytes and shorts. It is
          probably safer and clearer not to use it at all, but to mask and
          shift like this:
             + // not recommended
               byte b = -15;
               b = (byte) (b>>>4);
               System.out.println("b= "+Integer.toHexString(b) );

               // recommended

               b= -15;
               b = (byte) ( (b & 0xFF) >> 4 );
               System.out.println("b= "+Integer.toHexString(b) );

     3.22 How do I compare two Strings together?
        o if (s1 == s2)

          is giving me funny results.

          A. The comparison using "==" on objects, like Strings, is asking
          the question "do these two objects have the same reference?". That
          is, do they have the same address, and hence are the same object?
          What you really want to do is ask "do these two Strings have the
          same *contents*?"

          You do that with any of (and there are others too)
             + if (s1.equals(s2) )

               or if (s1.equalsIgnoreCase(s2) )
               or if (s1.startsWith(s2) )
               or if (s1.endsWith(s2) )
               or if (s1.regionMatches(s1_offset, s2, s2_offset, length) )
               or if (s1.compareTo(s2) < 0)

          Note that you can do this with literals:
             + if ("apple".equals(s2) ) ...

          If you compare these the other way round, like this:
             + if ( s2.equals("apple") ) ...

          and s2 is null, you will get a null pointer exception. Be alert to
          this.

     3.23 How can I be type-safe without having to create a multitide of
     subclasses (IntegerLinkedList, StringLinkedList, etc.)?
        o A. Generic programming in java (the rough equivalent of C++'s
          templates) works reasonably well since all java classes are
          subclasses of Object. There is, however one potential problem -
          there is always a possibility that a generic container may contain
          different classes of objects.

          This naturally leads to the question of how to do this in a
          type-safe way. If you've created a generic LinkedList class, how
          can you be type safe without having to create a multitide of
          subclasses (IntegerLinkedList, StringLinkedList, etc.)?

          One way to handle this would be to offer up an additional
          constructor in your generic class that takes a parameter of type
          "Class" and uses that parameter along with Class's "isInstance"
          method to guarantee that Objects added to the container are the
          expected type.
             +  public class LinkedList
                  {
                     protected Class type = Object.class;

                     public LinkedList(Class type) { this.type = type; }

                     public void addElement(Object element) throws Exception
                     {
                        if(!type.isInstance( element ))
                           throw new Exception(
                              "Expected element of type (" + type +
                              ") got element of type (" + element + ")");

                        ...
                     }
                  }

          Note that the comments in the source for isInstance() refer to a
          "specified Class parameter", suggesting that you are supposed to
          write something like:
             +  public void addElement(Object element) throws Exception
                     {
                        Class c = element.getClass();
                        if(!type.isInstance(c))

          This works, but the documentation for isInstance is clear that the
          parameter should be an Object rather than a Class. Also, be aware
          of "Collections" that are coming in JDK 1.2. More information
          about this is available at the Java Developer Connection at the
          Java website http://java.sun.com.

     3.24 Why is there a standard JNI?
        o A. JNI is the Java Native Interface. It defines the way that a
          Java program can call C programs. The industry has agreed on, and
          Sun has codified, JNI as the standard. Microsoft shuns the
          standard and uses a protocol of its own called Raw Native
          Interface, RNI.

          You might think that once a Java program uses JNI, portability is
          lost, and hence it doesn't matter if vendors diverge from the JNI
          standard. However, it does affect programmers and especially
          end-users. When you use native code, you lock your program into
          one platform (and other platforms if you port the native code).
          But programs that use native code should still be able to use a
          JVM, and other Java tools and libraries from any vendor. This is
          possible when everyone uses the same native code interface.

          Microsoft's non-standard RNI is the reason that programs using the
          Microsoft JVM cannot use the standard Java jdbc-odbc library. That
          library has a piece written in C. It works for all JVM's except
          Microsoft's.

          The standard JNI thus has two purposes:
             + Source code compatibility between different platforms.
             + Binary code compatibility between different JVMs on the same
               platform.

     3.25 What are the naming conventions in Java?
        o A. The naming conventions are straightforward:
             + 1. package names are guaranteed uniqueness by using the
               Internet domain name in reverse order: com.javasoft.jag - the
               "com" or "edu" (etc) part used to be in upper case, but now
               lower case is the recommendation.
             + 2. class and interface names are descriptive nouns, with the
               first letter of each word capitalized: PolarCoords.
               Interfaces are often called "something-able", e.g.
               "Observable", "Runnable", "Sortable".
             + 3. object and data (field) names are nouns/noun phrases, with
               the first letter lowercase, and the first letter of
               subsequent words capitalized: currentLimit
             + 4. method names are verbs/verb phrases, with the first letter
               lowercase, and the first letter of subsequent words
               capitalized: calculateCurrentLimit
             + 5. constant (final) names are in caps: UPPER_LIMIT

          Also see Q1.10.
          [Reference: Java Language Specification, section 6.8 Naming
          Conventions.]

     3.26 What are the differences between an interface and an abstract
     class?
        o A. The principal difference is that an abstract class is used when
          you have a type/subtype relationship. An interface does not imply
          a type/subtype hierarchy; it merely forces a class to have some
          methods with a given signature. That allows some other code to
          rely on being able to call those methods.

          Interfaces allow you to treat an object as an abstraction without
          having to know anything about its particulars. If, for example,
          you wanted to have a bunch of persistent objects on which you need
          to provide persistence services, these objects of many varying
          kinds would all in their individual ways implement a Persistent
          interface that prescribes a save() method. The persistence service
          simply treats each different object as a Persistent and calls
          save() on it. Each object of all the unrelated classes knows how
          to save() itself when told to do so. The service has no need to
          worry about the actual class of each object.

          You want to use abstract classes when you plan to have related
          subtypes that define the abstract behavior. The subclass should
          have a "kind of" relationship to the superclass. A user record is
          a kind of record, a dog is a kind of mammal, etc. Inheritance
          provides a "kind of" relationship.

          By way of contrast, an interface provides a "plays the role of"
          relationship. An image loader could play the role of an Observable
          thing. Just about any class could play the role of a "sortable
          thing". Interfaces therefore often have a name that is a
          "something-able thing". A class may only extend one other class,
          but it can implement an arbitrary number of interfaces.

          Abstract classes can have abstract methods and they can also have
          fully defined members. Interfaces can't have any code in them at
          all, though they can have final data. Another minor difference is
          that calls to a subclass method are faster than calls to an
          interface method (because the interface method involves a bit more
          lookup at runtime about what is actually being called).

     3.27 How do static methods interact with inheritance?
        o A. Static (per-class, rather than per-object) methods do not
          participate in overriding (choosing the right method at runtime
          based on the class of the object). Probably the best and simplest
          way to think about this (and to write your code) is to write every
          invocation of a static method using the fully qualified class name
          so:

          class A {
            public static method1() {
                A.method2();
            }
            public static method2() {
            }
          }

          class B extends A {
            public static method3() {
              A.method1();
            }
            public static method2() {
            }
          }

          Now it is perfectly clear that the static method2() that is called
          is A.method2(), not B.method2(). This is true regardless of
          whether you use the fully-qualified class name or not, but the use
          makes it obvious to all.

     3.28 How do I get unsigned ints in Java?
        o A. Java doesn't have unsigned ints. The reason is that this is a
          poorly designed area of C -- the rules for what type you end up
          with when you mix signed and unsigned in expressions are
          complicated -- and they changed between K&R and ANSI C (you might
          have heard this under the name "unsigned preserving vs. value
          preserving"). Worse, they depended on the underlying hardware, so
          they varied from platform to platform, causing bugs in all kinds
          of unexpected places. The book "Expert C Programming" goes into
          this in more depth (p25). So, to avoid bringing over the hidden
          complexities, Java does not bring over unsigned types from C.

          Use type char if you are ok with 16-bit unsigned quantities.
          Otherwise go to the next larger type and use masking.
          Specifically, to convert an int to its unsigned representation,
          use:

              ((long)i) & 0xFFFFFFFF

          This promotes the signed int to long and chops off the
          sign-extension, leaving it as an unsigned 32-bit quantity.

          Also worth noting is that if you're going to work with unsigned
          bytes, int is a more efficient larger type to use than short or
          char, since smaller values have to be promoted to int to do any
          arithmetic or testing on them.

     3.29 How do I send a variable number of arguments to a method, or get
     multiple return values back?
        o A. (Easy) Use method overloading to support different parameters.
          This makes things easy on the caller but can get out of hand if
          you want to support a wide number and variety of parameter types.
          You should ask yourself if your code design is well-organized if
          you need to do this.

          (More complicated) Use arrays. It's possible to declare arrays
          inline as shown below:

          foo("A param", new Object[] {"param3", "param4", new Integer(5)} );

                // ...

          void foo(String param1, Object param2[]) {
                  System.out.println(param1);
                  for (int i = 0; i < param2.length; i++) {
                        System.out.println(param2[i].toString());
                  }
          }

          You can even pass arrays of arrays using this method. Of course,
          inside the method you need to be able to decode what the arguments
          are and how you use them.

          Alternatively you can invent a class that just contains all the
          possible fields you might want to pass into a method (plus
          booleans to say if each field is set or not), and make an object
          of that class be a parameter to the method.

          You can return multiple values from a method the same ways; either
          have the method return an array or a wrapper object.

          Remember the wise words of Prof Alan Perlis however, "if your
          procedure has more than about half a dozen parameters, you
          probably forgot a few." Perlis meant that passing large numbers of
          arguments into a function suggests that your function is
          badly-organized.

                             -------------------
4.AWT and Related Topics

   * 4.0 AWT

   * 4.0.1Why do I get this when using JDK 1.1 under X Windows?
        o
             + java.lang.NullPointerException
               at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59)
               at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153)
               at java.awt.Frame.addNotify(Frame.java)
               at java.awt.Window.pack(Window.java)

          A. There's a missing font on your system. Move font.properties
          from the "lib" subdirectory aside to font.properties.bak Then it
          won't look for the font and fail to find it.

          The problem occurs because the Motif AWT libraries use the Font
          "plain Dialog 12 point" as a fall-back default font.
          Unfortunately, when using a remote X server sometimes this font
          isn't
          available.

          On an X-terminal, the diagnostic may be slightly different, a segv
             + % appletviewer HelloWorldApplet.html
               SIGSEGV 11* segmentation violation
               si_signo [11]: SIGSEGV 11* segmentation violation
               si_errno [0]: Error 0
               si_code [1]: SEGV_ACCERR [addr: 0x14]

          To determine which fonts you have, issue a command such as
             + xlsfonts > ~/fonts.txt

          Then pick through the long list of fonts to determine which ones
          you want to use. The xfd program will let you look at a font:
             + xfd -fn "your font name here" &

     4.0.2Why is GridBagLayout so hard to use?
        o A. There are two reasons. First, detailed GUI layout is difficult.
          Simple layouts are easy. Second, GridBagLayout was contributed to
          Javasoft by a programmer who wanted to support the Java effort. It
          was intended as a proof that the AWT offered enough features for
          programmers to write their own layout managers. It wasn't designed
          with human factors and ease of use in mind. If it bothers you (it
          bothers me) then just don't use it. Create your GUI on several
          panels and use the other layout managers as appropriate to get the
          exact effect you want. The official story from the project leader
          of the AWT project, as explained to the Mountain View Java Users'
          Group on Dec 4 1996, is:
             + "The case has been made and is now accepted that
               GridBagLayout is too hard to use for what it offers. GBL will
               continue to be supported, and something better and simpler
               will eventually be provided as well. This "better GBL" can be
               used instead of GBL."

          Bottom line: nobody has to spend any effort on GBL, there are
          better alternatives available now, and it will be replaced by the
          SwingSet "SpringLayout" Springs & Struts style layout manager.

          SpringLayout was to be introduced as part of the Java Foundation
          Classes with JDK 1.2, but it was dropped from the beta release as
          the code was not ready in time. Javasoft generously made the
          preliminary code available and invited programmers to hack on it
          and submit the results.

     4.0.3How do you change the font type and size of text in a TextArea?
        o A. myTextArea.setFont(new Font("NAME", <STYLE>, <SIZE>));
             + where:
                  + NAME is the name of the font (eg Dialog or TimesRoman).
                    <STYLE> is Font.PLAIN, Font.ITALIC, Font.BOLD or any
                    additive combination (e.g. Font.ITALIC+Font.BOLD).
                    <SIZE> is the size of the font, e.g. 12. e.g. new
                    Font("TimesRoman", Font.PLAIN, 18);

     4.0.4Can you have different fonts for individual words in a TextArea ?
        o A. No. If you're trying to write a word processor, use the Canvas
          class to render on.

     4.0.5How much text can be put in a TextArea?
        o A. TextArea just uses the corresponding widget of the underlying
          window system. It will be bounded by the limit imposed in the
          native window system. In Windows95 TextAreas can hold about
          28Kbytes. The native widget allows 32Kb, but there is some
          overhead which reduces the amount available to the programmer. The
          limit will likely disappear with JDK 1.2 which dispenses with peer
          controls.

     4.0.6MyClass works fine except when I try to set a particular font. I
     just can't seem to get it to work in Win95, but I can get it to work on
     a MacOS and Unix.
        o A. You probably specified a font name that isn't available under
          your Win95; this is one of those cross-platform differences that
          can bite you if you over-specify for one platform, like specifying
          "Arial" as a font and expecting it to work on something other than
          Windows.

          On both Windows 95 and Solaris 2.6, these fonts
             + Dialog
               SansSerif
               Serif
               Monospaced
               Helvetica
               TimesRoman
               Courier
               DialogInput
               ZapfDingbats

          are revealed by this code:
             + import java.awt.*;

               class foonly {
                static public void main(String s[])
                {
                String n[]= new Frame().getToolkit().getFontList();
                for (int i=0;i<n.length; i++)
                System.out.println(n[i]);

                System.exit(0);
                }
               }

               In other words, You can get a String array of the names of
               the fonts by

               String[] fonts = Toolkit.getDefaultToolkit().getFontList()

          The names of actual fonts like Helvetica, TimesRoman, and Courier
          are deprecated in JDK 1.1 in favor of font styles like SansSerif,
          Serif, and Monospaced (respectively). The font style will be
          mapped into the nearest actual font on a platform.

     4.0.7Is it possible to draw a polygon or a line more than 1 pixel wide?
        o A. JDK 1.1.1 doesn't have support for this. The standard
          workaround for drawing a thick line is to draw a filled polygon.
          The standard workaround for drawing a thick polygon is to draw
          several polygons.

          There is a useful class at
          http://www.apl.jhu.edu/~hall/java/GraphicsUtil.html It extends the
          drawxxx and fillxxx methods of java.awt.Graphics. It adds a Line
          Width argument to most of the drawxxx methods, a Color argument to
          most of the drawxxx and fillxxx methods, and a Font argument to
          draw String and drawChars.

     4.0.8 I use add(Component) to add Components to the Container. Is there
     any way toexplicitly set the z-order of these Components?
        o A. JDK 1.0 has no way to explicitly set the z-order of components.
          You can try it heuristically, based on the browser you're using,
          or you can use CardLayoutManager to ensure the panel you want is
          at the front.

          In JDK 1.1 the z-order of components ("z-order" means
          "front-to-back" order, i.e. which window is in front of which) can
          be controlled by using the the method add(Component comp, int
          index). By default, components are added 0 to N. The method paint
          of class Container paints its visible components from N to 0.

     4.0.9When I call repaint() repeatedly, half my requests get lost and
     don't appear on the screen. Why is this?
        o A. repaint() just tells the AWT that you'd like a paint to happen.
          AWT will fold several adjacent repaint requests into one, so that
          only the most current paint is done. One possible workaround might
          be to use a clip rectangle and only paint the different areas that
          have changed.

     4.0.10 What is the difference between
     Component's setForeground(Color c)
     and
     Graphics's setColor(Color c) ?

          A. First of all, these methods do the same thing: set the
          foreground color to the value of the parameter. The difference
          lies in where you use them. There is also a
          Component.setBackground that will set the background color.

          If you are in a constructor or an event handler (e.g. "click here
          to turn the canvas blue") you have a Component and should use the
          setForeground() method. If you are in a paint() method, that takes
          a Graphics context as its argument so you will typically use
          g.setColor(c).

          Unlike a Component, a Graphics object doesn't have a background
          color and a foreground color that you can change independently. A
          Graphics object arrives in the color(s) inherited from the drawing
          surface. From then on, any rendering (drawLine(), drawRect(),
          fillOval(), etc.) will be
          done in the setColor() color. Because they do different things,
          the Component and Graphics methods have different names.

     4.0.11 When I start amouse drag inside a Component, and go outside the
     Component, still dragging, the mouse events still get sent to the
     Component, even though I am outside it. Is this a bug?
        o A. No, it is the specified behavior. The java API documentation
          says:
             + "... Mouse drag events continue to get sent to this component
               even when the mouse has left the bounds of the component. The
               drag events continue until a mouse up event occurs. ..."

          It is done for the convenience and ease of the application
          programmer. It allows you to handle all drags from the place of
          origin. If you don't want this, simply look at the coordinates of
          the mouseDrag Event, and if they are outside the Component, ignore
          them.

     4.0.12 What's all this about subclassing Canvas and overriding paint()
     ?Can't I just do a getGraphics() for a component, and draw directly on
     that?
        o A. You can do that, and it might work up to a point (or it might
          not). A problem arises when the window system wants to refresh
          that component e.g. because it has been partially obscured and is
          now revealed. It calls paint(), and paint() has no knowledge of
          the other g.drawing() you have just done.

     4.0.13 Butcouldn't the AWT just remember what has been drawn to a
     Graphics context, and replicate that instead of calling paint()?
        o A. Possibly it could, but how do you unremember something that has
          been drawn? How do you start drawing over again with different
          contents? You could solve these by creating extra methods, but
          that is not how it works. In practice it is a lot simpler to be
          able to look at the paint method, and see explicitly all the
          things that will be done to draw that component. Bottom line: use
          paint(), not g=getGraphics(); g.drawString( ...

     4.0.14How can I get the dimensions and resolution of the screen?
        o A. java.awt.Toolkit.getDefaultToolkit().getScreenSize()
          java.awt.Toolkit.getDefaultToolkit().getScreenResolution()

          Screen resolution is in dots-per-inch.

          Take a look in the Toolkit class for other useful methods.

          Toolkit.getDefaultToolkit().getColorModel().getPixelSize()

          gets you the color model in terms of bits per pixel.

          Math.pow(2,
          Toolkit.getDefaultToolkit().
                getColorModel().getPixelSize())

          gets you the color model in terms of number of colors. Or use
          this:

          1 << Toolkit.getDefaultToolkit().
                            getColorModel().getPixelSize()

          That does a shift left to calculate the power of two.

     4.0.15 How do I allow for the size of the title bar and border when I
     draw a Frame?
        o A. Use MyFrame.getInsets(). This returns a java.awt.Insets object
          which has four ints: top, left, bottom, right, giving the number
          of pixels each of those margins are inset from the top. You can
          use these value to adjust the Dimension object returned by
          component.getSize().

          If you are doing this in the constructor you need to ensure that
          the Frame's peer object is created first. Otherwise the Insets
          object returned by getInsets() will have all zero values. Make a
          call to Frame.addNotify() to have the peer created.

     4.0.16 When I run theSwing demo on Win95 I get an error "Out of
     environment space"
        o A. That's because you don't have enough space for your DOS
          environment. You can fix this with:
             + Right click your MS-DOS Prompt icon or window and choose
               Properties.
             + Choose "Memory" and on "Initial Environment" choose 4096
               instead of "auto".
             + Run Swing again, you'll be OK.

     4.0.17 How do Iresize a List? I had a List defined as
        o List tlist = new List(10);

     but the Strings in the list were 80 characters long and only the first
     15 were being shown. I was not able to resize the List to display the
     contents without using the scroll bar.
        o A. A List cannot be resized in a constructor, so add the following
          to the Applet (or wherever)
             + public void paint (Graphics g) {
               tlist.setSize(200,200);
               }

          Then before showing panel/frame with the List:
             + tlist.resize(400,400);

     4.0.18 How can my program tellwhen a window is resized?
        o A. Override the setBounds() method of Component to do what you
          want. Of course, have it call super.setBounds() as well. Note that
          setBounds() replaces reshape() which is deprecated.

          Note the new APIs call the deprecated APIs instead of the other
          way round. For example, Component.setBounds calls
          Component.reshape, instead of reshape calling setBounds.

     4.0.19 Why doesn't my window close when I click on the X in the title
     bar?
        o A. Here's how to make your program do that.
          JDK 1.0.2: Handle Event.WINDOW_DESTROY to do a hide() and
          dispose() on the Frame.

          JDK 1.1:
          a) Listen for WindowEvent and do hide(); dispose(); in
          windowClosing() - this really ought to be the "default" behaviour.
          Or
          b) enable AWTEvent.WINDOW_CLOSING and do the hide() and dispose()
          in processWindowEvent().

     4.0.20How do I clear the contents of a TextArea?
        o A. Set it to an empty String with this:
             + area.setText("");

     4.0.21 What are those preferredSize() and minimumSize() methods in
     Component?
        o A. Those methods allow a LayoutManager to calculate the preferred
          and minimum sizes of the Components it is arranging. You can
          control the values that the LayoutManager gets by creating
          subclasses of the Components you are using and overriding these
          methods.

     4.0.22 How can Iforce a synchronization of the graphics state, e.g. of
     a cursor change, or an animation frame to be rendered?
        o A. This is done by the sync() method in the toolkit. So just use:
             + AnyComponent.getToolkit().sync();

     4.0.23 How do Iplot a single pixel to the screen?
        o A. Use g.drawLine(x1,y1,x1,y1) to draw a line one pixel in length.
          If you are drawing a very large number of individual pixels,
          consider using a java.awt.MemoryImageSource object and measure
          whether this offers better performance.

     4.0.24 How can Itab between components?
        o A. In JDK 1.0, you have to read the key press, and program it
          explicitly. JDK 1.1 supports tab and shift-tab (previous field)
          automatically. The tab order is the order that the components were
          added to the container.

     4.0.25 What is the difference between "low level" and "semantic"
     events?
        o A. Low-level events are tied to a specific component (resizing a
          window, dragging the mouse, striking a key, adding a Component to
          a Container, etc). Semantic events are those generated when you
          frob a control (move a scrollbar, click on a button, select from a
          menu, etc), and the same kind of event can be generated by several
          different components. A Button and a List both fire an Action
          event when they are clicked on.

          To the programmer, the important difference is that you can change
          a low level event such as the key value in a keypress, and it will
          display the new value. You can also consume low level events so
          that they do not appear in the widget. You can't do these things
          with semantic events - they have already "occurred" to the widget.

          Semantic events: Use the method addXListener() to add a listener
          object which implement the XListener interface, to get XEvent
          objects delivered (usually via the AWTEventMulticaster). Low level
          events: use the method enableEvents() and override performX() to
          grab those events in the object itself.

     4.0.26Is it possible to have a Java window float above all other
     windows. for example a tool palette floats in a super-layer always
     above all the regular document windows on which you use the palette's
     tools?
        o A. On MS Windows, a Window object floats above all other windows,
          unlike a Frame, which is layered in with ordinary windows. This
          behavior yields a "floating" effect. Whether a Window object is
          really supposed to float is another question entirely.

          On Mac, a Window object is either layered in with other windows,
          just like a Frame is, or else it is entirely modal -- depending on
          which VM you use. In Java -- there appears to be no easy way to
          get floating behavior. If anyone knows otherwise, please send in
          your comments.

     4.0.27How do I center a dialog box?
        o A. You cannot currently get the applet's absolute screen
          coordinates. Its location (0,0) is relative to the browser, not
          the screen itself. But you can center something that it pops up or
          displays centered on the screen with code like this:

          Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
          my_window.move(
           ( screen.width - window.size().width ) / 2,
           ( screen.height - window.size().height ) / 2 );

          my_window.show().

          In a related fashion, you can center something on its parent like
          this. Note the intelligent use of APIs like translate() to do the
          work for you.

          void centre(Component parent) {
           pack();

           Point p = parent.getLocation();
           Dimension d = parent.getSize();
           Dimension s = getSize();

           p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
           setLocation(p);
          }

     4.0.28 How do I get back to anormal echo after I have used
     TextField.setEchoChar('*');
        o A. TextField.setEchoChar('\0') works on most Windows based
          browsers... but for most other platforms (ie: Netscape under
          UNIX), it just locks up the textfield.

          There is only one good solution, and that is to make two
          TextFields on top of each other, one normal, and one with
          .setEchoChar('*'), and switch between them.

     4.0.29 How can I get the absolute mouse coordinates?
        o A. You mean, if the browser is about 640x480, you want a y-coord
          between 0 and 480. If the browser window is about 800x600 you want
          a y-coord between 0 and 600. This might be needed for a pop-up
          menu, where you want to pop up at the absolute mouse position.

          The approach is to sum up the event's (x,y) and the locations of
          the target and its parents until there is no parent. Though on
          some browsers, it seems this is not reliable. [Better suggestions
          are solicited.]

     4.0.30 How can iconify/deiconify a window in Java?
        o A.There is no way in Java today to write code to force a window to
          iconify or deiconify. There is a way (tested on Windows and UNIX)
          to achieve this effect that involves creating and destroying
          peers, but it is not recommended. You can drop into native code to
          do it. The "party line" in JavaSoft is that it is because Java is
          an application language, not a window manager. Everyone wishes
          they'd add it.

     4.0.31 How can I write text at an angle?
        o A.Check out http://www.nyx.net/~jbuzbee/font.html. Jim has some
          code to do exactly this. A good way to do it is to draw the text
          to an offscreen image and write an ImageFilter to rotate the
          image.

          Also, in JDK 1.2 on, the Java 2D API handles arbitrary shapes,
          text, and images and allows all of these to be rotated, scaled,
          skewed, and otherwise transformed in a uniform manner.

     4.0.32 How do I know which mouse button was pressed, and how often?
        o A. To handle mouse events you have to implement the MouseListener
          interface, or derive from the MouseAdapter class in order to use
          one of the mouse handling methods. The MouseEvent argument passed
          to the handling methods contains fields that say which button was
          pressed, and the click count. Use code like this.

          public void mouseClicked(MouseEvent m) {
           boolean leftButtonPush   =
            (m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
           boolean centerButtonPush =
            (m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
           boolean rightButtonPush  =
            (m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;

           int click = m.getClickCount();    // might be 1,2,3 clicks or more

          You can also call at m.isPopupTrigger(). If it returns a true
          value, the user has asked for a pop-up menu. On a lot of window
          systems, the right mouse button is the trigger for pop-up menus.
          The code above applies to JDK 1.1. There were similar methods for
          JDK 1.0. See also question 15.10.

     4.0.33 How do I detect a resize of a Frame?
        o A. Register a ComponentListener on the frame, like this:

          import java.awt.*;
          import java.awt.event.*;

          class MyFrame extends Frame {
             public MyFrame() {
                addComponentListener(new CmpAdapter());
             }

             class CmpAdapter extends ComponentAdapter {
                public void componentResized(ComponentEvent evt) {
                    //doSomething();
                }
             }
          }

          Alternatively, the same effect can be achieved like this:

          class MyFrame extends Frame implements ComponentListener {
              public MyFrame() {
                  addComponentListener(this);
              }

              public ComponentHidden(ComponentEvent evt) { }
              public ComponentMoved(ComponentEvent evt) { }
              public ComponentShown(ComponentEvent evt) { }
              public ComponentResized(ComponentEvent evt) {
                  //doSomething
              }
          }

     4.0.34 How do I get word-wrap in a TextArea?
        o A. It's a little obscure. Creating a TextArea with no horizontal
          scrollbar causes wrapping to occur automatically. The idea is that
          if you ask for a scroll to scroll viewing over to the right, there
          is no reason for the widget to do word wrap. So take away the
          scroll bar, and word wrap will be done instead.

          Supply TextArea.SCROLLBARS_NONE or
          TextArea.SCROLLBARS_VERTICAL_ONLY to the TextArea constructor to
          get word wrap. By default, a TextArea is created with both
          horizontal and vertical scrollbars.

     4.0.35 How can I make an offscreen image with transparent pixels?
     How can I grab the pixel values from an offscreen image?
     How can I use AWT drawing primitives (e.g. drawString() or drawOval())
     on an image I created from an ImageProducer?
        o A. None of these things can be done.

          Despite the fact that there is only one class called Image in the
          AWT libraries, it suffers from a (currently undocumented) severe
          case of schizophrenia: there are really two unrelated types of
          Image. The first type are those created by the
          Component.createImage(int, int) call, known as "offscreen" images,
          and the second are those created by the
          Component.createImage(ImageProducer) call, or by the
          Toolkit/Applet.getImage() calls, which I will call "produced"
          images.

          The only common ground between these kinds of Image is the
          following:
             + you may find their width and height by the methods of the
               Image class.
             + you may use them as the argument to the various
               Graphics.drawImage() calls.

          The differences between these objects are the following:
             + you may not put transparent pixels into an offscreen - note
               that all Java primitives accept Color objects, which all
               represent completely opaque colours as if Produced from an
               int with the upper 8 bits equal to 0xff. (see 8.3)
             + you may not call Image.getGraphics() on a produced image, and
               hence may not use any AWT primitives.
             + you may not grab pixels from an offscreen image using
               PixelGrabber.
             + anyone know of any other limitations?

          In these cases, "you may not" generally means "you may not
          successfully". Symptoms on attempting these range from Exceptions
          to garblings of the Image. Any or all of these restrictions may be
          removed in Java 1.2, which features a new 2d API. Wait and see.

          There are some relevant bugs shown in the Java Developer
          Connection: Bug ID 4098505. Apparently, from the report from the
          Sun engineer, PixelGrabber is specified to work with offscreen
          images, just it is currently buggy, and invariably gets the wrong
          colour model. No fix has been scheduled yet.

          Bug ID 4077718 reports that setting transparent Colors in
          offscreen images has been available since Java 1.2beta1. I am
          personally unable to verify this.

          There is an incorrect answer from Sun to the third matter, of
          getGraphics() on produced images, in article 1501 in
          Questions&Answers.

     4.0.36 How can I grab a pixel from an Image object?
        o A. This is the purpose of the java.awt.image.PixelGrabber class. A
          fragment of code showing its use is:

          import java.awt.image.PixelGrabber;
          import java.awt.Image;
          ....
          ....
          public static int pixelValue(Image image, int x, int y) {
          // precondition: buffer must not be created from ImageProducer!
          // x,y should be inside the image,
          // Returns an integer representing the color value of the x,y pixel.
              int[] pixel=new int[1];
              pixel[0]=0;

          // pixel grabber fills the array with zeros if image you are
          // trying to grab from is non existent (or throws an exception)
              PixelGrabber grabber = new PixelGrabber(image,
                                               x, y, 1, 1, pixel, 0, 0);
              try {
                  grabber.grabPixels();
              } catch (Exception e) {System.err.println(e.getMessage());}
              return pixel[0];
          }

          By the way, one issue on working with images is that the Java VM
          will consume virtual memory pretty fast if you are loading lots of
          images without calling the Image.flush() method when done. The
          getImage() method probably caches old images so they aren't
          garbage collected.

     4.0.37 How can I limit a TextField to no more than N characters, or to
     only allow numeric input?
        o A. The approach is to look at keystrokes as they happen, and
          disallow input that does not meet your criteria.

          A neat variation is to extend the basic AWT component, and in your
          subclass also include the handler that will look at the
          keystrokes. This bundles everything neatly in one place. The code
          may look like:

          import java.awt.*;
          import java.awt.event.*;

          public class XCTextField extends java.awt.TextField implements
          java.awt.event.TextListener {

              public XCTextField(int columns) {
                  super(columns);
                  enableEvents(AWTEvent.FOCUS_EVENT_MASK);
                  addTextListener(this);
              }

              // other constructors may be useful, too

              public void textValueChanged(java.awt.event.TextEvent event) {
                  int col = this.getColumns();
                  int len = getText().length();
               // int caret = getCaretPosition();

                  if (col > 0 && len  > col) {
                  // or if the char just entered is not numeric etc.
                          String s = this.getText();
                          Toolkit.getDefaultToolkit().beep();
                          this.setText(s.substring(0,col));
                          this.setCaretPosition(col-1);  // put the caret at end
                  }

              }

              public void processFocusEvent(java.awt.event.FocusEvent e) {
              // this routine highlights according to focus gain/loss.
                  super.processFocusEvent(e);
                  int id = e.getID();
                  if (id==java.awt.event.FocusEvent.FOCUS_GAINED)
                      this.selectAll();
                  else if (id==java.awt.event.FocusEvent.FOCUS_LOST)
                      this.select(0,0);
              }
          }

4.1 APPLETS

   * 4.1.1 What is thedifference between an application, and applet and a
     servlet?
        o A. An application is a standalone program. An applet is a
          downloadable program that runs in a web-browser. Typically an
          applet has restricted access to the client system for reasons of
          security. Other than that it is virtually no different to a
          regular Java program.

          A servlet is a java program whose input comes from a server and
          whose output goes to a server. Other than that it is virtually no
          different to a regular Java program. Think of a servlet as an
          application, but one that (like an applet) requires a context in
          which to run, namely web-server software. Servlets are used like
          CGI, and they allow the server end to be written in Java as well
          as the client.

          The Web Server starts up a servlet when the URL is referenced, and
          now your applets have something that they can talk to (via
          sockets) on the server that can write files, open connections to
          other servers, or whatever.

          There is also a software technology from IBM called an "Aglet". An
          aglet is a mobile agent that can go from machine to machine,
          performing tasks, serializing data collected, and "shipping
          itself" (code and data) to the next machine. It's too early to say
          if aglets are a flash in the pan or or a dawning technology. Read
          about aglets at http://www.trl.ibm.co.jp/aglets/

          Don't confuse Sun's JWS "Java Web Server" with JWS "Java
          Workshop". Java Web Server supports servlets as does the
          lightweight and free server at Acme.com:
             + http://www.acme.com/java/software/Acme.Serve.Serve.html

     4.1.2 Myapplet works on my machine, but fails when I put it on our web
     server. Why?
        o A. It could be one of several reasons, and unfortunately the
          messages that you get in this situation aren't much help. In
          general, you can assume that either your applet's class files are
          corrupted somehow, or the web server can't find one or more of
          them when the browser needs them.

          Be careful of the following things:
             + Make sure you transfer the class files in binary mode, rather
               than text or ASCII mode.
             + Make sure you transfer *all* of the class files which are a
               part of your applet. Sometimes people are surprised by how
               many there are. There will be a class file for every class
               and interface you define, even if you define more than one in
               a single source file. If you use the Java 1.1 "inner classes"
               feature, there will be class files for each inner class as
               well.
             + Make sure you maintain the appropriate case distinctions in
               your filenames. If a class is called StUdLy, it must be found
               in a file called StUdLy.class.
             + Make sure you maintain the directory structure that matches
               your package structure. If you declare a class in package
               COM.foo.util, the class file needs to be in directory
               COM/foo/util under the applet's codebase directory. Again,
               case distinctions are important for package/directory names,
               just as they are for class/file names.
             + Make sure that the web server process will have read access
               to the class files, and search access to the directories that
               the files are in. For example, if the web server runs on a
               Unix machine, use the command "chmod o+r filename" for the
               files, and "chmod o+x dirname" for the directories.

     4.1.3 How do Iuse an image as the background to my applet? How do I set
     the background color of my applet the same as the browser?
        o A. You can simply do a g.drawImage(yourImage, x,y, this) in the
          paint() routine of your applet. If the image isn't big enough to
          fill the entire background, tile it or scale it There is some code
          to tile at:
             + http://www.geocities.com/SiliconValley/Vista/1337/

          (under AWT) Alternatively, the AWT can scale your background image
          to the size of
          the applet. The result quality will depend on the kind of image.
          Inside an applet class, you can use:
             + drawImage(img, 0, 0, size().width, size().height, this);

          You can set the background color to match the background color of
          the browser by passing the value in as a parameter, like this:

          In the HTML applet tag:
             + param name=BrowserColor value=F1F1F1
               (value should be the same hex as the HTML COLOR value).
               In the Applet init() method:

               String colparam = getParameter("BrowserColor");
               int col = Integer.valueOf(colparam,16).intValue();
               setBackground( new Color(col) );

          An applet cannot override the size imposed by the HTML. If you
          make the applet larger, the browser will still clip to the
          origional size. If you need more room, open up a new Frame, Window
          or Dialog to show your output.

     4.1.4 How do you make theapplet's background transparent?
        o A. There is no way to give an applet a transparent background that
          lets the web browser background show through. You can simulate it
          by giving the applet a background that matches the underlying
          browser background. It doesn't produce satisfactory results with a
          patterned background because of problems aligning the edges.

          Lightweight components (new in JDK 1.1) have a transparent
          background.

     4.1.5 How do you dofile I/O from an applet?
        o A. See answer to question 6.8.

     4.1.6 How do you get aMenuBar/Menu in an applet?
        o A. In your applet's init() method, create a Frame instance and
          then attach the Menus, Menubar etc to that frame. You cannot
          attach the Menu or a Menubar to an applet directly.

          Or get the parent Frame like this (doesn't work in all execution
          environments):
             + Container parent = getParent();
               while (! (parent instanceof Frame) )
                parent = parent.getParent();

               Frame theFrame = (Frame) parent;

          This second suggestion definitely doesn't work in the
          appletviewer, and probably won't work on Macs (where would the
          menubar go?) or in some browsers. In JDK 1.1, just use a popup
          menu, which isn't attached to a Frame.

     4.1.7Can I get rid of the message "Warning:Applet Window" along the
     bottom of my popup windows in my Applet?
        o A. This is a security feature that prevents the applet programmer
          from popping up a window that looks like it came from the native
          OS and asking for passwords or credit card info (etc). Users must
          always be aware of when they are talking to an unsigned applet.
          You can get rid of it by signing the applet, if the user accepts
          signed applets from you. See the Java Signing FAQ at
          http://www.fastlane.net/~tlandry/javafaq.txt

          In Netscape (only), using the Capabilities API to make the call
             + PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");

          before creation of the Frame eliminates the message, if the
          security manager passes it.

     4.1.8When I subclass Applet, why should I put setup code in the init()
     method? Why not just a constructor for my class?
        o A. The browser invokes your constructor, then setStub, then
          init(). Hence when your constructor is invoked, the AppletStub
          (and through it the AppletContext) is not yet available. Although
          in principle you can do things in the constructor that don't rely
          (even indirectly) on the AppletStub or AppletContext, it is less
          error-prone to simply defer all setup to the init method. That way
          you know that anything that needs the stub/context will have it
          available.

     4.1.9How do I pull a non-class file, such as a .gif, out of a jar file?
        o A. In your class, you should be able to do something like this:
             + String imageFileName = "foo.jpg"
               URL imageURL = getClass().getResource(imageFileName);
               Toolkit tk = Toolkit.getDefaultToolkit();
               Image img = null;
               try {
                    java.awt.image.ImageProducer I_P;
                    I_P = (java.awt.image.ImageProducer)imageURL.getContent();
                    img = tk.createImage(I_P);

               Or equivalently, and possibly simpler, this:

               String imageFileName = "foo.jpg";
               InputStream jpgStream
                           = getClass().getResourceAsStream(imageFileName);
               Toolkit tk = Toolkit.getDefaultToolkit();
               Image img = null;
               try {
                    byte imageBytes[]=new byte[jpgStream.available()];
                    jpgStream.read(imageBytes);
                    img = tk.createImage(imageBytes);

          (Like anything involving Jar files, this is from JDK 1.1 on).
          getResource(String) does not work in applets in Netscape due to
          Netscape security issues. You should use
          getResourceAsStream(String) there instead. See
          http://developer.netscape.com/software/jdk/relnotes.htm

          Note that getResourceAsStream() is also good for reading a text
          (or other kind of) file from a JAR file.

          public void init() {

            InputStream myStream = getClass().getResourceAsStream("myFile");
            //   ...
          }

          Once you have it as an InputStream you can read it how you like.

     4.1.10 I want to know about {applets,applications} butthe lousy book I
     got just talks about {applications,applets}. What can I do?
        o A. The truth is that 95% of the material is the same, whichever
          your book chooses to focus on. Some people write their apps to
          work completely in a Panel, then depending on whether they're
          running stand-alone or in a browser the Panel is either added to a
          Frame or an Applet. The trick is that you need to add a listener
          to the application's Frame to handle the WINDOW_CLOSING
          (previously WINDOW_DESTROY) event yourself.

          If you fail to do this, when running as an application, the window
          won't close. See question 15.7 for a sample of the right handler.

          In this scenario the following code will tell you which
          environment you're running in:
             + public boolean isRunningInBrowser() {
                Component p = getParent();

                while(p != null && !(p instanceof Frame)) {
                p = p.getParent();
                }

                return (p == null);
               }

     4.1.11 How do I print a page with an applet?
        o A. Browsers are starting to introduce support for this. Until they
          all have it, your best bet is to print a screendump. Using the
          browser to print the page may leave a blank where the applet is.
          Putting print support in the applet will print the applet only,
          not the rest of the browser page. See also Q5.2.

     4.1.12 How can I position my dialogs centered(not top left)?
        o A. Use some code like this:

          void centre(Component parent) {
              pack();
              Point p = parent.getLocation();
              Dimension d = parent.getSize();
              Dimension s = getSize();
              p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
              setLocation(p);
          }

     4.1.13 How can I get two applets on the same page to communicate with
     each other?
        o A. In your HTML page, give a NAME in the APPLET tag for the applet
          receiving message, say <APPLET ... NAME=someName ...>. In the Java
          code of the other applet do

          Applet anotherApplet = getAppletContext.getApplet("someName");

          Cast anotherApplet to the correct applet subclass, and you can
          call any methods in the applet subclass. Don't forget to use
          appropriate synchronization when two threads tweak variables.

          You can walk through all the applets on an HTML page using code
          like that below. However this appears to be broken in Communicator
          4.04 on Win95.

          Applet otherApplet;
          AppletContext ac =getAppletContext;
          for (Enumeration applets=ac.getApplets(); applets.hasMoreElements();){
               otherApplet=(Applet)applets.nextElement();
               if (otherApplet!=this) break;
               // do something with otherApplet, e.g.
               // if (otherApplet instanceof FooApplet) ...
          }

          Some people suggest using the static members of a common class to
          communicate information between the applets. This is not
          recommended as it relies on class-loading behavior that may change
          in future.

          Inter-applet communication sometimes arises when you have a
          multi-screen type program and you don't want to force the user
          into downloading everything at once. One alternative is to make
          them into one applet with two GUIs. Try to avoid the need for
          applets to talk to each other. Also check the URL
          http://java.sun.com:81/products/hotjava/1.1/applet_environment.html
          which explains how it can be done in HotJava 1.1. Recommendation:
          stay far away from code which is browser-specific.

     4.1.14 How can I resize an applet?
        o A. If you want resizing behavior from an applet, you should launch
          an external frame that can be resized independently.

          One programmer suggests using percentages for the height/width
          parameters in an applet tag, like this:

          <APPLET CODE = "lewinsky.class" WIDTH="100%"  HEIGHT="100%" >

          You can't resize the applet directly, but it does get resized when
          you resize the browser window (tested with Netscape 3.04 and 4.04,
          but does not work with appletviewer). If you have nothing else on
          your HTML page and use 100% for your width and height, the browser
          window looks almost like a real application.

          For the extremely tricky: have the browser reload the page with
          the applet when the browser resizes using new values for width and
          height (probably not what you want most of the time). You would
          need javascript to generate a page dynamically using
          document.write("...") when the browser resizes. Not recommended.
          Another possibility is to use the new SplitPane class in JFC.

     4.1.15 How do I read a text file stored in a JAR?
        o A. The best way to do this is to use the method
          Class.getResourceAsStream() which will give you an input stream
          from which you can read the text file in the JAR. This technique
          can be used to get parameter info from a text file for an applet.
          See www.uq.net.au/~zzcmumme for an example.

4.2BROWSERS

   * 4.2.1When will my favorite browser support Java 1.1?
        o A: All popular browsers now have JDK 1.1 support. Netscape
          Communicator 4.04 plus patch "J" fully supports the features of
          Java 1.1. It was released in December 1997, and is only missing
          the JavaSoft support for applet signing (Netscape has gone its own
          way on this).
             + URL:
               http://developer.netscape.com/support/faqs/champions/java.html#21

          Sun's HotJava browser fully supports the JDK 1.1 features.

          People who are obliged to use a browser without standard Java
          support should use Java Plug-In. Java Plug-In substitutes a
          standard Java virtual machine for that shipped with the browser.
          It allows you to use RMI, JavaBeans components, and Java
          Foundation Classes in Internet Explorer 3.02, 4.0, and 4.01. Java
          Plug-In also works flawlessly with Netscape browsers. You can
          download Java Plug-In from http://java.sun.com/products/.

     4.2.2Is it possible to set and retrieve cookies from Java, in a manner
     that is compatible with all browsers supporting cookies?
        o A. Short answer: no.
          Longer answer: probably no.
          Ultimate answer:
          A cookie is a morsel of tasty data that a server sends back to the
          client, and can retrieve on demand. It allows the server to retain
          some state information for each of its clients. The information is
          typically something like "what pages has the user seen?" or "is
          this a privileged user?".

          The DevEdge site on Netscape's home page has a javascript-java
          example on getting cookies. Also
          http://www.geocities.com/SiliconValley/Vista/1337 has info on
          connecting an applet with JavaScript functions. It's quite
          involved. Stick to just Java if you can.

     4.2.3 I am developing an applet and testing it in Netscape Navigator.I
     find that after I recompile, I press reload, clear the caches, retype
     the URL of the HTML wrapper, and I still have the old version. Why is
     this?
        o A. It is because Netscape has completely failed to improve the
          defective code that does this monstrously wrong thing. It has been
          like this for many successive releases.

          Flushing the network cache will make no difference; that isn't
          where the caching is taking place. Although applets are sometimes
          "pruned" and their ClassLoaders garbage-collected, this doesn't
          happen predictably, so restarting Netscape is the only reliable
          work-around at the moment.

          A related question is "how do I make the browser reload from a
          URLConnection instead of just getting the content from the local
          cache?" The answer is to use
          java.net.URLConnection.setUseCaches(false)
          Browsers seem to vary in their conformance to this programmatic
          request. Netscape caching varies depending on whether a proxy
          server is in use, and which thread in the applet made the get
          request.

     4.2.4 So,why can't Netscape reload the applet when you press the Reload
     button?
        o A. For the applet to be reloaded, the new version would have to be
          loaded in a different ClassLoader. Navigator/Communicator's policy
          for assigning ClassLoaders to applets doesn't take into account
          whether a reload has been done (although there is no technical
          reason why it couldn't).

          Some versions of Netscape reload the Applet if you hold down
          <Shift> while you click on reload. Until they fix it, use the
          appletviewer to test applets. And send them mail -- developers can
          only fix the bugs they know about.

     4.2.5 Should I use MicrosoftCAB files or Java JAR files?
        o A. The question contains its own answer.

          CAB format is a Microsoft-only format. So do not use it as it
          destroys software portability.

          JAR format is the Java standard format, based on PKZIP format
          including data compression. JARs were introduced with JDK 1.1

          See http://www.ibm.com/java/community/viewarchive4.html for more
          information.

          You should use the Java standard format JAR (Java Archive) files,
          not a vendor-specific format. JAR files are not just a Java
          standard, they are in industry-standard PKZIP format. One reader
          comments that both formats can be used with this tag:
             + <APPLET NAME=myapplet
               ARCHIVE="myzip.zip"
               CODE="com/nnnnn/nnnn/cccccccc.class"
               WIDTH=n
               HEIGHT=n>
               <PARAM NAME="cabbase" VALUE="mycab.cab">
               </APPLET>

          IE3 does not support JAR
          IE4 supports compressed and uncompressed JAR, but not signed JAR
                                   -----------------

4.3SWING

   * 4.3.1 What is Swing?
        o A: Swing is a new GUI toolkit bundled with JDK 1.2, and available
          as an add-on extension library for JDK 1.1. Swing is the first GUI
          toolkit that lets developers create lightweight components with a
          pluggable look-and-feel design. From an architectural standpoint,
          the Swing component set extends -- but does not replace -- the
          Abstract Windowing Toolkit (AWT). Swing has many components that
          can be used in place of components in the AWT (e.g. JFrame instead
          of Frame, JButton instead of Button, JPanel instead of Panel). It
          also has many components that don't exist in the AWT (e.g. tool
          tips, toolbars, and progress bars). However Swing relies on the
          underlying AWT being there.

          The Swing toolkit allows the creation of GUI's that are every bit
          as sophisticated as native code toolkits like MFC -- with the Java
          advantage that they run on every platform. The pluggable look and
          feel means that they can have the exact same appearance on every
          platform too, if the user chooses it.

          With Swing, native window behavior is confined to external window
          frames (and their borders) and a few other things such as fonts
          and the buffers used to hold window contents. The composition,
          layout, and drawing of controls is now all handled by Java code.
          So identical code is executed to create and manage your user
          interface on every platform. Swing provides a much greater
          consistency of behavior across different platforms.

     4.3.2 Why is my menu showing up behind other components when I use
     Swing?
        o A: The answer relates to lightweight and heavyweight (peer-based)
          components. There is a good article about it at
          http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html

          For those who want the quick fix, and will read the article later,
          adding the line:

          com.sun.java.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);

          before you create any menus will probably fix it (even if you're
          using menus other than JPopupMenu).

          The summary answer is that a Lightweight component will not appear
          over a heavyweight component by default.

     4.3.3 Why does my JFrame go away after I chose system close on the
     window?
        o A: Assume that you have a Swing JFrame component, and you handle
          the windowClosing event, but do nothing in the handler. You will
          see that the JFrame disappears anyway.

          The reason is that JFrame's have default handling of the system
          close operation, separate from the windowClosing event. You have
          to override that by calling:

          setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

          on your JFrame.

                             -------------------

5.CORE LIBRARIES

   * 5.1I can't seem to change the value of an Integer object once created.
        o A. Correct. Integer (Float, Double, etc) are intended as an object

          wrapper for a specific value of a number, not as a general purpose

          way of shipping a primitive variable around as an Object. If you
          need
          that it's easy enough to create: class General { public int i; }

     5.2 How do Iprint from a Java program?
        o A. Use the Toolkit.getPrintJob() method
             + Component c = this.getParent();
               while (c!=null && !(c instanceof Frame))
                c=c.getParent();

               PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
               Graphics pg = pj.getGraphics();
               printAll(pg);
               pg.dispose();
               pj.end();

          This feature was introduced with JDK 1.1. A common place to put
          this is in the code that handles a button press. Printing from an
          untrusted applet is subject to a check from the SecurityManager.

     5.3 What are the properties that can be used in a PrintJob?
        o A. The properties are
             + awt.print.destination - can be "printer" or "file"
               awt.print.printer - printer name
               awt.print.fileName - name of the file to print
               awt.print.numCopies - obvious
               awt.print.options - options to pass to the print command
               awt.print.orientation - can be "portrait" or "landscape"
               awt.print.paperSize - can be "letter","legal","executive" or
               "a4"

               The defaults are destination=printer, orientation=portrait,
               paperSize=letter, and numCopies=1

               You can search for info like this by joining the Java
               Developer Connection (it's free)

               http://developer.javasoft.com/developer/index.html

               Then do a search for "PrintJob".

     5.4 Is there anypackage in Java to handle HTML?
        o A. See the answer to Question 8.14

     5.5Why don't Dialogs work the way I want them to?
        o A. Modal dialogs (dialog windows that stay up until you click on
          them) are buggy in many browsers and in the 1.0.2 JDK. One bug is
          that the dialog is not necessarily put on top when it is
          displayed. Most of the modal dialog bugs are fixed in JDK 1.1.

     5.6 Where can I findinformation about the sun.* classes in the JDK?
        o A. You're not supposed to. Those classes are only to support
          functions in the java.* hierarchy. They are not part of the API,
          and won't be present in Java systems from non-Sun vendors. Some
          people have reverse engineered the code and published an API for
          these classes but you use it at your own risk, and it may change
          without warning.

          Worst of all, those programs will not have the portability of true
          Java but will only run on Sun JDKs. For the same reason you
          shouldn't use classes outside the java.* packages when using JDKs
          from other vendors.

          If you still insist on going ahead, check these URLs:
          http://java.sun.com/products/api-overview/index.html
          http://www.parmly.luc.edu/javaudio/
          http://www.users.interport.net/~mash/javamidi.html

     5.7 How do you read environment variables from with a Java program?
        o A. Environment variables are not used in Java, as they are not
          platform portable. The Mac doesn't have environment variables for
          example. A Windows 95 application not started from a DOS window
          does not have environment variables. Use properties instead. It
          was a design error in JDK 1.0 that programmers had to set the
          CLASSPATH environment variable. This should have been set in a
          property file. JDK 1.1 removes the need to set the CLASSPATH
          environment variable, and (as the documentation explains) it's
          generally a mistake if you do.

          Create your own properties file (see java.util.Properties) or
          specify them with the -D option when you invoke the interpreter or
          JRE. Additionally, on some systems you can set a property from the
          command invocation line like this:
             + java -Dfoo=$foo MyClass (Unix)

          or
             + java -Dfoo=%foo% MyClass (Win95/NT)

          This sets the "foo" property to the value of the environment
          variable foo, and makes it available in the System properties.
          Make sure you do not leave any spaces after the -D or around the =
          sign. Inside the program you get the value with:
             + String env = System.getProperty("foo");

          More simply, just put the environment variable on the commandline
          and read it as arg[0]
             + java MyClass %FOO% ; Win32
               java MyClass $FOO ; Unix

          Finally, you could execute a Runtime process to get the
          environment variables if you are on a platform that has them. This
          is a poor approach as it builds platform-specific knowledge into
          the program. See Q10.5 for more details. On Unix, the command that
          prints environment variables is "/usr/bin/env". On Windows95, it
          is "set"

     5.8 How do you use the Date class to display the current time in my
     timezone?
        o A. There is more than one bug involving timezones, so some people
          have it working OK, but others trying something very similar are
          hitting other date format and timezone bugs. Before diving into
          the details, let's review the date-related classes.
             + class Date represents a specific instant in time, with
               millisecond precision. The design of this class is a very bad
               joke - a sobering example of how even good programmers screw
               up.
             + class Calendar is an abstract class for converting between a
               Date object and a set of integer fields such as year, month,
               day, and hour.
             + class GregorianCalendar is the only subclass of Calendar in
               the JDK. It does the Date-to-fields conversions for the
               calendar system in common use. Sun licensed this
               overengineered junk from Taligent - a sobering example of how
               average programmers screw up.
             + class DateFormat is an abstract class that lets you convert a
               Date to a printable string with fields in the way you want
               (e.g. dd/mm/yy or dd.MMM.yyyy or whatever). DateFormat and
               SimpleDateFormat classes use the default timezone for your
               JVM. This is the JVM's "user.timezone" property (a more
               sensible choice would be to attempt to use the tz of the
               underlying OS). If the "user.timezone" property is not set,
               it now defaults to GMT (not PST as it used to). A very small
               improvement. To associate the tz of your choosing with a date
               format, use:

                 DateFormat df = DateFormat.getDateInstance();
                 df.setTimeZone(TimeZone.getDefault());

             + class TimeZone is an abstract class that represents a time
               zone offset, and also figures out daylight savings.
               GregorianCalendar tries to default to the timezone (if any)
               set in your Java system properties file. This timezone will
               be something like, e.g. "PST", "EST", "CET" etc.

               If there is no preset timezone, it used to default (prior to
               JDK 1.1.2 or so) to PST - Pacific Standard Time as used in
               California. Since 1.1.2 the code now defaults to GMT when no
               TZ is in the properties file.

               You only need bother with TimeZone class if the default TZ
               doesn't suit you, or if you want to use other timezones for
               your Date objects or date conversions.
             + class SimpleTimeZone is the only subclass of TimeZone in the
               JDK. It represents a time zone for use with a Gregorian
               calendar. This simple class does not handle historical
               changes, and has limited rules. When you ask for the default
               timezone, you'll actually get an object of this subclass
               back.

          If you want to see the properly formated version of your Date, you
          shouldn't use myDate.getTime().toString(). A Date object now only
          represents an instant in time, resolved to the millisecond. All
          other uses (such as extracting individual fields or formatting)
          have been deprecated. To display the current date declare a
          GregorianCalendar and pull the fields out of that, as in this
          example:

          import java.util.*;
             ...
                  GregorianCalendar g = new GregorianCalendar();
                  int year = g.get(Calendar.YEAR);
                  int mon  = g.get(Calendar.MONTH);
                  int date = g.get(Calendar.DATE);
                  mon++; // in class Calendar & GregCal, months run 0-11 ;-(
                  System.out.println(mon +"/" +date +"/" +year);

          If you want fancy formats for printing/expressing the date, you
          should use the new internationalization routines. You will need to
          use the DateFormat and SimpeDataFormat classes in the java.text
          package. Here is an example:

          import java.util.*;
          import java.text.*;

            Locale.setDefault( Locale.ENGLISH );
            System.out.println(
                 DateFormat.getDateInstance(DateFormat.SHORT).format(new Date())
            );

          This will print (on April 7, 1998):

          4/7/98

          There is some sample code in the Java API documentation. As an
          example of how the new method should work
          jdk1.1/src/java/util/Date.java contains the method:
             + DateFormat formatter = new SimpleDateFormat (
                                  "d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
               formatter.setTimeZone(TimeZone.getTimeZone("GMT"));

               System.out.println( formatter.format(new Date()) );

               The last line results in output of: "7 Apr 1998 21:52:06 GMT"

          You can even use:
             + formatter.setTimeZone(TimeZone.getDefault());

          It should be reasonably straight forward to adapt this code for
          your preferred format (e.g. change string to "hh:mm" or other) and
          timezone, e.g. change "GMT" to "ECT", "JST" or other timezone.

     5.9How are dates represented in Java?
        o A. java.util.Date stores dates as long integers representing the
          number of milliseconds since 00:00:00 UTC Jan 1, 1970 (the birth
          of Unix, a date known as the "Epoch"). Dates earlier than the
          Epoch are represented as negative numbers, counting away from
          1/1/1970.

          The scheme is sufficient to represent dates from 292,269,053 B.C.
          to 292,272,993 A.D. (64 bits covers -9223372036854775808 to
          +9223372036854775807 millesecs so divide by 1000 to get secs,
          divide that by 3600*24*365.25 to get years, and you get -2.9227E8
          to 2.9227E8 centered on the Epoch i.e. about 292,269,053 BC to
          292,272,993 AD).

          In JDK 1.1, Date was augmented by Calendar. Things didn't get any
          better. Instead of being ill-conceived and simple, it is now
          ill-conceived and complicated. The code was all licensed from
          Taligent. It didn't really improve matters. Dates are the lemon of
          Java, as Roedy Green truly notes.

          You could consider using the BigDate class written by Roedy, and
          available at http://oberon.ark.com/~roedy

     5.10 That may be, but how do I extract day, month, year from a Date?
        o A. In JDK 1.1, Date represents an instant in time. Calendar
          translates between an instant in time, and individual fields like
          year, month, day, etc

          So get your Date -- the current Date can be had by
             + Date now = new Date();

          Then construct a Calendar to do the translation:
             + Calendar mycal = Calendar.getInstance();
               mycal.setTime(now);

          // Now read the Calendar's fields using get().
             + System.out.println("Year = " + mycal.get(Calendar.YEAR));

          We hope (perhaps in vain) all this junk will be fixed once and for
          all in a future release.

     5.11 How do I create my own Time Zone to apply to dates?
        o A. The Calendar, DateFormat, and even TimeZone classes will give
          you the timezone of your system (wherever you are). You can create
          a TimeZone object with the GMT offset of your choice like this:

          bst_tz = new SimpleTimeZone( 6 * 60 * 60 * 1000, // +6 hour offset from GMT
                                       "BST");
          TimeZone.setDefault(bst_tz);

          You can then apply that TimeZone to create a Calendar object like
          so:

          GregorianCalendar BritishSummerTime =
                   new GregorianCalendar(bst_tz);

     5.12 How do I create the BST timezone specifically?
        o A. First, note the pitfall that as well as being the Bangkok
          Standard Time timezone 6 hours east of GMT, "BST" also means
          "British Summer Time".

          In most or all other timezones, daylight saving time is handled
          automatically and internally. But GMT is the reference for all
          other timezones, and so does not have the summertime update
          applied automatically. So here is the code to create a British
          Summer Time timezone that is offset 1 hour from GMT between two
          dates:

          import java.util.*;
          import java.text.*;

          // confirm whether BST does run from first Sun in Apr to last in Oct.

          // create a BST timezone
          SimpleTimeZone bst_tz =
             new SimpleTimeZone( 0, // no offset from GMT
                            "BST",  // individualized tz id
             Calendar.APRIL, 1 ,Calendar.SUNDAY,2*60*60*1000,  // first Sun Apr 2AM

             Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000  // last Sun Oct 2AM
          );
          // set the BST timezone as the default
          SimpleTimeZone.setDefault(bst_tz);

          // apply that TimeZone to create a Calendar object like so:
          GregorianCalendar BritishSummerTime =
               new GregorianCalendar(bst_tz,Locale.UK);

          and here is how you would print out values using BST:

          // create a template for printing the date
          DateFormat df = DateFormat.getTimeInstance(
                             DateFormat.LONG,Locale.UK);

          // tell the template to use BST tz.
          df.setTimeZone(TimeZone.getDefault());
          System.out.println("Using British Summer Time "
                            +"the time is: "
                            + df.format( BritishSummerTime.getTime() ) );

          // Now get and compare with current time in GMT
          df.setTimeZone(TimeZone.getTimeZone("GMT") );
          System.out.println("\nCurrent time in GMT is: "
                            + df.format(BritishSummerTime.getTime() ) );

          In the winter, this BST zone is aligned with GMT; in the summer it
          is one hour later (4am GMT is 5am BST).

          You can look at a list of timezone names and offsets in the file
          $JAVAHOME/src/java/util/TimeZone.java

     5.13What kind of different date formats are allowed for the Date
     constructor with the string parameter.
        o A. The Language Specification (which also covers the java.lang,
          java.util, and java.io packages) is the best reference for
          answering questions like this. It has much more detail than the
          API Documentation has, and it is available as a book or online at
             + http://java.sun.com/docs/books/jls/html/javautil.doc.html

          The Date(String) constructor is deprecated in Java 1.1, by the
          way.

     5.14 How do I get Java talking to a Microsoft Access database?
        o A. Use the JDBC-ODBC bridge. It is not especially challenging to
          set up, but it does require painstaking attention to detail. There
          is a step-by-step example in the van der Linden text "Just Java
          1.1" mentioned in the sponsorship section of this document.

          Note that the Microsoft version of the Java kit does not support
          JDBC-ODBC access because it uses a non-standard native code
          interface. Also check the JDBC FAQ listed at the end of this
          document.

     5.15I can't seem to change the current working directory.
        o A. Correct. This missing functionality is an oversight that we
          hope will be corrected in future. Changing the user.dir property
          merely changes the text property, not the underlying reality that
          it is supposed to reflect.

     5.16How do I create a Vector of ints?
        o A. ints are primitive types and hence can't be stored by the
          Vector class which stores objects. You'll need to wrap the ints.
          Try this:
             + int i =7;
               Vector holdsInts = new Vector(5,1);

               holdsInts.addElement(new Integer(i));
               int j = ((Integer)holdsInts.elementAt(0)).intValue();

     5.17 I have several worker threads. I want my main thread to wait for
     any of them to complete, and take action as soon as any of them
     completes. I don't know which will complete soonest, so I can't just
     call Thread.join on that one. How do I do it?
        o A. You need to use the wait/notify mechanism to allow any of the
          worker threads to wake up your main thread when the worker has
          completed.

     5.18How do I get random numbers?
        o A. If you just need a quick random double between 0.0 and just
          less than 1.0
             + double myrandom = Math.random(); // [0,1)

          The notation "[0,1)" is common math notation for "zero to .9999999
          etc" The Sun documents say this returns 0.0 to 1.0, but inspection
          of the source shows they are wrong. However, due to the inherent
          inaccuracies of floating point arithmetic, multiplying N by
          0.999999 etc can result in an answer of N, not N * .999999 . So
          watch out when N is big.

          Where things get even trickier is in the case where you want an
          int within a certain range, say 1 to 6 to simulate the throw of a
          die or 1 to 52 to represent a playing card. Class Random has a
          nextInt method that will return any integer:
             + import java.util.Random;
               Random r = new Random();
               int i = r.nextInt();

          However, that has an (almost) 50% chance of being negative, and it
          doesn't come from the right range. So you just take the abs()
          value and then mod it into the right range:
             + int dice_throw = 1 + Math.abs(i) % 6;

          Except, the abs() method fails gracelesslly in the presence of the
          Integer.MIN_VALUE (it returns the same, negative, result!). So it
          is better to AND to get the non-negative value: In general, to get
          a random int between high and low limits (inclusive):
             + java.util.Random r = new java.util.Random();
               int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;

          The sentence above states "(almost) 50% chance" because there is
          one more value in the negative integers than in the positive
          integers in two's complement arithmetic as used by Java. For most
          purposes, the bias introduced will be insignificant, but we "and"
          the nextInt() to convert it to zero. Sure, it's unlikely to occur,
          but you don't want the reactor going critical just because you
          missed this case while testing.

          A worse problem is that with the algorithm used, the low order
          bits are significantly less random than the higher order bits. And
          the low order bits are precisely the ones you get when you do the
          remainder operation.

     5.19 What does "deprecated" mean? I got this in a compiler error
     message.
        o A. The compiler will flag a now-obsolete API as "deprecated". The
          word means "officially disapproved of". Compile again with the
          "-deprecation" option to see what is deprecated. In almost all
          cases, the old API has been replaced by a new one. Update your
          code to use the new one.

          An example of using a deprecated API is calling component.size().
          That has been replaced by component.getSize().

     5.20 Where/why should I use the Enumeration interface?
        o A. It's a very convenient way to step through some of the library
          data structures, such as HashTable, Vector, and ZipFile. It is
          thread safe. If you're looking at an element in one thread while
          another thread is trying to delete it, it won't half vanish.

          Here's how you might look at every file in ZIP file:

          ZipFile z = new ZipFile("foo.zip");
          for (Enumeration e=z.entries(); e.hasMoreElements(); ) {
           ZipEntry ze = (ZipEntry)e.nextElement();

          System.out.println("got " + ze.getName() );
          }

          And here's how you might look at all the tokens in a String:

          StringTokenizer tokens =
              new StringTokenizer (SomeArbitraryString, "\n", false);

          Enumeration enum = tokens.elements();
          while enum.hasMoreElements()
              System.out.println(enum.nextElement());

          You should look for opportunities in your own data structures to
          implement Enumeration, anywhere where the structure has repeated
          elements.

     5.21 Which version of WinZip is compatible with java.util.zip?
        o A. You need WinZip version 6.2 or later. Version 6.1 or earlier is
          not good enough. WinZip can be downloaded from
          http://www.winzip.com/download.cgi. The pkzip software works fine.

     5.22 What is the Model/View/Controller paradigm?
        o A. Model/View/Controller is a design pattern used extensively in
          JDK 1.2. Basically, the "model" contains your data, the "view" is
          the graphical representation, and the "controller" is responsible
          for telling the "model" what happens in the "view".

     5.23 How can Java access other fonts on my system?
        o A. You do it by editing the fontnames in the font.properties file
          in the lib directory of your JDK release. Watch out for program
          portability when you do this.

          For fuller details, check the website
          http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft
          site at
          http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
          They have lots of information on this.

                             -------------------

6. I/O

   * 6.1How do I read a String/int/boolean/etc from the keyboard?
        o A. The easiest way is to pick up the source for the 100% pure Java
          class EasyIn from http://www.afu.com/ (same place as this FAQ)
          Compile it with your code and use it like this:
             + EasyIn easy = new EasyIn();

               int i = easy.readInt(); // gets an int from System.in
               boolean b = easy.readBoolean(); // gets a boolean from System.in
               double d = easy.readDouble(); // gets a double from System.in

          ... etc.

          EasyIn is free, comes with source, and you can do what you like
          with it, including improve it, and send me back the results.

          If, instead, you want to "roll your own" code (why?!) In JDK 1.0.2
             + java.io.DataInputStream in = new java.io.DataInputStream(System.in);
               String s = in.readLine();

          One way in JDK 1.1
             + java.io.BufferedReader in =
                new java.io.BufferedReader( new InputStreamReader(System.in));

               String s = in.readLine();

          Once you have the token in a String, it is easy to parse it into
          one of the other types, as shown earlier in the FAQ. Yes, it is
          bone-headed, as it makes the simplest case of keyboard I/O
          unnecessarily complicated. A bug was filed with Javasoft to record
          this problem, but don't count on this being fixed any time soon.

     6.2Why do I have trouble with System.out.println()?
        o A. Check the spelling. The last two characters are the letters
          "ell enn" not "one enn".

          The name of the method stands for "print line", since it prints a
          String and goes to the next line, rather than staying on the same
          line as System.out.print() does. Yes, the name is yet another Java
          naming inconsistency, since the input equivalent is readLine(),
          not readln().

     6.3How do I write to the serial port on my PC using Java?
        o A. There is a platform-independent serial port API introduced in
          JDK 1.2. You can download the documentation by registering with
          the Java Developer Connection (it's free, http://java.sun.com) and
          browsing http://java.sun.com/jdc/earlyAccess/communications.html.

          For systems prior to JDK 1.2, read on. At least two companies have
          written a library to drive the port. See
             + http://www.sc-systems.com has a library for Windows95,
               WindowsNT, OS/2, Mac PPC, Solaris Sparc, Linux x86, FreeBSD
               x86, HP/UX PA-RISC, and possibly others too.
               http://www.cd.com/portio

               In addition, there is a Unix serial port utility available
               with source at: http://jarvi.ezlink.com/rxtx/ It's free under
               the GPL, and works on Linux, Irix, Solaris, Win95, NT.

          While not helpful to typical home users, there is an alternative
          portable COM port solution for Java 1.1 and even 1.0. Buy your COM
          ports in the form of "terminal servers". Using a COM port is now
          as easy as connecting to it with a Socket. Port parameters can be
          changed programatically using SNMP for most terminal servers (but
          this is never necessary when a modern modem or other fixed rate
          equipment is attached). Any networked box can serve as a terminal
          server - even Win95 - with a simple native server application for
          that box, but buying an actual firmware based hardware box is much
          easier.

          Furthermore, your Win95 native applications can now share the COM
          ports (and any attached modems) via a Win95 product called
          "Dial-out IP": http://www.tactical-sw.com/

          If the port exists as a pathname in the filesystem, you can open
          it as a file and read/write. You can also print text this way by
          writing to "prn" or "lpt1" on a pc, and "/dev/something" on Unix.
          Writing a formfeed at the end of the file is essential on
          Windows95. Here is some sample code.

//class that opens the printer as a file and writes "Hello World" to it
import java.io.*;
public class lpt {
    public static void main (String[] argv) {
        try {
                FileOutputStream os = new FileOutputStream("LPT1");
                            //wrap stream in "friendly" PrintStream
                PrintStream ps = new PrintStream(os);

                            //print text here
                ps.println("Hello world!");

                            //form feed -- this is important
                            //Without the form feed, the text
                            //will simply sit in the print
                            //buffer until something else
                            //gets printed.
                ps.print("\f");
                            //flush buffer and close
                ps.close();
          } catch (Exception e) {
                System.out.println("Exception occurred: " + e);
          }
     }
}

   *
        o If you wish to change the characteristics of the port (e.g. baud
          rate, parity, etc), not just read/write data, Java currently
          offers no portable way to do this. You will need to use one of the
          packages mentioned above or some native code or a system command.

     6.4How do I append to a file?
        o A. There are two ways. JDK 1.1 introduced new constructors for two
          of the output classes, that allowed you to set a boolean flag:
             + public FileWriter(String fileName, boolean append) throws IOException
               public FileOutputStream(String name, boolean append) throws IOException

          Another way is to do this:
             + RandomAccessFile fd = new RandomAccessFile(file,"rw");
               fd.seek(fd.length());

          Then write using fd. Note that the latter method does not take
          advantage of the "append" mode present in many operating systems
          (such as all Unixes). Such a difference may make a difference with
          multiple processes or threads appending to the same output file.
          This can happen frequently, even if not intended by the
          programmer, e.g. with logfiles in multitasking environments. With
          the lack of file-locking mechanisms in Java the issue becomes even
          more significant.

     6.5Is it possible to lock a file using Java ?
        o A. Java does not feature an API to lock a file or regions within a
          file. Code that needs to do this must take one of four approaches:
             + 1. implement an advisory locking scheme using features that
               Java does have (synchronized methods). This allows you to
               lock files against use by other Java code running in the same
               JVM.

               2. Use an atomic operation like file "renameTo()" and have
               all processes (Java and non-Java) follow the same protocol:
               if the operation succeeds, you have the lock, and you change
               the file back to give up the lock. The FAQ previously
               recommended delete() or mkdir() as the primitive, but there
               has been a report that these operations are idempotent (can
               be repeated without error) in some JVMs. The suggestion of
               renameTo has been proven to work in practice. See
               http://www.camb.opengroup.org/~sanfilip/FileLock/ for example
               locking class docs and source.

               3. make calls to native code to issue the locking ioctls.
               This approach is not portable, but gives you a shot at having
               your locks respected by other programs using standard locking
               ioctls outside Java.

               4. Push the work to a central server. Since socket connection
               requests arrive in a single queue on the server, this can be
               used to serialize lock requests. There might be some merit in
               copying the NFS lockd protocol for a general approach.
               Rolling your own simple version for a specific application is
               pretty easy. A database would be better off locking records
               or fields, not byte offsets. In theory, the server socket
               approach would make it easier to perform automatic cleanup of
               a lock on abrupt VM process failure, e.g. by asking "are you
               still alive?" to the lock holder occasionally.

     6.6How do I make the keyboard beep in Java?
        o A. In JDK 1.1, java.awt.Toolkit has the method beep(). It does not
          work on NT 4.0 (bug).
             + System.out.print("\07");
               System.out.flush();

          should work, and works in JDK 1.0.2, too. That's the ASCII BEL
          character (Java doesn't support the C abstraction of '\a' for an
          alert character).

     6.7 How do I execute a command from Java? How do I do I/O redirection
     in Java using exec() ?
        o A. See answer to question 10.5

     6.8How do you do file I/O from an applet?
        o A. For security reasons, untrusted applets accessed across the
          network are restricted from doing certain operations, including
          I/O. This prevents rogue applets from sending out your private
          data, or deleting it. A trusted (signed) applet can perform these
          operations (JDK 1.1 on).

          The following suggestion is for server-side input.

          - You can read a file on the server if you can create a URL
          referencing the file. Then open a stream, then use any of the
          stream-based methods to read.

          This allows reading but not writing. It requires an http demon
          running on the server, which will usually be the case.
             + try{
                URL url = new URL("http://somewhere.com/test.txt");
                // or URL url = new URL( getDocumentBase(), filename);
                DataInputStream dis = new DataInputStream(url.openStream());
                String s = dis.readLine(); //read till you get a null line.
               } catch(MalformedURLException e){System.out.println("URLException:"+e);}
               catch(IOException e){System.out.println("IOException:"+e);}

          You cannot write a file on the server this way.

          The following suggestions are for server-side output.

          It absolutely requires the cooperation of the server to allow an
          applet to write a file to the server. This cooperation may take
          any of several forms:
             + ftp server process
             + file server (webnfs or custom written)
             + listening on a socket for data from applets
             + CGI script
             + Java RMI (remote method invocation)

          In particular:
             + 1. FTP code. Simon Arthur wrote some classes that will FTP a
               file over to the server (as long as it supports "passive mode
               FTP". The classes are at
               http://www.mindspring.com/~chroma/mail/Mail.html
               The code to use these classes to do an ASCII FTP goes like
               this:

               import java.applet.*;
               import java.io.*;
               import java.net.*;
               import SIMONARTHUR.mail.*;

               public class FConn extends Applet {

                   public void init() {

                       String servername = getParam("servername", "ftp.javasoft.com");
                       String username = getParam("username", "anonymous");
                       String  passwd = getParam("passwd", "user@abc.com");
                       String  dir = getParam("dir", "fTp");
                       String  file2trans = getParam("file", "test_read");
                       FTPConnection f = new FTPConnection(servername, "");
                       f.setUserName(username);
                       f.setPassword(passwd);
                       f.setDirPath(dir);
                       try {
                           URL uf = new URL(getDocumentBase(), file2trans);
                           InputStream ufi = uf.openStream();
                           f.putFile("test_write", ufi, false); // true=binary FTP
                           ufi.close();
                           f = null;
                       } catch(Exception oops) {oops.printStackTrace();}
                       System.out.println("Finished ftp transfer...");
                   }

                   protected String getParam(String name, String defaultValue) {
                       String s = getParameter(name);
                       return (s == null) ? defaultValue : s;
                   }
               }

               The HTML might look like:

               <applet code=FConn width=300 height=300>
                 <param name="servername" value="ftp.javasoft.com">
                 <param name="username" value="anonymous">
                 <param name="passwd" value="user@abc.com">
               </applet>

               2. WebNFS. This is an evolution of the NFS (Network File
               System) to make file resources visible in browsers. More
               information at http://www.sun.com/webnfs

               3. Open a socket back to the server and read/write the data.
               Have a process on the server that listens for socket
               connections from applets and does the requisite I/O. This
               does I/O on the server.

               4. Or use a CGI script or servlet on the server to write when
               browsed. There is some source at
               ftp://ftp.oyster.co.uk/pub/java/fileIO/

          The following suggestions are for client-side I/O.

          3. Use a trusted applet (see section on security). This will
          permit local I/O without any of the restraints mentioned above. In
          this regard, the appletviewer and many other browsers regard
          applets loaded from a local filesystem (rather than across the
          net) as being more trustworthy, and perhaps even allowed to do
          I/O.

          4. Or use a browser that has a security policy that is configured
          to allow file I/O (such as Sun's appletviewer).

     6.9I used a C program to write a binary file. When I instantiate a
     DataInputStream on the file in Java, and try to readInt, I do not get
     the correct numbers. Why is this?
        o A. Java does everything in network byte order (big-endian order),
          as do many computers including Motorola, and SPARC. The Intel x86
          uses little endian order in which the 4 bytes of an int are stored
          least significant first. Rearranging the bytes on the way in will
          get you the results you need. This is only necessary when the file
          was written by a non-Java program on a little endian machine such
          as a PC.

          The following code will byte-swap little-endian integers into
          network standard order
             + public int swap(int i) {
                int byte0 = i & 0xff;
                int byte1 = (i>>8) & 0xff;
                int byte2 = (i>>16) & 0xff;
                int byte3 = (i>>24) & 0xff;
                // swap the byte order
                return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
               }

               Alternatively, the following code assembles bytes from a byte
               array in big-endian order (as used by Java) into an int:

               byte[] bytes = ... // whatever
               int start_index = ... // wherever

               int value = 0;
               for ( int i = start_index; i
               If the bytes are in little-endian order, just change the "for":
               for ( int i = start_index+3; i >= start_index; --i )

               And this code will assemble a double that has been written in
               reverse byte order:

               byte[] gnol = byte[8];
               stream.read(gnol);

               long l = ( (gnol[7]&0xff)<<56) | ((gnol[6]&0xff)<<48) | | ((gnol[5]&0xff)<<36) | ... // and the rest double d = Double.longBitsToDouble(l).doubleValue();

     6.10How do I make I/O faster? My file copy program is slow.
        o A. This is the purpose of BufferedInputStream. It is a flaw in
          Java that buffered I/O is not the default, with a flag or
          different constructor to turn it off. I/O is the second worst
          designed package in Java, after the Date class.

     6.11How do I do formatted I/O of floating point numbers?
        o A. Look at http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html
          for the html with the javadoc info. The actual file is called
          http://www.apl.jhu.edu/~hall/java/CoreJava-Format.java However,
          you must rename the file to Format.java for it to compile. Also,
          one version of this had a bug: when you try to format a true 0 you
          go into an infinite loop (need to test d in exp_format).

          Although many utilities claim to handle all varieties of C's
          printf, as far as has been found, this is the only one to
          correctly handle the equivalent of %e in printf.

     6.12How do I read numbers in exponential format in Java?
        o A: The program below (written by Steve Chapel) uses
          StreamTokenizer to read data from the standard input and
          recognizes doubles in exponential format (e.g. -1.23e-45).

     import java.io.*;

     public class ReadExponential {
      public static void main(String argv[]) {
      DataInputStream in = new DataInputStream(System.in);
      StreamTokenizer st = new StreamTokenizer(in);
      try {
      while (st.nextToken() != StreamTokenizer.TT_EOF) {
      switch (st.ttype) {
      case StreamTokenizer.TT_NUMBER:
      double num = st.nval;
      int exp = 0;
      st.ordinaryChars('\0', ' ');
      st.nextToken();
      st.whitespaceChars('\0', ' ');
      if (st.ttype == StreamTokenizer.TT_WORD &&
      Character.toUpperCase(st.sval.charAt(0)) == 'E') {
      try {
      exp = Integer.parseInt(st.sval.substring(1));
      } catch (NumberFormatException e) {
      st.pushBack();
      }
      } else if (st.ttype < 0 || st.ttype > ' ')
      st.pushBack();
      System.out.println("Num " + num * Math.pow(10, exp));
      break;
      case StreamTokenizer.TT_WORD:
      System.out.println("Word " + st.sval);
      break;
      default:
      System.out.println("Char '" + (char) st.ttype + "'");
      break;
      }
      }
      } catch (IOException e) {
      System.out.println("IOException: " + e);
      }
      }
     }

     6.13I'm trying to read in a character from a text file using the
     DataInputStream's readChar() method. However, when I print it out, I
     get ?'s.
        o A. Remember that Java characters are 16-bit Unicode characters,
          while many hosts systems store characters as 8-bit ASCII
          characters. Therefore, to read individual chacters from a text
          file, you need to ensure the proper conversion. The proper way to
          do this is to use an InputStreamReader, which converts from 8 to
          16 bit streams:
             + FileInputStream fis = new FileInputStream("myfile.txt");
               InputStreamReader isr = new InputStreamReader(fis);
               char c3 = (char) isr.read();

          The less-favored way (because it is not so portable, as the
          encodings translation is not done) is just to read a byte and cast
          it into a character:
             + FileInputStream fis = new FileInputStream("myfile.txt");
               DataInputStream dis = new DataInputStream(fis);
               char c1 = (char) dis.readByte();

     6.14How do I delete a directory in Java?
        o A. JDK 1.0 did not support directory removal. JDK 1.1 supports
          directory removal with the method:
             + public boolean delete() in class java.io.File

          Make sure you don't have any open streams in the directory you're
          trying to remove. Do a close() on all streams, even if the
          underlying file is gone.

     6.15 How do I tell how much disk space is free in Java?
        o A. There currently aren't any good Java APIs for system
          introspection. There is no Java way to control processes, or look
          at system resources. You can use Runtime.getRuntime().exec() to do
          "df" on unix or "dir" on Windows right now.

          Alternatively, check out JConfig:
          http://www.tolstoy.com/samizdat/jconfig.html
          JConfig is a cross-platform library that fills in many of the gaps
          in the core Java API, and makes it possible to work with files,
          processes, file types, video monitors, etc. in a much more Windows
          and Mac friendly manner.

     6.16 How do I get a directory listing of the root directory C:\ on a
     PC?
        o A. The obvious approach of calling File.list("C:\"); does not
          work. There are two reasons why this fails. First, slash is an
          escape character in Java, so if you want a literal slash, you have
          to repeat it. Second, you need to give the name of the directory,
          i.e. dot. Putting this together, either of the following calls
          will work

          File.list("C:\\.");
          or
          File.list("C:/.");

          Note: a file separator of "/" works just as well as "\" in most MS
          Windows programs and library calls. It is an artifact of DOS's
          origin's as a ripped-off port of CP/M. They changed the direction
          of the CP/M file separator, See also JConfig in Q6.15.

     6.17 What is the difference between the various ZIP formats: ZIP, GZIP,
     and PKZIP?
        o A. GZIP files (the Gnu format) are not archives and compress only
          one file. GZIP is essentially a one file subset of the Zip format.
          Zip is an archive file format, popularized on PCs, that contains
          multiple compressed files. PKZIP is a set of
          commercially-available programs that create Zip files. All three
          PKZIP, GZIP and Zip use the deflate compression format, which is
          based on the LZ77 algorithm. This compression is also used by the
          ZLIB library and hence the PNG graphics file format (which uses
          ZLIB). PNG - Portable Network Graphics - provides a patent-free
          replacement for GIF and TIFF. If you save a GIF, don't forget to
          pay the royalty to UNISYS. The PNG format is specified in RFCs
          1950, 1951, and 1952, and is unencumbered by licenses or patents.

          An alternative compression technology, LZW compression, is
          encumbered by Unisys's patent. LZW is used in GIF files and by the
          Unix compress command. Luckily, as well as being free from patent
          restrictions, LZ77 also gives better compression than LZW. LZW is
          the initial letters of the last names of the three computer
          scientists who developed the algorithm (Lempel, Ziv, Welch).

          The basic classes (all in java.util.zip) that read LZ77 Zip format
          are Deflater and Inflater. These are used by the stream classes
          DeflaterOutputStream and InflaterInputStream. The java.util.zip
          classes GZIPInputStream and ZipInputStream inherit from
          InflaterInputStream.

          PKZIP is a commercial program for DOS, Windows, and OS/2, sold by
          PKWARE Their FAQ (http://www.pkware.com/zipgfaq.html) specifically
          says
             + "Because PKWARE has dedicated the .ZIP file format to the
               public domain, it is possible for other people to write
               programs which can read .ZIP files. NOTE THAT THE PKZIP,
               PKUNZIP, PKSFX PROGRAMS AND THEIR ASSOCIATED SOURCE CODE AND
               SUPPORT PROGRAMS ARE THE EXCLUSIVE PROPERTY OF PKWARE INC.
               AND ARE NOT PUBLIC DOMAIN SOFTWARE PROGRAMS.

          The "other people" PKZIP's FAQ refers to is the InfoZIP project, a
          group of public-minded programmers spread over the world producing
          free software that works on most ANSI C compilers and platforms.
          See
             + http://www.cdrom.com/pub/infozip/

          Jar files are in ZIP format, but are not as complete as a full
          filesystem archive format since file permissions are not saved.
          Some versions of WinZip are known to be inadequate for processing
          the full PKZIP format. Use InfoZIP instead.

     6.18 How can I use characters other than ASCII in Java?
        o A.Search for the article titled "Adding Fonts to the Java Runtime"
          at http://java.sun.com.

          The article explains how to add fonts to Sun's JDK, using the
          font.properties file. [If anyone has summarised the information,
          please send it in].

     6.19 I did a read from a Buffered stream, and I got fewer bytes than I
     specified.
        o A. This is the way that BufferedInputStream works up to and
          including the current release. The behavior is so unintuitive that
          it really represents a bug. Javasoft has "resolved" the bug by
          writing the comments in the program so that the behavior is not
          disallowed.

          When you instantiate a buffered input stream, you can specify the
          size of buffer it should use. Let's call this the internal buffer.
          When you call read() you can say how many bytes to read. Let's
          call this the request. If the request is smaller than the internal
          buffer and not a multiple of the internal buffer, then the last
          read returns only the odd bytes left in the internal buffer! The
          more reasonable and intuitive behavior would be for the internal
          buffer to be refilled, so that the whole request can be granted.

          For example, if you create a BufferedInputStream with an internal
          buffer of 1000 bytes, and try to read 512 byte chunks, your first
          read will return 512 bytes, but your second read will only return
          (1000-512), or 488, bytes. (Assuming that the file has at least
          that many bytes in it). The following code illustrates the
          problem.

          // troubleshooting by Tov Are Jacobsen
          import java.io.*;
          class filebug {
            public static void main(String args[]) throws
                                  FileNotFoundException,IOException  {
              BufferedInputStream bis =
                 new BufferedInputStream( new FileInputStream("test.txt"),
                                          1000 );
              byte[] buf = new byte[2000];
              int numread;
              System.out.println( "Available: "+bis.available() );
              while (true) {
                  numread = bis.read(buf,0,512);
                  if (numread<0) break; System.out.println( "got "+numread+", avail:"+ bis.available()); } } }

          Of course, a valid reason for getting less than you asked for is
          that you asked for more data than is actually available in the
          Stream, e.g. you requested 512 bytes from a file that only
          contains 40 bytes. In general, there are no guarantees about how
          much data is returned for a given buffered input stream read
          request. To avoid this problem, push a DataInputStream on top of
          your buffered stream. Then you can call readFully() which will do
          what you want. A similar "got less than I asked for" occurs when
          reading a socket. Network protocols frequently packetize data and
          send it across in bursts. Nothing is lost of course, and you are
          always told how many bytes you actually got. You will get the
          remaining bytes on a subsequent read. This happens regardless of
          the language used. Be sure to check the "amount of data returned"
          when using the read(byte[], int, int) method of
          BufferedInputStream, or when reading from a socket. Another
          problem with java.io.InputStream.read(byte[], int, int) is that it
          catches and ignores IOExceptions. Instead, these exceptions should
          be passed on to the caller. Ace programmer Jef Poskanzer,
          jef@acme.com, has a version to do this at
          http://www.acme.com/jef/.

6.20 How do I redirect the System.err stream to a file?

   * A. You cannot assign a new FileOutputStream to System.err, as it is
     final. Instead use the System.setErr() library call, like this:

     System.setErr(new FileOutputStream("myerrors.txt"));

     This was introduced with JDK 1.1. There is also a corresponding setIn()
     for redirecting standard in, and a setOut() for standard out.

                             -------------------
7.NETWORKING & DISTRIBUTED OBJECTS

   * 7.1Should I use CORBA in preference to RMI? Or DCOM? Or what?
        o A. If your distributed programs are all in Java, then RMI provides
          a simpler mechanism that allows the transfer of code,
          pass-by-value of real Java objects, and automatic garbage
          collection of remote objects.

          If you need to connect to C++ (or other language) systems or you
          need CORBA-specific services, then CORBA is your choice.
             + http://www.javaworld.com/javaworld/jw-10-1997/jw-10-corbajava.html

          has a good intro to CORBA in the Java world.

          In July 1997, Sun announced that it was aligning RMI to work more
          closely with CORBA. Sun is simply adding an IIOP transport layer
          to RMI to support interoperability with CORBA. Java programs can
          then access CORBA-based objects through IIOP, the OMG's
          CORBA-based protocol. This is very good news for those building
          heterogenous Enterprise systems, although it will take some
          additions to IIOP to support the pieces that RMI uses.

          Microsoft spokespeople have tried to promote DCOM by spreading
          misinformation that RMI is changing or being dropped. That is
          totally wrong. The RMI API continues unchanged in its current
          form. Using DCOM would restrict your code to only ever run on
          Microsoft platforms using Intel hardware, and negates the "write
          once, run anywhere" Java philosophy. Non-portable, single vendor
          code should be avoided.

     7.2 hang for a">Why does <my java debugger/IDE/other> hang for a couple
     of minutes if my Windows PC is not dialed up to the Internet?
        o A. Java has networking support built in. When the Java program
          starts the Winsock dll automatically gets loaded. The first thing
          this does is to try to resolve the fully qualified domain name for
          your machine under the name "localhost". If your system doesn't
          have this name mapped, it will try to query a nameserver on the
          internet, which is typically (on a PC) your dialup ISP. So it
          either prompts you to connect to the ISP, or waits till the
          attempt times out.

          You can sometimes minimize the Win95 problem by giving your system
          another way to resolve DNS names. Edit the hosts file for your
          system so that localhost and the full domain name are both
          mentioned. On Windows 95 systems the hosts file is: %windir%\HOSTS
          (for example, C:\WINDOWS\HOSTS)
          On Windows NT systems the hosts file is:
          %windir%\System32\DRIVERS\ETC\HOSTS (for example,
          C:\WINNT\System32\DRIVERS\ETC\HOSTS)

          So if my system is called goober.best.com change the hosts file
          from
             + 127.0.0.1 localhost

          to
             + 127.0.0.1 goober.best.com localhost

          or (showing more of the file) to

               # Hosts file
               127.0.0.1       localhost
               129.146.77.177  goober

          Another alternative is to dial up with a PPP connection to your
          ISP whenever you want to run networking programs. Fundamentally
          the experience of some people has been that networking is not
          completely satisfactory on Windows95, and is subject to sporadic
          unexplained failures. If this occurs to you, there is little
          choice but to reboot and start again. Microsoft has several
          network-related patches at its site http://www.microsoft.com

     7.3 If I call the InetAddress.getByName() method with an
     IP-address-string argument, like "192.168.0.1",I get an
     UnknownHostException on some platforms, but not others. Code like
        o Socket sock = new Socket("155.152.5.1", 23);

     triggers the exception. Why?
        o A. This is a platform difference that arises out of different
          semantics in the underlying network libraries, and is [said to be,
          but subject to confirmation] fixed in JDK 1.1. On Solaris and
          Windows NT, the IP address string only works for IP addresses that
          have an associated hostname. On Linux and Windows 95, the IP
          address string works in all cases.
          http://www.cdt.luth.se/~peppar/java/InetAddress/ has a workaround.

          When InetAddress is instantiated with an IP address, a reverse DNS
          lookup is done. If the IP address is not associated with a valid
          hostname, the instantiation will fail. This is part of anti
          DNS-spoofing, and in JDK 1.1 works because the reverse lookup will
          not occur until the hostname is asked for. So in JDK 1.1,
             + InetAddress in = InetAddress.getByName("155.152.5.1");

          [Note: this info is still to be confirmed. Net gurus?]

     7.4 I am using JDK 1.1.1 on Windows95, and when I start jdb I get
     "Uncaught exception: java.lang.UnsatisfiedLinkErrorno winawt in shared
     library path"

     The same program works OK using jdk1.1
        o A. It *sounds* like your java\bin directory is not on your PATH
          and so the system can't find the winawt DLL.

          But actually the problem is the version of Microsoft's Visual C++
          that was used to build the product. VC++ 4.2 incorrectly generates
          code that depends on MSCVRT.DLL or in the case of java_g,
          MSVCRTD.DLL. These DLLs are not present in (some versions of)
          Win95. To make things even more interesting, some versions of
          Win95 (yes, there are at least four different ones...) ship with a
          broken MSVCRT.DLL (and MSVCRTD.DLL?) that seems to work, only it
          doesn't, and after a while it dies.

          Sun linked the winawt_g.dll with VC++ 4.2, which wrongly brought
          in MSVCRTD.DLL, the debug version of the VC++ runtime. You have to
          get that library from somewhere (like, say, VC++)
          in order to get jdb to run.

          You'll hit this problem any time you try to debug 1.1.1 code with
          jdb on a win95 system that doesn't have VC++ (or the MSVCRTD.DLL
          library from some other source) installed. At least this is a
          problem you can solve without waiting for the next release.

          Some people say that the missing library has been seen at
          http://cag-www.lcs.mit.edu/curl/Binaries/PC/ Others say you need
          to buy VC++ to get it.

     7.5I want to pass a class file to willing recipients who are using my
     applet. Any ideas how?
        o A. You could use a trick: put your .class file(s) in a .zip
          archive and use showDocument() on the URL. A person accessing this
          will get a dialog box put up asking them about saving the file to
          their local hard disk. You can see this in action and try it out
          yourself at:
             + http://www.best.com/~rmlynch/saveit.html

     7.6How do you succeed with new URL(someURL) from behind a proxy server?
        o A. Tell the run time system what you are trying to do, like this:
             + java -DproxySet=true -DproxyHost=proxy_host
               -DproxyPort=proxy_port \MyJavaProgram

          note proxyPort is optional and it defaults to 80.

     7.7What is "swizzle", as in "Swizzle this object?"
        o A. It means serialize. To swizzle an object is to recursively
          serialize or flatten composed objects.

     7.8I have been using the Serializing capabilities in 1.1 to save some
     objects to disk. I added a new field to one of my objects that get
     serialized and now deserializing my old data no longer works. I get
     this exception:
        o java.io.InvalidClassException: MacroData; Local class not compatible

          A. You need to add a declaration such as
             + static final long serialVersionUID = 4021215565287364875L;

          in the modified class. The actual value of this long is supplied
          by the "serialver" utilitity suppied with the JDK. Any versions of
          a class other than the first version require this static to be
          defined
          in the class. This is how versioning is achieved.

     7.9My socket code looks good, but is broken!
        o A. When using sockets you typically open both inward and outward
          streams. If you close one of them, the other seems to 'break'
          instantly. Check whether this is happening for you, by adding the
          matched pair.

          [comments from net gurus welcome]

     7.10 How do I map between IP address and hostname?
        o A. In Java 1.1 (earlier releases were buggy) use:
             + String host = InetAddress.getByName("211.10.2.119").getHostName();

     7.11How do I embed an anchor in a URL? Just putting it as part of the
     string in the constructor doesn't work.
        o A. Like this:
             + URL url = new URL("http://www.my_domain.com/my_page.html");
               URL anchor = new URL(url, "#section2");
               this.getAppletContext().showDocument(anchor);

     7.12RMI seems to have stopped working for me in JDK 1.1. Why is this?
        o A. The rules for where the client looks for a stub class seem to
          have changed making it necessary to reset your class path on the
          client after starting the rmi registry. In particular, it looks
          like rmic was not updated to the new "don't need $CLASSPATH"
          convention as the compiler was.

          There are several very good sources available from Sun which cover
          many simple and advanced RMI problems. They are:
             + The documentation, of course:
                  + http://java.sun.com/products/jdk/1.1/docs/guide/rmi/index.html
             + Dedicated FAQs on RMI and Object Serialization
                  + http://java.sun.com/products/jdk/rmi/faq.html
             + Mailing list RMI-USERS@JAVASOFT.COM with archive at
                  + http://chatsubo.javasoft.com/email/rmi-users/

          Visit the archive!

     7.13After a number of RMI client to server connections (55 on my
     system), subsequent RMI clients trying to connect fail. Why?
        o A. You are hitting the default limit of 64 open file descriptors.
          Try increasing the limit in your OS.

          In addition there is currently a practical RMI connection limit
          imposed by the scalability of the VM and the performance of object
          serialization. In JDK 1.2 this is addressed. The actual number of
          active clients you will be able to support will depend on the
          workload mix you have (i.e. the number of clients, how often they
          talk to the server, and how much work must be done per call).

     7.14 How do I POST to a CGI script from an applet?
        o A. Let's start by noting that this is more troublesome than it
          might seem at first, and that GET is preferred. For an untrusted
          applet, the CGI script can only be on the server that served the
          applet. Then use code like this:
             + try { sock = new Socket(host, 80);
               dock = new DataOutputStream(sock.getOutputStream());
               dock.writeBytes("POST "+cgiloc+" HTTP/1.0\n");
               dock.writeBytes("Content-type: text/html\n");
               dock.writeBytes("Content-length: " +my_string.length() + "\n\n");
               dock.writeBytes(my_string+"\n");
               dock.close();
               sock.close();

               uresp = new URL(getDocumentBase(),"respond.html");
               getAppletContext().showDocument(uresp); }

          The my_string contains the data you want to POST to the CGI
          script. The string should be encoded in the special way CGI
          expects. The class method java.net.URLEncoder.encode(my_string)
          will do it. The CGI has to write its output to respond.html so
          that it can be displayed by the browser. Even this won't really
          work, because respond.html could be overwritten by a subsequent
          request to the same CGI before the results of the first POST are
          read back.

          To get an acceptable solution takes quite a lot of effort. There's
          a pretty good explanation at
          http://www.javaworld.com/javaworld/javatips/jw-javatip41.html In
          general you should prefer GET to POST for CGI access from Java. As
          it says on the Javaworld page, the answers to the question are
          really: you can't, don't POST (use GET), use a bean, or cheat.

          Finally, if you request a url via the
          URLConnection/HttpURLConnection, the server sets the content type,
          and your applet can use URLConnection.getContentType() to get the
          type. Alternatively, use setRequestProperty to set it, like this:
             + url = new URL(cgiUrl);
               urlc = url.openConnection();
               urlc.setRequestProperty("Content-type", "application/x-www-form-urlencoded");

     7.15 How do I get a URLConnection to work through proxy firewalls?
        o A. The following code should do what you want.

          // set up to use proxy
          System.getProperties().put("proxySet", "true");
          System.getProperties().put("proxyHost", "proxy.server.name");
          System.getProperties().put("proxyPort", "80");

          Q. But how do I know the name of the proxy server?
          A. This code just tells you how you can get a URL connection to
          the outside. Since it is your proxy server, you are expected to
          know the name of it. There isn't any code that you can write that
          will allow arbitrary URL connections to be initiated from outside
          the firewall. Think about it! If there were, the firewall would
          not be doing its job.

     7.16 How can I write CGI programs in Java?
        o A. CGI (the Common Gateway Interface for web servers) is an API
          for writing programs that use the web as its user interface. By
          far, the most popular language for this task is Perl, because of
          its powerful text handling capabilities, and excellent resources
          available for making the jobs of CGI programmers easier. CGI
          programs can be written in any language, including Java.

          Unfortunately, the interface between the web server and the CGI
          program uses environment variables extensively. Use of environment
          variables is deprecated in Java 1.1, because of portability issues
          (not all systems have environment variables). The way to get
          around this is to write a "wrapper" for the Java program in a
          language that supports environment variables, and can then invoke
          the Java program with the appropriate environment data passed in
          as Java properties.

          Because the Java runtime environment is not a lightweight process,
          it might take a moment for the CGI program to get started before
          anything happens. This is particularly true on operating systems,
          like NT, that have a large overhead to spawning new processes.

          In preference to using Java for CGI on the server, you might
          consider using the Java servlet API in Netscape's Enterprise
          Server. This allows you to develop server-side programs in Java
          without suffering the same performance restrictions and other
          limitations of the CGI API. See
          http://search.netscape.com/comprod/server_central/query/eval_guide/enterprise/advantage.html
          for more details.

     7.17 How can I write the "ping" program in Java?
        o A. You can't. Quoting from the Java Networking FAQ, which you can
          find at http://www.io.com/~maus/JavaNetworkingFAQ.html

               Ping requires ICMP packets. These packets can only be
               created via a socket of the SOCK_RAW type. Currently,
               Java only allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP)
               sockets. It seems unlikely that this will be added very
               soon, since many Unix versions only allow SOCK_RAW
               sockets to be created by root, and winsock does not
               address ICMP packets (win32 includes an unsupported and
               undocumented ICMP.DLL).

                              * ------------------

8.MULTI-MEDIA

   * 8.1Why won't my audio file play?
        o A. Java 1.1 and earlier releases use one audio format exclusively.
          The audio file must be in .au format, recorded at 8 KHz, mono, in
          mu-law encoding. If your audio clip is in a different format
          (e.g., .wav) or a different frequency it must be converted to the
          exact specifications above before Java can play it. Support for
          .wav and other formats is part of the Java Media Framework coming
          in JDK 1.2.

          Search at www.yahoo.com for GoldWave for Win 95, sox for Unix and
          similar conversion utilities for other systems. One conversion
          utility in Java is at http://saturn.math.uaa.alaska.edu/~hursha
          The source of a Java class to play linear PCM .WAV files is at:
          http://www.shef.ac.uk/~cs1mjp/Java/WhiteBoard/WavePlayer.html It
          can be used in any Java application or applet.

     8.2Does Java support Animated GIFs?
        o A. Java 1.0.2 and earlier releases use GIF and JPEG formats, and
          do not use the GIF89 animated GIF format. (An animated GIF is one
          that contains successive frames of an image, so when they are
          displayed in quick sequence the image appears to contain
          movement). When you display an animated GIF in Java 1.0.2, you
          will just get the first frame. There doesn't appear to be any easy
          way to get other frames from the image.

          The advantage of an animated GIF file is that there is only one
          file to download, and it is simple to do simple animations. The
          advantage of programmatic control over individual frames is that
          you control the rate and order of displaying them.

          Here's a surprise: JDK 1.1 supports the animated display of
          animated GIFs. For simple animations animated GIFs are a lot
          easier and lighter-weight than coding an animation explicitly.

          8.2.0 How do I create animated GIFs?
             + A. Use GIFanimator from ULead (said to be the best)
               http://www.ulead.com, or GIF Construction Set from Alchemy
               Mindworks

          8.2.1How do I prevent animated GIFs from flashing while
          displaying?
             + A. The problem is most likely that in your paint method you
               have
                  + g.drawImage(img, ix, iy, this);

               You should change this to
                  + g.drawImage(img, ix, iy, getBackground(), this);

               This will change all the transparent regions of the image to
               the background color before painting to the screen. If you
               paint transparent images directly to the screen they flicker.

               If that does not solve it then check that:
                  + 1. ImageUpdate is

                    public boolean imageUpdate(Image img, int flags, int x,
                     int y, int width, int height) {
                     if ((flags & (FRAMEBITS|ALLBITS))!= 0) {
                     repaint();
                     }

                     return (flags & (ALLBITS|ABORT)) == 0;
                    }

                    2. update is

                    public void update(Graphics g) {
                     paint(g);
                    }

               If you have a background Image behind the partly transparent
               animated GIF you will have to double buffer. You can crop the
               backgound image so you won't have to double buffer the full
               app and waste too much memory.

     8.3Does Java support transparent GIFs?
        o A. GIF89a images with a transparent background show up as
          transparent without further filtering. This has been supported
          from 1.0 on. Java correctly displays both animated GIFs and
          transparent GIFs.

          Even better, you can fill the transparent pixels with a color (so
          they appear non-transparent in Java). Just pass the fill color
          explicitly:
             + drawImage(img, x, y, w, h, fillcolor, this);

          Further, you can filter the pixels of an Image to turn any bits
          you wish transparent. However, the most you can do is reveal what
          is underneath the image. You cannot reveal what is underneath the
          applet (i.e. on the browser itself). By default applets have a
          plain grey background.

     8.4How do I play video in Java?
        o A. Use the Java Media Framework Player API

          The spec can be found at
             + http://java.sun.com/products/java-media/jmf/mediaplayer/

          Intel has released a SDK for the Java Media Framework Player API.
          The SDK is for Windows 95 and Windows NT For more information, see
             + http://developer.intel.com/ial/jmedia

          SGI has released an implementation of JMF for IRIX:
             + See http://www.sgi.com/Products/motion/

     8.5How can I play *.au files from an application?
        o A. A new static method was introduced in JDK1.2 in the class
          Applet:

          public final static AudioClip newAudioClip(URL url) {

          The method turns a URL (pointing to an audio file) into an
          AudioClip. Since the method is static it can be used without any
          objects of class Applet needing to exist, e.g. in an application.
          Once you have an AudioClip, you can play it with

          MyAudioClip.play();

          The Java Media Framework provides a richer API for playing sounds
          in an application.

          For code prior to JDK 1.2, you can use the AudioClip or
          AudioPlayer class in sun.audio
          http://www.javaworld.com/javaworld/javatips/jw-javatip24.html If
          you do this your code is no longer 100% pure Java, as it relies on
          a vendor library.
             + import sun.audio.*;

               URL url; ...
               AudioStream audiostream = new AudioStream(url.openStream());
               AudioPlayer.player.start(audiostream);
               ...
               AudioPlayer.player.stop(audiostream);

          b. Use the new Java Media Framework API, allowing a wide range of
          video and audio formats to be played back. See previous question
          for implementations of this.

     8.6How do I read in an image file, in an application?
        o A. Use
             + Image img = Toolkit.getDefaultToolkit().getImage(fname);

     8.7 When I initialize a component,I call MyComponent.getImage() to get
     its image. createImage() returns null! I know the image works
     elsewhere. What's wrong?
        o A. A peer component needs to exist for your component before you
          can get its image. This is done by the method addNotify() (surely
          one of the most poorly named methods in all Java -- it doesn't
          mean "add a Notify". It means "Notify that the Component has been
          added to a Container". It tells the system, "you need to create
          the peer for this Component now"). addNotify will be called for
          you when you add your component to a container.

          Javasoft recommends against explicit calling (and, presumably
          overriding also) of addNotify() by applications programmers - this
          is especially important in these days of Lightweight components
          that do not have peers. If you have any code that requires peer
          resources, move it into a conditional branch of the paint() or
          update() method. A common reason for seeming to require peer
          resources in a constructor, or alternatively in the
          getPreferredSize() method, (which is also usually before the peer
          is created) is to measure the area required for your window, in
          terms of font and image sizes.

          Font sizes may be obtained by applying
          Toolkit.getDefaultToolkit().getFontMetrics() to the required font.
          This does not require a peer. Image sizes may be obtained by
          waiting for the relevant Image to load from the ImageProducer by
          using an ImageObserver, or a MediaTracker (see 8.15), also without
          requiring a peer. See 15.4 for more discussion of this problem.

          If you override addNotify(), don't forget to call
          super.addNotify() in your overriding version.

     8.8 How can Iforce a reload a fresh version of an image into my applet?
     My image file is changed periodically, and I want the applet to go and
     retrieve it, not cache it.
        o A. You need to turn off caching for the URL.
             + URL url = null;
               URLConnection con;
               try {
                url = new URL(getDocumentBase(),"image.jpg");
                con = url.openConnection();
                con.setUseCaches(false);
               } catch (MalformedURLException e1) {System.err.println(e1.getMessage());}
               catch (IOException e2) {System.er.println(e2.getMessage());}

          Note: some programmers have reported that it caches anyway, even
          if that do this. That is a browser bug.

          One programmer reported that even after turning off caching and
          calling image.flush() before getImage(..), he was still seeing the
          same picture even though it had been changed on the server.

          He worked out a solution: access the image via a cgi script that
          returned a URL. This redirects the browser, and he put in an
          Expires: header as well to force the reload. Painful and
          laborious, but it got the result.

     8.9 How can Isave an Image file to disk in jpg or gif format?
        o A. A number of people have written utilities to do that. One of
          them is available at the same place as this FAQ:
             + http://www.afu.com
               Jef Poskanzer has written an abstract ImageEncoder class and
               implemented it for GIFs and PPMs. Those are at
               http://www.acme.com/java/software/
               A non-java solution is to use the standard IJG 'cjpeg'
               utility. It supports GIF, PPM, BMP, PNG and Targa input
               files.
               Hong Shi wrote a PPM to JPEG convertor.
               http://www.ctr.columbia.edu/~hshi/report6880.htm
               Sean Breslin has written a program that compresses a Java
               Image into a JPEG file. http://www.afu.com/jpeg.txt
               Florian Raemy has written a program that encodes a JPEG then
               decodes it again. http://lcavwww.epfl.ch/demos/jpeg.html This
               is a proof of concept, not industrial strength code that
               meets the JFIF (JPEG File Interchange Format) standard.

     8.10 What causes this problem?
        o $ appletviewer m.html
          Premature end of JPEG file
          sun.awt.image.ImageFormatException: JPEG datastream contains no image
          at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:133)
          at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:215)
          at sun.awt.image.ImageFetcher.run(ImageFetcher.java:98)

          A. There's a known bug in early releases of the JDK which can
          cause the above failure when reading a JPEG across a slow
          connection. The failure only occurs if the JPEG contains a large
          application data block (APPn marker) --- the problem is that the
          JPEG decoder is trying to skip over the APPn and failing if not
          all of the APPn has been received yet. The quoted error message is
          only one of several possible complaints, but they all stem from
          the same root.

          Photoshop is the most common source of JPEGs containing oversize
          APPn blocks. In particular, if you allow Photoshop 4 to save a
          thumbnail (preview) in a JPEG, the thumbnail plumps up Photoshop's
          private APPn marker to several K, which is usually enough to cause
          this problem.

          There are several possible workarounds:
             + 1. Get a newer JDK --- this problem is said to be fixed in
               1.1. (If you are putting images up on the Web, this isn't
               much of a solution, because you can't assume visitors to your
               site have an up-to-date Java installation.)

               2. When making JPEGs for Web use from Photoshop, make sure
               you have turned off the "save thumbnails" preference. (This
               is a good idea quite aside from bug workarounds, because the
               thumbnail is just a waste of download time as far as a Web
               browser is
               concerned.) You might still have a problem if you've got
               verbose comments or lots of paths being saved into the file,
               but 99% of the time, getting rid of the thumbnail will make
               Photoshop's APPn small enough to not trigger the Java bug.

               3. Use a tool such as 'jpegtran' (from the Independent JPEG
               Group) to strip out the Photoshop APPn entirely without any
               loss of image quality. Recommended answer for the compulsive
               byte-trimmer.

               4. (Last resort) Load and resave the image in a different
               image editor that won't insert any APPn or other overhead
               data. This implies a JPEG generational loss, so I don't
               recommend it if you are picky about image quality.

               Any large overhead marker will cause the same problem; 4K of
               comment text, say, in a COM marker. So Photoshop is not the
               only source of tickling this bug.

     8.11How can I convert between GIF and JPEG formats?
        o A. In a word: don't.

          There's hardly any overlap between the set of images that JPEG
          works well on and the set that GIF works well on. Sometimes, with
          enough care, you can get an acceptable conversion ... but most of
          the time gif<->jpeg conversion will just turn your image to mush.
          It's better to pick the right format in the first place.

          If you're determined to convert formats anyway, try the GBM
          (Generalized Bitmap Module). The package is GNU licensed, in C and
          is very good. Find it at
          http://www.interalpha.net/customer/nyangau/
          GBM does a good job converting to JPG, and 'lossiness' is
          adjustable to 0%. It also converts to/from about 20 other formats,
          does cropping, sizing, color mapping, gamma correction,
          halftoning, everything you could want. GBM source doesn't support
          jpeg directly, but utilizes jpg source from IJG called jpeg-6a and
          found at
          ftp://sun2.urz.uni-heidelberg.de/pub/simtel/graphics/jpegsr6a.zip

          For more info see the JPEG FAQ at
          http://www.faqs.org/faqs/jpeg-faq/

     8.12If you have an InputStream (rather than a file) that contains an
     Image, how can you display it?
        o A: Using this method, and some adroit shuffling.
             + Toolkit.getImage(URL url)

          Create a thread that pretends to be an http server. Make it listen
          to some port (8765 for example) for incoming requests. When the
          thread gets a request, it should simply whisk up the appropriate
          http headers and follow it by the InputStream. Thus the component
          that has the input stream and wants to do the getImage(url) can
          now invoke:

          Toolkit.getImage("localhost:8765/")

          The thread will act as a stream-to-url adapter, and send back the
          data It saves you from having to read 200K of JPEG data before you
          can begin drawing anything.

     8.13 How can I record sounds in Java?
        o A. The Java Media Framework will eventually support this, but it
          does not yet. JMF 1.0.1 only supports playback.

          JMF 1.0.1 is bundled with JDK 1.2, and available as a separate
          download for JDK 1.1 and Netscape Communicator 4 with Java 1.1. In
          the meantime, there is a package for Win95/NT available at
          http://www.scrawl.com/store/
          It supports 8, 16-bit, stereo, mono, 11025, 22050, 44100 Hz
          record/play, load/save .WAV files. You could also interface to
          native code for your platform.

     8.14 Does Java have any built-in support for displaying HTML?
        o A. JDK 1.1 supports rendering HTML using the unbundled JFC 1.1
          package known as Swing. The Swing package is bundled in JDK 1.2.
          It has an elementary (graphics, tables, text) HTML bean that is
          good enough for simple rendering (help files, email, etc). Other
          alternatives include:
             + JavaBrowser http://www.ii.uib.no/~alexey/jb/index.html Free
               source, free for use under GNU LGPL licence, HTML 2.0 (sort
               of).
             + ICE Browser - Java Bean Component
               http://www.icesoft.no/ICEBrowser/ Free binaries for use in
               free applications. Commercial licensing available including
               source - flat fee licence. Thin HTML client! Lightweight!
               HTML 3.2
             + HotJava HTML Component - Java Bean Component
               http://www.javasoft.com/products/hotjava/bean/index.html $195
               for private use binary licence. HTML 3.2
             + HTML browser (free source)
               http://barium.tn.tudelft.nl/people/gool/java/html/Html.html
             + Web Window Browser http://www.opencube.com/example_wwb.htm
               $139 - no sources.
             + jHelp ($20-650)
               http://w3.nai.net/~rvdi/jhelp/jhelp2/jhelp.html jHelp is a
               HTML browser component written in Java, HTML 2.0

     8.15 I loaded an Image file from a JPEG/GIF file using the
     Toolkit/Applet.createImage(URL/String) method, and (the height and
     width are -1 / it will not draw to the screen). What is wrong?
        o A. The behaviour of the AWT on creating images in this way is to
        o Do nothing at all.
        o When the image is first drawn using Component.drawImage(), or its
          size is requested, the image begins to load in a different Thread.
        o As the image loads, the ImageObserver specified in the
          drawImage()/getHeight() call is periodically notified of the
          loading status of the image, by calls to its imageUpdate() method.
        o In the case of Component.drawImage() call, the default behaviour
          of Component.imageUpdate() is to schedule *another* repaint() call
          when the image has fully loaded. This means that, in particular
          the following code will not work:

          class MyComponent extends Component {
            ...
            public void paint(Graphics g) {
              ImageFilter cropper=new CropImageFilter(0,0,16,16);
              Image cropped_image=createImage(new
              FilteredImageSource(image.getSource(),cropper));
              g.drawImage(image,10,400,this);        // this line works
              g.drawImage(cropped_image,400,15,this);    // this line doesn't -
              }
            }

          since the cropped_image will not be created in time to be painted,
          and when it is finally created, another call will be scheduled to
          paint, which will try to draw another one, etc.

          (Note also that creating objects like this in paint() methods is
          generally a very poor idea in Java, since they are called very
          frequently, and you will strongly offend the garbage collector.
          See 15.4 for examples of how to reuse objects.)

          In order to get round this problem, you may i) add all such Images
          to a MediaTracker, and call the waitForAll() method. ii) implement
          your own ImageObserver interface, and wait for the imageUpdate()
          method to be called with the ALLBITS/FRAMEBITS value. i) is
          easier, but ii) is recommended, since there are reports of
          MediaTracker not working in some environments. See also 8.12.

                                ------------------

9.SECURITY

   * 9.1What is a "trusted applet"?
        o A. JDK 1.1 introduced the notion of a "trusted applet" which is
          one that has been cryptographically-signed to guarantee its origin
          and make it tamper resistant. Trusted applets can be granted more
          system access privileges than untrusted applets.

          You preconfigure your browser with a list of whose X.509
          certificate you trust, and then applets arrive with X.509's
          attesting to their keys. It's easier than it sounds.

     9.2 What is the story withJava and viruses? What is the blackwidow
     virus?
        o A. Java was designed with security in mind. The security features
          make it very difficult, probably impossible, to attach a virus
          (self- copying code) to a Java applet. As far as is known, there
          has never been a Java virus.

          There has been mention of a "Java virus" called "BlackWidow" in
          the media (it was mentioned in Unigram in late 1996, and obliquely
          on the RISKS newsletter in February 1997). A request to the editor
          of Unigram for more information brought the answer that there was
          no more information, it was just a report of a rumor. As far as is
          known, this story exists *only* as rumors reported on by the
          press. There is no actual Java virus or blackwidow virus (there
          was a legitimate commercial product of that name, since renamed).
          If anyone has more concrete information about a virus that can
          attack a Java applet (again, this is thought to be impossible),
          please would they contact the FAQ maintainer with details.

     9.3 Why do I get the warning string at the bottom of popup
     windows"Unsigned Java Applet Window" in my applets?
        o A. This is a security feature, to make certain that users can
          always tell that a window asking for their password and credit
          card details (or whatever) is from an applet. There should be no
          way for an untrusted applet to work around this message. See also
          the answer to 4.1.3.

     9.4Where can I find crypto libraries for Java?
        o A. Cryptographic libraries are not part of the Java release
          because US Government policy classifies strong cryptography under
          the same rules as munitions. Its export is regulated under the
          International Traffic in Arms Regulations. Many people regard this
          as a Kafka-esque (and futile) attempt to stem the use of
          cryptography inside the US.

          A comprehensive and free crypto library (called Cryptix) is at
             + http://www.systemics.com/software

          Another crypto library for Java is at
             + http://www.acme.com/java/software/Package-Acme.Crypto.html

          Blowfish, CRC16, CRC32, DES, DES3, IDEA, RC4, ROT13 (can they
          really call that "crypto"?), and more.

          One commercial Java encryption source (from Ireland) is
             + http://www.baltimore.ie/jcrypto.htm

          A complete crypto API for Java (with HTML documentation) at:
             + http://www.geocities.com/SiliconValley/Heights/8298

          The library provides comprehensive and complete range of crypto
          library and functions covering DES, 3DES, IDEA, Blowfish ...and
          RSA, DH, DSA and PGP access to Java programmers. The crypto
          functions are based on the C cryptlib, by Peter Gutmann. It would
          be illegal to export this under current US government rules, but
          the author of the code is outside the US, and not subject to US
          export regulations. Download it today before it becomes illegal.

          Also, early access to Sun's Java Cryptography Extension (JCE) is
          available for JDK 1.1 at:
             + http://java.sun.com/products/jdk/1.1/jce

          (This may not be exported outside the USA and Canada).

          There's a Q&A archive at
             + http://jeeves.javasoft.com/hypermail/java-security-archive/index.html

          An actual port of PGP v2.6.3i to Java is at
          http://tassun.math.nsc.ru

     9.5How do I find out what these terms mean?
        o A. Read Bruce Schneier's excellent book "Applied Cryptography 2nd
          Ed." for more info on what these terms mean. Read David Kahn's
          excellent (if exhaustive) book "The Codebreakers" for more info on
          the history and background of encryption.

     9.6Where is Javasofts Security FAQ?
        o A. Javasoft's security FAQ can be found at
          http://java.sun.com/sfaq/index.html
          See also
          http://java.sun.com/products/jdk/1.1/docs/guide/security/

                                ------------------

10.Java IDIOMS

   * 10.1 How do I convert a String to an int?

   *
        o A. There are several ways. The most straightforward is:
             + int i = Integer.parseInt(myString);
               long l = Long.parseLong(myString)

          or
             + i = Integer.parseInt(<String>,<int radix>);

          Note: there are similar methods for Byte, Short, and Long. Don't
          forget to use myString.trim() to get rid of unwanted spaces before
          the conversion.
             + int i = Integer.valueOf(my_str).intValue();

          also works but involves the creation of an extra object. Note: use
          this for floating point values, as there are no parseDouble or
          parseFloat methods.

          float f = Float.valueOf(my_str).floatValue();
          double d = Double.valueOf(my_str).doubleValue();

     10.2How do I convert an int to a string?
        o A. String s = String.valueOf(i);
             + or
                  + String s = Integer.toString(i);

               or
                  + String s = Integer.toString(i, radix);

               or
                  + String s = "" + i; // briefer but may result in extra object allocation.

          Note: there are similar classes for Double, Float, Long, etc.

     10.3How do Iprint the hex value of an int?
        o A.You can print the hex equivalent of an int with:
             + int i = 0xf1;
               System.out.println("i is hex " + Integer.toHexString(i) );

     10.4 How can you send a function pointer as an argument?
        o A. Simple answer: use a "callback". Make the parameter an
          interface and pass an argument instance that implements that
          interface.
             + public interface CallShow { public void Show( ); }

               public class ShowOff implements CallShow {
               public void Show( ) { .... }

               public class ShowMe implements CallShow {
               public void Show( ) { .... }

               public class UseShow { CallShow callthis;
               UseShow( CallShow withthis ) { callthis = withthis; }
               void ReadyToShow( ) { callthis.Show( ); }

               // in some other class that uses all this stuff:
               UseShow use_1 = new UseShow( new ShowOff() );
               UseShow use_2 = new UseShow( new ShowMe() );

          and then the ReadyToShow() method on use_1 or use_2 will call the
          appropriate method, as if you had stored a pointer to the method.

     10.5How do I execute a command from Java?
        o A. Use Runtime.getRuntime().exec( myCommandString ) Where
          myCommandString is something like "/full/pathname/command"

     10.6How do I do I/O redirection in Java using exec() ?
        o A. This solution works on Unix platforms using either JDK 1.0.2,
          or JDK 1.1. The trick is to use an array of Strings for the
          command line:
             + String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};

          If you don't do this, and simply use a single string, the shell
          will see the -c and /bin/ls and ignore everything else after that.
          It only expects a single argument after the -c.

          import java.io.*;
          import java.util.*;

          class IoRedirect {
           public static void main(String Argv[]) {
           try {
           String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
           Process p = Runtime.getRuntime().exec(command);
           p.waitFor();
           System.out.println("return code: "+ p.exitValue());
           }
           catch (IOException e) {
           System.err.println("IO error: " + e);
           }
           catch (InterruptedException e1) {
           System.err.println("Exception: " + e1.getMessage());
           }
           }
          }

     10.7 So why can't I exec common DOS commands this way (as in 10.6)?
        o A. The reason is that many of the DOS commands are not individual
          programs, but merely "functions" of command.com. There is no
          DIR.EXE or COPY.EXE for example. Instead, one executes the command
          processor (shell) explicitly with a request to perform the builtin
          command, like so:
          Runtime.getRuntime().exec("command.com /c dir") for example. On
          NT, the command interpreter is "cmd.exe", so the statement would
          be
          Runtime.getRuntime().exec("cmd /c dir")

          This occurs on any OS where some commands are actually interpreted
          directly by the shell.

     10.8 OK,how do I read the output of a command?
        o A. As above (10.5, 10.6), adjusted like this:
             + BufferedReader pOut=
                new BufferedReader(
                new InputStreamReader(p.getInputStream()));
               try {
                String s = pOut.readLine();
                while (s != null) {
                System.out.println(s);
                s = pOut.readLine();
                }
               } catch (IOException e) { }

          Another possibility is to read chunks of whatever length as they
          come in:
          ...
             + p = r.exec(cmd);
               InputStream is = p.getInputStream();
               int len;
               byte buf[] = new byte[1000];
               try {
                while( (len = is.read(buf)) != -1 ) {
                  String str = new String(buf,0,0,len);
                  System.out.println( "Process out: " + str );
                }
               }
               catch( java.io.EOFException eof ) {

               ...

               }

               catch( java.io.IOException ioe ) {

               ...

               }

     10.9 How do Icompile code which has a cyclic dependency, i.e class
     pkg1.X contains a reference to class pkg2.Y ?
        o A. You throw both classes at the compiler at the same time.
             + javac pkg1/X.java pkg2/Y.java

     10.10 How can Istore the errors from the javac compiler in a DOS file?
     javac foo.java > errorfile seems not to work
        o A. javac write errors to stderr, so on NT use:
             + javac myfile.java 2> errors.dat

          On Win95, this doesn't work (as command.com is very poor
          software), so you have to use the javac error redirection
          mechanism:
             + javac -J-Djavac.pipe.output=true myfile.java > errors.txt

     10.11How can I pretty-print Java source?
        o A. Try http://www.CS.ORST.EDU/~speton/percolator/ (currently in
          Beta)
          Or http://www.parallax.co.uk/~rolf/download/jpp.pl
          Some Unix utilities work adequately:

          indent (fails with "//" comments though)
          cb (very few style choices though)

          alias printjava 'vgrind -lC++ -t -w \!* | lp'
          works pretty well too.

     10.12What is the point of creating the temporary reference to
     this.layoutMgr? This code is from the 1.0 AWT, and the programmer was
     probably pretty skilled.
        o public synchronized void layout() {
           LayoutManager layoutMgr = this.layoutMgr;
           if (layoutMgr != null) {
           layoutMgr.layoutContainer(this);
           }
          }

          A. The code makes a local copy of a global variable for one or
          both of two reasons.

          The first reason is that accessing local variables can be faster
          than accessing (non final) member variables It's good for loops or
          where there are many references in the source.

          The second reason is so that even if other threads update the
          global,
             + this.layoutMgr = someOtherLayoutMgr;

          this method will still have a pointer to the original layoutMgr.

          If the local variable were omitted, and another thread used the
          setLayout() method to change layoutMgr to null between when the
          layout method checked for null and when it invoked layoutMgr's
          layoutContainer method, a NullPointerException would result.

          Note that the synchronized keyword on the layout method doesn't
          help any, since setLayout (which could make such a dire change)
          isn't synchronized. Synchronized methods only lock out other
          synchronized methods on this object. (The unhelpful synchronized
          keyword on the layout method is gone in JDK 1.1.)

          There are two alternative solutions. One would be to make
          setLayout synchronized and make layoutMgr private, so that it
          can't be set other ways. This provides a stronger form of thread
          serialization, in that you would never be able to see an old
          layout manager being used after it had been replaced. However, it
          is slower. Another option that provides no increase in thread
          serialization over the original would be to catch the
          NullPointerException.

          Threads programming is hard! This idiom was probably put in place
          by someone who got really bitten by this in the past.

     10.13What is the difference between "a & b" and "a && b" ?
        o A. "a & b" takes two boolean operands, or two integer operands. It
          always evaluates both operands. For booleans, it ANDs both
          operands together producing a boolean result. For integer types,
          it bitwise ANDs both operands together, producing a result that is
          the promoted type of the operands (i.e. long, or int). "|" is the
          corresponding bitwise OR operation. "^" is the corresponding
          bitwise XOR operation.

          "a && b" is a "conditional AND" which only takes boolean operands.
          It always avoids evaluating its second operand if possible. If a
          is evaluated to false, the AND result must be "false" and the b
          operand is not evaluated. This is sometimes called
          "short-circuited" evaluation. "||" is the corresponding
          short-circuited OR operation.

          Possible mnemonic: The longer operators "&&" or "||" try to
          shorten themselves by not evaluating the second operator if they
          can.

     10.14If I create a thread, and then null out the reference to it, what
     happens to the thread? Does it get interrupted or what?
        o A. The code looks like this:
             + Thread t = new Thread( my_runnable_obj );
               t.start();
               ...
               t = null; // what happens to the thread?

          The answer is that *you* may no longer have a reference to the
          thread, but the JVM still does. Once a thread is started, and as
          long as it keeps running, it is a root object. Root objects are
          the starting points for "things in use" that the garbage collector
          uses.

     10.15 Howdo I calculate the number of days between two dates?
        o A. There is no API for this (there should be), but you can
          calculate it by hand, like this:
             + Calendar earlierDate = new GregorianCalendar();
               Calendar laterDate = new GregorianCalendar();

               earlierDate.set(1997, 1, 1, 0, 0, 0);    // Jan 01, 1997
               laterDate.set(1998, 1, 1, 0, 0, 0);      // Jan 01, 1998

               // the first getTime() returns a Date, the second takes
               // that Date object and returns millesecs since 1/1/70.
               // The API has misleading and horrible naming here, sorry.
               long duration =    laterDate.getTime().getTime()
                                - earlierDate.getTime().getTime();

               long nDays = duration / (24 * 60 * 60 * 1000);
               System.out.println("difference in days: " + nDays);

     10.16 Howcan a Java program determine the level of JDK support given by
     the underlying VM? I.e. is it running in a JDK 1.0.2 or 1.1 VM?
        o A. Look at the java.version system property with:
             + String ver = System.getProperty("java.version");

          There isn't a lot of standardization on the string contents
          however. Another possibility is to try { ... } a library method
          that didn't exist in JDK 1.0.2, such as SomeComponent.setSize(),
          and catch the exception. If you got an exception, it's a 1.0
          implementation. In 1.0 setSize() was known as resize().

                                ------------------

11.FOR C and C++ AFFICIONADOS

   * 11.1How do I translate C/C++ into Java or vice-versa?
        o A. In general it is not simple to translate C/C++ into Java, as
          Java lacks the arbitrary pointer arithmetic of those languages. If
          your C code does not use pointer arithmetic, automatic translation
          gets a lot simpler. Try these URLs:
             + http://www.ist.co.uk (search for X-Designer 4.6: Java
               edition).
               http://members.aol.com/laffra/c2j.html
               http://www.ilog.com/

          Going the other way there are currently three freely-available
          tools to translate Java into C. It seems that these have been done
          for hacking value, rather than practical purposes.
             + j2c from Japan,
                  + http://www.webcity.co.jp/info/andoh/java/j2c.html
             + Toba from the Sumatra research project, translates 1.0.2
               .class files into .c source code
                  + http://www.cs.arizona.edu/sumatra/toba
             + JCC from Nik Shaylor.
                  + http://www.digiserve.com/nshaylor/jcc.html

          None of them support the AWT yet, and both j2c and JCC have
          additional restrictions.

          There's a product to convert Visual Basic to Java. Details at
             + http://www.blackdirt.com and http://www.javadelphi.com (also
               a Delphi-to-Java source converter) and
               http://www.tvobjects.com

          This program dumps info about the class file:
             + http://www.professionals.com/~cmcmanis/java/dump/index.html

          Chuck McManis was one of Sun's original Java implementors.

     11.2How are finalizers different from C++ destructors?
        o A. Java objects are not explicitly deleted and do not have
          destructors. Instead they are implicitly garbage collected when
          the JVM realises your program can no longer access them. Typically
          this technology is _not_ based on reference counting and _will_
          cope with circular references.

          Every object has a routine called finalize() which will be called
          before the object is collected. This is Java's nearest equivalent
          to C++'s destructor. However, it is not a good idea to rely on
          finalization for the timely freeing of resources.

          This is because garbage collection and hence finalization may be
          arbitrarily delayed, and may never happen at all if the program
          terminates before it runs out of memory. You should instead
          provide your objects with methods similar to Graphics.dispose() to
          free resources, and call the
          dispose() method explicitly when you have finished using them -
          typically within the "finally" clause of a "try/catch" block. You
          may then call your dispose() method from within your finalize()
          method as a last-ditch attempt to free the resource if someone
          forgets.

          Alas, all this means the C++ idiom of "object construction is
          resource aquisition" does not translate well to Java. However,
          note that 90% of destructors in C++ are there to free memory, and
          the GC means you don't need to do that in Java. As well as fixing
          an important source of bugs, the GC is essential to Java's
          security model; without it you could forge object references by
          preserving the reference after the object has been deleted.

          If your program appears to be crashing due to running out of some
          system resource (like File, Window or Graphics handles), it
          probably because the system is running out of handles before it
          has run out of memory. Check that you have called the dispose()
          method (or equivalent) on every object that uses system resources.
          You can help the GC a little bit more by explicitly
          NULLing out references that you've finished with.

     11.3What's the Java equivalent of sizeof()?
        o A: There isn't one. sizeof() in C and C++ is used in three main
          places:
             + 1) To check on the size of a primitive type. In Java, the
               sizes of primitive types are fixed in the language
               specification (a short is _always_ 16 bits; an int is
               _always_ 32 bits, etc), so this is no longer necessary.

               2) In memory allocation (i.e. malloc (32 * (sizeof(int));) In
               Java you always allocate a specific type of object, rather
               than a block of raw memory that you will fill as you like.
               The system always knows the size of the kind of objects you
               are allocating. So sizeof is not needed.

               3) in pointer arithmetic (i.e. p += sizeof (int)) Pointer
               arithmetic of this type is not allowed in Java, so this isn't
               necessary, either.

          For all these reasons, there is no need for a Java sizeof()
          operator. Some people have suggested that you can find out the
          size of an object by having the object serialize itself to a
          ByteArrayOutputStream, and looking at the bytearray.length.

          That won't work because a lot of additional data is written when
          an object is serialized. The additional data includes a
          description of the class, any objects referenced by the serialized
          object, null references (written as a single byte), etc. If you
          write another instance of the same class, the amount of data
          written can differ dramatically. And if you serialize the same
          object again, it isn't written at all -- even if its data fields
          have changed! Instead, a one byte token and a four byte "sequence
          number" that refer to the first writing are output. Using Object
          Serialization to determine the size of an object does not (except
          by coincidence) give the right answer.

     11.4Does Java have the equivalent of "const" arguments in C and C++?
        o A. Java 1.1 adds the ability to use the "final" keyword to make
          arguments constant. When used to qualify a reference type,
          however, this keyword indicates that the reference is constant,
          not that the object or array referred to is constant. For example,
          the following Java code:
             + void foo(final MyClass c, final int a[]) {
                c.field = 7; // allowed
                a[0] = 7; // allowed
                c = new MyClass(); // final means this is NOT allowed
                a = new int[13]; // final means this is NOT allowed
               }

          is roughly equivalent to the following C/C++ code:
             + void foo(MyClass * const c, int * const a) {
                c->field = 7; // allowed
                a[0] = 7; // allowed
                c = new MyClass(); // const means this is NOT allowed
                a = new int[13]; // const means this is NOT allowed
               }

          Java does not have any equivalent to the following C/C++ function
          declarations:
             + void foo(const MyClass *c); // a pointer to a const class
               void foo(const int *a); // a pointer to a const int
               void foo(const int a[]); // a pointer to an array of const ints

     11.5Are there any hacks around this?
        o A. Certainly! There are always hacks around stuff. One way of
          enforcing constant values is to have two interfaces, a constant
          one and a non-constant one, e.g.
             + public interface ConstFoo {
               int getValue();
               }

               public interface Foo extends ConstFoo {
               int getValue();
               void setValue(int i);
               }

          Then when you want to receive a parameter that cannot be modified
          you have:
             + void noChange(ConstFoo foo);

          For a parameter that can be modified
             + void change(Foo foo);

     11.6How can I write C/C++ style assertions in Java?
        o A. The two classes shown below provide an assertion facility in
          Java. Set Assert.enabled to true to enable the assertions, and to
          false to disable assertions in production code. The
          AssertionException is not meant to be caught--instead, let it
          print a trace. Since the exception is not meant to be caught, we
          just extend Error instead of RuntimeException. As with
          RuntimeException, a method does not need to declare that it throws
          Error. In addition programmers are less likely to write
          "catch(Error) ..." than "catch(RuntimeException)".

          With a good optimizing compiler there will be no run time overhead
          for many uses of these assertions when Assert.enabled is set to
          false. However, if the condition in the assertion may have side
          effects, the condition code cannot be optimized away. For example,
          in the assertion
             + Assert.assert(size() <= maxSize, "Maximum size exceeded");

          the call to size() cannot be optimized away unless the compiler
          can see that the call has no side effects. C and C++ use the
          preprocessor to guarantee that assertions will never cause
          overhead in production code. Without a preprocessor, it seems the
          best we can do in Java is to write
             + Assert.assert(Assert.enabled && size() <= maxSize, "Too big");

          In this case, when Assert.enabled is false, the method call can
          always be optimized away, even if it has side effects. However, an
          opposing view holds that even this might not work in the face of
          java's late binding. If the Assert class is in a package, and if
          the computer the applet/application is running on has a different
          version with Assert.enabled being true, then it's possible that
          assertions *should* be enabled in that case. Therefore, the
          compiler can't assume that enabled is *false* at runtime just
          because it *is* false in the compilation environment. This may be
          thought perverse, but it could happen.
          If a language lawyer wants to weigh in on this theory, please go
          ahead.
             + public class AssertionException extends Error {
                public AssertionException(String s) {
                super(s);
                }
               }

               public final class Assert {
                public static final boolean enabled = true;
                public static final void assert(boolean b, String s) {
                if (enabled && !b)
                throw new AssertionException(s);
                }
               }

     11.7How do I do stuff like scanf and sscanf in C/C++? And how do I do
     stuff like sprintf, e.g.
        o float x = 12345.6789;
          printf("%6.3f/n", x);

          A. You can break a string like "5 loaves 2 fishes" into its parts
          by using java.util.StringTokenizer. This is the Java equivalent of
          sscanf().

          StreamTokenizer does a similar thing on a file or any stream (i.e,
          what scanf() and fscanf() do in C).

          To do formatted character output, create a format string, and then
          use that to format your binary value, e.g.
             + import java.text.*;

               float fi = 1234.56789F;
               DecimalFormat df2 = new DecimalFormat( "0.000" );
               System.out.println( df2.format(fi) );

          gives:
             + 1234.567

          There are lots of different characters you can feed to the
          DecimalFormat constructor, not just "0". See
          $JAVAHOME/src/java/DecimalFormat.java source for details.

     11.8 What is the Java equivalent of C++ friend"?
        o A: The keyword "friend" in C++ is a hack to allow a piece of code
          to access the private member declarations of another class. In
          Java, you would do this by labelling, not the friend, but the
          private members. Instead of making them private, make them
          protected. Classes in the same package have automatic "friendship"
          in that they can access each other's protected fields.

     11.9Does anything like the C++ Standard Template Library exist for Java
     ?
        o A: Yes, only it's better and simpler to use in Java. It's called
          the Java Generic Library. This library (JGL) is freely
          downloadable from http://www.objectspace.com/

          It includes about a dozen nice data structures (including sets and
          bags) and algorithms like unions, searching, and sorting.

          [Some Java vendors are bundling it with their next release]

     11.10 to be continued
        o A: to be continued

                             -------------------

12.FURTHER RESOURCES

   * 12.1 Useful URLS
        o Site with the latest copy of this FAQ: http://www.afu.com/

          Other Java resources:
          The Java "Hall" of Fame: http://www.apl.jhu.edu/~hall/java/
          good glossary: http://oberon.ark.com/~roedy
          conversions: http://oberon.ark.com/~roedy/convert.html
          good JDBC FAQ: now disappeared from original site, if anyone knows
          whereabouts, please send details.
          general Java: http://java.miningco.com/

          Tutorial:
          http://java.sun.com:80/nav/read/Tutorial/index.html
          http://www.phrantic.com/scoop/onjava.html

          Java Book lists:
          http://www.netcharts.com/majug/reviews.html

          Javasoft site: http://java.sun.com

          General sharing and exchange of Java info:
          http://www.gamelan.com
          http://www.JavaShareware.com

     12.2Newsgroups
        o These are the Java newsgroups since the reorganization that I
          arranged in April 1997

          comp.lang.java.help simple programming and setup questions
          comp.lang.java.announce (moderated) announcements
          comp.lang.java.advocacy for arguments: no it isn't, yes it is
          comp.lang.java.programmer programming in Java
          comp.lang.java.security security issues
          comp.lang.java.machine JVM and native interfaces
          comp.lang.java.databases JDBC,ODBC, java access to DBs.
          comp.lang.java.softwaretools IDES, editors, compilers, tools, etc
          comp.lang.java.gui AWT, JFC, AFC, WFC, etc etc
          comp.lang.java.beans Software components in Java
          comp.lang.java.corba (newsgroup added Dec 3 1997) interaction
          between Java and CORBA.

          Please make an effort to post only to the single most appropriate
          group.

          As with the other language groups on Usenet (comp.lang.c,
          comp.lang.c++, etc) questions about products from specific vendors
          that only work on one specific platform are best posted to other
          newsgroups. For example, questions about ActiveX belong in
          comp.os.ms-windows.programmer.ole, not the Java groups. For
          questions about J/Direct try the group
          microsoft.public.java.visualj++ or microsoft.public.java.sdk.
          These are available from Microsoft's news server
          msnews.microsoft.com. Many IPSs don't provide direct access to
          these groups (or those of other companies) but you can access them
          by setting the NNTPSERVER environment variable to point to the
          newserver.

     12.3Are there any commercial/shareware/free Java libraries?
        o A. Take a look at the Java Collection Framework, a group of
          classes that are part of Java 1.2. These classes implement
          general-purpose data structures, and they will become widely used.

          The documentation for JDK 1.2 explains that the Collection
          Framework defines three kinds of thing:
             + Standard interfaces representing data structures of various
               kinds for you to implement. Since these are interfaces, you
               can use them in your code before you have implemented them.
             + Partial implementations of those interfaces, saving you some
               work.
             + Complete implementations, ready to use for data in your
               programs.

          The standard interfaces are Collection, Set, List and Map, plus
          the more specialised SortedSet and SortedMap. Lists have duplicate
          elements whereas Sets do not. Finer distinctions such as
          immutability are defined in the implementor classes, enforced by
          throwing runtime exceptions. See the JDK1.2 documentation for a
          full discussion. Also see http://byrden.com/java/Tree/index.shtml
          for a description of extending the collection framework, and a
          freeware class implementing trees.

          For more about sorting prior to JDK 1.2, look at the class
          SortDemo in the demo directory of the JDK. Alternatively, use one
          of the several classic sorts available from Roedy Green. They are
          supplied free with heavily commented Java source code.

          See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary
          at http://oberon.ark.com/~roedy/index.html .

          Also, try the Java Generic Library. This library (JGL) is freely
          downloadable from http://www.objectspace.com/

          Also Visual Engineering has JChart at: http://www.ve.com. No
          licensing fees.

          Visual Numerics has its Java Numeric Library available for
          download at http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They
          offer the JNL as a proposed standard library for numerical
          functions missing from Java.

     12.4 Why doesn't somebody write a shell in Java? Then they could use it
     on all platforms!
        o A. Somebody has done just that. Look at http://www.jsh.net/

     12.5 Are there any URLs for other libraries?
        o A. Indeed, there are. The Java3D Repository
          http://java3d.sdsc.edu/

     12.6Are there any URLs for regular expression handlers in Java?
        o A. http://www.oroinc.com/products/OROMatcher.html This comes from
          ORO Inc, is free, and handles Perl5 style exprs.

          And don't forget to check out Lava -- a set of Java classes
          designed to support programmers who develop console-mode
          applications and/or C programmers who are converting to Java. The
          first release of Lava has printf and other text formatting,
          encryption, parsing and miscellaneous I/O. Lava can be downloaded
          from http://www.newbie.net/sharky/lava/

                             -------------------

13. MOST COMMON JAVA NOVICE PROBLEMS

   * 13.1 I can't seem to get my classpath environment variable set
     correctly.
        o A. Classpath was a hack from the early releases of Java. The
          CLASSPATH tells the Java Virtual Machine and other Java
          applications where to find the class libraries, such as the
          runtime library classes.zip file.

          Don't set your CLASSPATH at all when starting out. If you have it
          set from a previous installation of JDK 1.0.2, unset it. The
          system knows where to look for libraries and your Java class
          files. By default, it searches your current directory. If you are
          creating your own packages, you might want to set CLASSPATH so it
          looks in the right places to find them.

     13.2 How do I do keyboard (interactive) I/O in Java?
        o A. Interactive I/O in Java is very poorly supported. Programmers
          must piece together several library classes in non-obvious ways to
          get the required functionality. See the answer to question 6.1.

     13.3 How do I do file I/O in an applet?
        o A. In general, an applet can read files on the server, but not
          write them, and has no access to the client. This is for reasons
          of security. It would be very unsafe to let any old applet that
          you downloaded from an unknown origin on the Internet read/write
          your files. It would be as unwise as allowing this kind of access
          to an ActiveX control (which is one reason ActiveX is dead on the
          Internet). There are several different ways to relax the rules.
          See the answer to question 6.8.

     13.4 How do I do I/O to the serial port on my computer?
        o A. Java 1.0 and 1.1 do not have a serial port API. There are
          several commercially-available libraries that supply the needed
          functionality. JDK 1.2 introduces access to the serial and
          parallel ports as an extension (optional extra) library. See also
          the answer to question 6.3.

     13.5 How do I do formatted I/O like printf and scanf in C/C++?
        o A. The java.text package introduced with Java 1.1 supports
          formatted I/O. See also the answer to questions 6.11, 6.12, and
          12.3.

     13.6 I have spent more debugging time finding case (upper vs lower)
     typos than everything else put together and squared!
        o A. Do not forget that your remark must be phrased in the form of a
          question to win on FAQ Jeopardy. In any event, it is worth
          reminding those new to Java that letter case really matters in
          Java, and that the names of public classes should exactly match
          (including case) the names of the files they live in. See also the
          answer to question 4.1.2

     13.7 Why do I get a compiler error with this statement: "double y =
     sin(90);"?
        o A. You need to write it this way:

          double cvtDegToRad = Math.PI/180;
          double x = 90*cvtDegToRad;
          double y = Math.sin(x);

          You need to use the "Math" classname, e.g. Math.sin instead of
          plain sin, because you have to say what class or object these
          methods belong to. These are static methods of the Math class, so
          you give the name of the class in invoking them.
          Also recall that the Math package works in radians, not degrees.
          360 degrees = 2 pi radians. So use a conversion factor as shown if
          you are working with degrees.

     13.8 Why do I get this compiler error: "Can't make static reference to
     method..."?
        o A. Your code probably looks something like this:

          class myclass {
              public static void main(String args[]) {
                myMethod();
              }

              public void myMethod() { //some code
              }
          }

          The issue is this: a static method means it belongs to the class,
          not each individual object. If you leave the static keyword off
          (the usual case) as is done here with the method "myMethod()", it
          means that method can only be invoked on an object. But your call
          from main() has not told myMethod() which object it is to be
          invoked on. Inside a non-static method, you don't have to provide
          this information, as it assumes you mean the same object on which
          it was invoked. But when calling from a static method, you must
          provide the information, and you haven't - hence the error
          message.

          A common fix is to instantiate a member of the class, on which to
          invoke myMethod(), like this:

              public static void main(String args[]) {
                  myclass m = new myclass();
                  m.myMethod();
              }

          This problem is especially common when you are writing code that
          you want to run as an applet and as an application. Naturally, you
          call init() and start() from main. What you really need to do is:

          public static void main(String[] args) {
              Applet ma = new myApplet();
              ma.init();
              ma.start();
          }

     13.9 How do I close a Java window by using the icon in the upper right
     hand corner of a window?
        o A. Create an event handler class to extend WindowAdapter. Then
          override WindowAdapter's windowClosing() to do the actions you
          want when a window's "close" action is clicked. Then add that to
          the listeners for that window.

          import java.awt.*;
          import java.awt.event.*;
          public class MyFrame extends Frame {
              public MyFrame(String s) {super(s);}

              public class WL extends WindowAdapter {
                  public void windowClosing(WindowEvent e) {System.exit(0);}
              }

             // do your other Frame stuff

          }

          Somewhere in your initialization code, put:

                  f1.addWindowListener( f1. new WL()  );

          This last syntax is not commonly known to many people yet, it's
          another whacky artifact of inner classes.

          Alternatively, combining the inner class and setting the handler
          in one go, you could do this:

                  MyFrame f1 = new f("wave");

                  f1.addWindowListener( new WindowAdapter() {
                     public void windowClosing(WindowEvent e) {
                        // and/or setVisible(false) and/or dispose()
                        System.exit(0); }
                  });

          See also the answer to Q.4.0.19, 4.0.30, and 15.7.

     13.10 Why is b+=100; OK, but b = b+100; fails to compile?
        o A. You have code like this

                  byte b = 0;
           Incompatible type for =. Explicit cast needed to convert int to byte.
                  b = b + 100;    // compiler error message
                    ^
                  b += 100;       // works OK

          The reason is "promotion". Arithmetic expressions are promoted to
          the type of the longest, floatiest operand in them, or at least to
          int. The first statement involves the assignment of an expression.
          The expression is promoted to 32 bits, and must be cast back down
          to 8 bits, like this "b = (byte) (b+100);". The second is an
          operator assignment, and the cast back to byte takes place
          automatically. The Java Specification says:
             + "A compound assignment expression of the form E1 op= E2 is
               equivalent to E1 = (typecast)((E1) op (E2)), where "typecast"
               is the type of E1, except that E1 is evaluated only once"
               [JLS 15.25.2]

          The compile-time narrowing of constants means that code such as:

          byte theAnswer = 42;

          is allowed, with no cast necessary. [JLS 5.2]

     13.11 How do I add two Float objects together?
        o A. You want to write code like this

          Float One;
          Float Two;
          Float Hard = One + Two;

          but the compiler does not allow it.

          Java has two separate ways of representing a 32 bit floating point
          number, Float and float. Float is a class, that whose sole purpose
          is to "wrap" a floating point number so it can be treated as an
          object. The class does not support floating point arithmetic,
          because the performance would be too slow. float is a primitive
          type (like int) that is used for floating point arithmetic.

          You choose one or the other depending on your predominant use. If
          all you need of your floating point numbers is arithmetic, declare
          them to be "float". If you need to use them as objects, for
          example to place them in a Vector, declare them as "Float".

          If you need both, tough. You have to declare them one way and
          convert whenever you need the capabilities of the other. Your
          specific code can be written as:

             Float One = new Float(1.0);
             Float Two = new Float(2.0);
             Float Hard = new Float(One.floatValue() + Two.floatValue());

          See also 3.8, 5.1 and 10.1.

     13.12 How can I put all my classes and resources into one file and have
     java run it?
        o A. Use a JAR file. Put all the files in a JAR, then use the jre to
          run the app, like:

             jre -cp app.jar Main

          assuming the jar is called app.jar and it has a class called Main
          that has the main() method for the application.

     See also "The 10 Most Common Java Programming Mistakes":
     http://webreview.com/wr/pub/97/12/19/feature/sidebar.html

                             -------------------

14. FOR WINDOWS USERS

   * 14.1 Is there a Java implementation for Windows 3.1?
        o A. Yes. See question 1.6

     14.2 I'm using Win95, and my DOS window won't accept filenames longer
     than 8.3.
        o A. Assuming you're running the win95 command.com, then you've
          changed the MS-DOS Prompt options under Properties menu item. In
          the Properties dialog, Program->Advanced gets you a dialog. Here
          make sure the "Prevent MS-DOS-based programs from detecting
          Windows" checkbox is UNCHECKED.

          If the option is checked you get exactly the kind of behavior
          you're seeing. The option is unchecked by default, so it must have
          been selected at some time in the past. Change it back to
          unchecked.

     14.3 I'm using notepad to edit my files, and how can I save them with
     the extension ".java"? Also, some source files have all the characters
     on one line. Why is that?
        o A. First answer: put the entire filename in quotes in the save
          dialog. Second answer: notepad expects to see a "carriage
          return/line feed" pair at the end of each line, rather than just
          the "newline" (line-feed) commonly used on Unix. Use this program
          to expand all newlines,

          import java.io.*;
          class crlf {
              public static void main(String s[]) throws IOException {
                  int c;
                  while ( (c=System.in.read())!= -1) {
                       if (c=='\n') System.out.write('\r');
                       System.out.write(c);
                  }
              }
          }

          compile with "javac crlf.java" and run with
          java crlf outfile.txt
          or just use wordpad instead of notepad. Wordpad is under
          Start->Accessories->WordPad

     14.4 What's J++6?
        o A. It is an abbreviation for "Microsoft J++ version 6". Microsoft
          launched J++ 1.0 in 1996 and it was compatible with Java 1.0. When
          Java 1.1 came out, Microsoft decided not to support key parts of
          it, such as JNI, JFC, RMI, and Java Beans. Nevertheless, Microsoft
          moved the version number of J++ to 1.1, which confused people who
          expected it to support JDK 1.1

          Microsoft has continued its attempt to fragment and undermine
          support for Java with J++6. First, it bumped the version number
          up, skipping over releases 1.2 , 3, 4, and 5. This aligned the
          number with other MS products, but falsely conveys the impression
          that J++6 is an equally stable and mature product. (A similar
          thing ocurred with NT, which was introduced at version 3.1, and
          with Microsoft's CIFS - Common Internet Filesystem, which is
          neither common nor an internet standard. It was actually renamed
          to CIFS as part of Microsoft's wishful thinking to make this NT
          remote file protocol be adopted all over the web). Then Microsoft
          introduced two new keywords ("delegate" and "multicast"), as well
          as the complexity of conditional compilation and conditional
          methods.

          Microsoft's SDK has been moved further and further from standard
          Java with each successive release. J++ combined with the visual
          editor generates calls to the Windows-only WFC library. Anyone
          writing Java code that uses VJ++6 may be needlessly restricting
          their programs to only ever run on Microsoft platforms. Microsoft
          has been cut off from future Java technology, so they do not have
          JNI, JFC, RMI, Java Beans, IIOP/CORBA hooks, Swing, PLAF &
          Accessibility, the Security API, Drag N Drop, among other
          features. If you like Java, you should encourage Microsoft to be
          compatible by not using their divergent tools. Use one of the
          other Integrated Development Environments instead. See also Q1.14.

          You may see some programmers refer to J--. By this they mean
          Microsoft's incompatible J++ SDK.

     14.5 How do I fix the message about "out of environment variable
     space"?
        o A. This occurs under Windows when you have long CLASSPATH names.
          You need to increase the enviroment space. Put this in your
          config.sys:

            shell=command /e:4096

                             -------------------

15. Java GOTCHA'S

   * 15.1 What is a "GOTCHA" (for non-English native speakers)?
        o A. It is an abbreviation of "Got you!" It is the triumphant
          exclamation that a bug or programming idiom makes as it traps the
          unwary programmer. This section details some of the popular
          "gotcha's" of Java.

     15.2 I changed a final value, and recompiled just the file that it was
     in, and the entire rest of the program used the old value!
        o A. This is the "expected" behavior. If you have this in one file

          class Flags { final static boolean debug = true; }

          and you change it to, and recompile just this file:

          class Flags { final static boolean debug = false; }

          Then the rest of your Java .class files will still see it as
          "true".

          When you declare a "static final int" (or any other primitive),
          the compiler turns that into a compile time constant whose value
          can be substituted wherever it is used in your program. If you
          update the value in the source file, you'll need to recompile
          every class that uses it.

          See Java Language Specification, section 13.4.8 "final Fields and
          Constants": "We call a field that is static, final, and
          initialized with a compile-time constant expression a primitive
          constant. If a field is a primitive constant, then deleting the
          keyword final or changing its value will not break compatibility
          with pre-existing binaries by causing them not to run, but they
          will not see any new value for the constant unless they are
          recompiled."

     15.3 What is the "substring trap"?
        o A. The "substring trap" is the name for a mistake that is all too
          easy to make when using the substring() method of class String.
          The method signature is:

          public String substring(int beginIndex, int endIndex)

          The name "endIndex" suggests that is the index where the Substring
          ends.

          But in fact, the substring extends only to the character at
          position (endIndex-1)! It seems to be done this way so that
          s.substring(0,s.length()) is equal to s. If so, the name of the
          second parameter should be something like endInxLessOne or Length.
          But not the confusing and misleading endIndex. Beware of the
          substring trap.

     15.4 Why does getGraphics() return null on my offscreen image?
        o A. The following code

          class MyFrame extends Frame {
            MyFrame() {
              Image offscreen = createImage(100,100);
              Graphics offg = offscreen.getGraphics();
              }
            ...
            }

          will usually not work, since the peer will not exist at this time.
          Without the peer for the Frame, you cannot succeed in creating
          offscreen Images. (There's no problem creating Produced Images
          without a peer. Trying to draw them, of course, is another
          matter).

          One "standard" form of offscreen code looks like this: (note the
          reuse of the Graphics and Image objects for as long as possible)

          class Gumble extends java.awt.Something {
            private Image offi;
            private Graphics offg;

            public void update(Graphics g) {
              if (g == null) return; // Paranoia
              Dimension size = size();
              if (    offi == null
                   || offi.getWidth()!=size.width
                   || offi.getHeight()!=size.height  ) {
                if (offg!=null) offg.dispose();
                offi = createImage(size.width, size.height);
                offg = offi.getGraphics();
                // Regenerate offi here...
                }
              // If you use getClipBounds() here,
              // check that for being null, too!
              // several implementations have been known to pass them....
              g.drawImage(offi);
              }

            public void paint(Graphics g) {
              update(g);
              }
            }

          See also 8.7;

     15.5 The dynamic type of a method argument doesn't seem to be used to
     choose an overriden method at runtime.
        o A.Correct. Generally, if you invoke a method on an object, the
          object's actual runtime type, not the type of the reference that
          you used to reference it, determines which method is invoked. This
          is regular polymorphism.

          It's not the same for object parameters: the compiler decides at
          compile time, depending on the types of the parameter expressions,
          which method signature to use, and this is "hardwired" into the
          bytecode. The compiler does not look at the object argument at
          runtime and say "ah, this is a derived type, so I will choose the
          method that takes the derived type as an argument."

          This is best seen in a code example:

          class Base { }
          class Derived extends Base { }

          public class foo {

             public static void method(Base b) {
               System.out.println("In the base method...");
             }

             public static void method(Derived d) {
               System.out.println("In the derived method...");
             }

             public static void test(Base b) {
               if (b instanceof Derived)
                 System.out.print("Derived:  ");
               else
                 System.out.print("Base:     ");

               method(b);   // which method?  method(base) or method(derived)?
             }

             public static void main(String args[]) {
               Base b = new Base();
               Derived d = new Derived();

               System.out.println("test calls.");
               test(b);
               test(d);
             }
          }

          Running the program gives an output of

          test calls.
          Base:     In the base method...
          Derived:  In the base method...

     15.6 Why did I lose my updates when I changed data fields in a graph
     that I was serializing?
        o A. Quoting from the object serialization specification at:
          http://www.javasoft.com/products/jdk/1.1/docs/guide/serialization/spec/serial-arch.doc.html#4176
             + The writeObject method serializes the specified object and
               traverses its references to other objects in the object graph
               recursively to create a complete serialized representation of
               the graph.

               Within a stream, the first reference to any object results in
               the object being serialized or externalized and the
               assignment of a handle for that object. Subsequent references
               to that object are encoded as the handle.

          In other words, changing an object and then writing it again does
          not really write it twice. Instead it just writes a reference back
          to the first occurrence, losing any fields that have changed in
          the meantime.

          There are three ways around this: (1) (inefficient) Reset (or
          close and reopen) the stream, and start again by writing the new
          value of the object. This is drastic -- you are throwing away all
          the serialization that you have already done.
          (2) (kludgey) Create a new object and write that.
          (3) (could be a lot of work) Write your own protocol for object
          serialization. Have something like a data stream where the
          contents of an object are marked by special identifiers. Each
          "end" of the stream can decide whether it will use a new object
          each time or reuse an existing object.

     15.7 When I click on a Java window frame, it doesn't close!
        o A. You need to add the code to listen for a window closing event,
          and take the appropriate action (hide the window, exit the program
          if the top level frame, etc).

          The window closing event handler is simple:

          Frame mf = new Frame("binky");
          mf.addWindowListener( new WindowAdapter() {
              public void windowClosing(WindowEvent we) {
                  System.exit(0); // or setVisible(false); etc.
              } });

          This really should be the default behavior of an AWT Frame. So
          you'll be delighted to hear that JavaSoft has "made it so" for the
          JFrame Swing component. That leads to a slightly different
          problem. See 4.3.3. See also 13.9.

     15.8 What's the deal with "super"? How far back into parent classes can
     I go?
        o A. The keyword "super" is best thought of a compiler metaname that
          refers only to the immediate superclass. The call "super()"
          invokes a constructor in the superclass, and the reference
          "super.someField" lets you to other fields in the immediate
          superclass.

          There is no way to "chain" several together, and reach back higher
          into the parent class hierarchy. You can reference your immediate
          parent class and that's it. If you have

          class Parent {        }

          class Child extends Parent {       }

          then, in Child "super.someParentMethod();" means "invokespecial
          X.someXMethod()" in the JVM, not "invokevirtual".

     15.9 When I change some component (e.g. a new label on a button) I
     don't see the change on the screen immediately even if I repaint().
        o A. You need to add these calls, instead of the repaint():

          invalidate();
          validate();

          They cause the component hierarchy to be marked as needing to be
          laid out again, and the validate causes that to be done. It may be
          expensive, but is always the most reliable way of getting the
          peers to recalculate size and to do what is needed to bring the
          display up to date.

     15.10 Why aren't popup menus working cross-platform for me?
        o A. On Windows, the pop-up trigger is a mouse release (except in
          certain programs like Netscape Communicator). On Unix, the pop-up
          trigger is a mouse press.

          Therefore you need to ask the question isPopupTrigger() in both
          the mousePressed() and mouseReleased() methods when implementing
          the MouseListener interface. Alternatively override Component's
          processMouseEvent as a central place for handling mouse input.

     15.11 Why aren't newlines working cross-platform for me?
        o A. Code like this:

          if (c == '\n')
               fin = true;

          is not cross-platform. On Unix the line terminator is "\n", on
          Windows, it is frequently "\r\n", on the Mac it is "\r".

          The call System.getProperty("line.separator") will return a string
          containing the platform-specific line separator character(s), and
          you then need to compare it according to how your data is
          formatted (e.g. compare 2 characters or one). There is also a
          property for the separator character in file pathnames, and other
          values too.

     15.12 Why did my polygon come out the wrong shape?
        o A. This question and answer comes directly off
          comp.lang.java.programmer, and deserves to be immortalized for
          posterity.
          When I use fillPolygon with the following points I get two
          inverted triangles instead of a rectangle. Why?

          int xPoints[] = {71, 78, 71, 78};
          int yPoints[] = {147, 147, 130, 130};
          g.fillPolygon(xPoints, ypoints, xPoints.length);

          Developer Felix Pahl supplied the answer in limerick form:
             + A developer (for details bored her)
               didn't follow the polygon's border
               so instead of right angles
               she got two triangles
               'cause the endpoints were in the wrong order!

          You must put the points in the order you would encounter them in
          if you went round the polygon's border. The filling algorithm is
          doing the right thing! Try drawing the points on paper to see:

          71,130   78,130
            O--------O
            |        |
            |        |
            |        |
            o--------o
          71,147   78,147

          Under JDK1.1, the two endpoints are connected automatically and
          you would order the array elements as:

          int xPoints[] = { 71,  78,  78,  71};
          int yPoints[] = {130, 130, 147, 147};

          Under JDK1.0.2, you have to explicitly connect the two endpoints,
          and you would write the array elements as:

          int xPoints[] = { 71,  78,  78,  71,  71};
          int yPoints[] = {130, 130, 147, 147, 130};

     15.13 Why can't I see all the components I added to a Frame?
        o A. If you have code like:

          Frame myframe = new Frame("Child Frame");
          myframe.resize(512,384);
          myframe.add(new Label("Child"));
          myframe.show();

          you may find that the Label does not show up in the Frame. Or it
          may show up in appletviewer, but not in a browser.

          The default layout manager for Frame is BorderLayout. Components
          positioned with a BorderLayout must include a positioning constant
          to be correct. So, change the add to

          myframe.add("Center", new Label("Child"));

          and all will be well.

     15.14 Why do I get the wrong results when I compare two Strings
     together?
        o if (s1 == s2)

          is giving me funny results.

          A. The comparison using "==" on objects, like Strings, is asking
          the question "do these two objects have the same reference?". That
          is, do they have the same address, and hence are not two object
          but one? What you most probably meant is "do these two Strings
          have the same contents?" which you can express this way:

          if ( s1.equals(s2) )

          This is a very, very easy mistake to make and impossible to spot
          until you have had it explained to you.

          People talk about "interning" a String. That means calling the
          intern() method on a String. This places the String in the
          constant pool if it was not already there. The compiler is
          required to intern() all literal Strings. If you intern() all your
          Strings as well then all duplicates are shared and comparisons can
          be done by the (much faster) address comparison rather than
          content comparison. It's a performance optimization. See also
          Q3.22.

     15.15 Why doesn't final prevent my object from changing?
        o A. You have code like this

          final StringBuffer s = new StringBuffer("don't change me");
           // ...
          s.append(", but I did");
          System.out.println(s);

          And the new value of s is "don't change me, but I did". The reason
          is that the "final" modifier makes the reference variable (here,
          s) final, not the object that s points to. It means that the
          reference variable cannot be changed to point to some other
          StringBuffer. The state of the StringBuffer can still be modified
          by calling methods on it or directly assigning to its public
          fields.

          The right way to think about final is that it prevents you
          assigning to that particular variable. The only way to make the
          fields of an object constant (unchanging) is to make all its data
          fields private, and not provide any set methods for them, only get
          methods. Even that won't stop other objects of the same class
          adjusting it.

     15.16 Why can't the compiler find my package?
        o A. When trying to compile a file in a package you get a compiler
          error like:


           DBTest.java:10: Class database.Table not found in type declaration.

          The file Table.java and DBTest.java are in the same directory.
          They both have "package database;" at the top of the file. The
          current directory is included in the classpath.

          The reason is that when compiling packages, you have to be at the
          'top' of the directory/package hierarchy. So to compile both
          Table.java and DBTest.java, you have to be in the directory that
          contains the database directory (i.e. where the package hierarchy
          starts), and just:

                 javac database/Table.java
                 javac database/DBTest.java


          and it should all compile fine.

------------------------------------------------------------------------

Acknowledgements

FAQ copyright 1997, 1998 by Peter van der Linden. Contributions and help
from:

Matt Kennel, Patric Jonsson, Brad Van Tighem, Tony Hursh , Glenn L
Vanderburg, Peter Jones, John McDowall, Jim Driscoll, Uday, Dave Harris,
Bill Wilkinson, Tom Valesky, Dan Drake, Giles Thomas, Mitch Baltuch, Guy
Ruth Hammond, Gordon Keith, Jason Brome, Shani Kerr, Steve Chapel, Timothy
Wolters, Robert Lynch, Jake Cormier, Sean C Sullivan, Joseph A. Millar, Jim
Frost, Jim Balter, Jeff Bauer, John Kochmar, Carl Burke, William Stubbs,
Mark Smith, Volker Turau, Real Gagnon, Russell Gold, Max Hailperin, Bill
Tschumy, Marco Nijdam, Marc Pawlowsky, Laurence Vanhelsuwe,Ian Macgregor,
Mike Faulkner, Rich Koch, Will Clark, Govind Seshadri, Rich Simkin, Ian
Stiles, Kieren, Darren Christie, Tom Lane, Michael Jungmann, Rob Mayoff,
George Ruban, Tom McCann, David Hopwood, Thomas Phan, Kai Stuke, Rolf
Howarth, Derek Snider, David Boydston, Andy Godwin, John F. Dumas, Doug
Bell, David J. Biesack, Tiger Quimpo, Martin Hugh Rogers, Brian Krahmer, Ian
Burrell, Nikki Locke, Bin Li, Jackson Thompson, Steve Odendahl, Greg Smith,
Jeffrey C. Ollie, Mark Halvin, Jeremy Cook, Lak Ming Lam, Peter S. Morris,
Mark Halvin, Juergen Keil, Alex Stewart, Mike Abney, Rodney Stephenson Mark
Gritter, Satish Talim, Tamminen Eero, Alexander Gridnev, Eric Hodges, Jamey
Graham, Will Lockhart, Scott Plante, Tom Sanfilippo, Jan Newmarch, Sean
Breslin, Stuart D. Gathman, rhino@wwdc.com, C Matthew Curtin, Tor Iver
Wilhelmsen, A.N.Pryke, Phil Race, David Holmes, David Rodal, Dominique
Plante, Trent Jarvi, Ingrid Biery, Gopal Unni Krishnan, Grant Lewis, Tov Are
Jacobsen, Gary McGath, Marty Hall, Will Forster, Colin Mummery, Darin
McBride, Mayank Shah, Jens Alfke, Glen Stampoultzis, Philip Brown, Peter
Steiner, Kurt Spaugh, Rasmus Ekman, Jonathan Revusky, Ken Kalish, Dave
Sanders, Bill Hyden, James Cloughley, Philip "diodes" Gustafson, Paul
Kinnucan, Juan Valdéz, Antranig Basman, Felix Pahl, David N. Still, Simon
Arthur, Mark Hammond, Dan Kegel, Thomas Weidenfeller, Pavel Shvartsman,
Christen Monberg, George Reese, Ian Macgregor, John Sublett, David
Zimmerman, Tony Dahlman, Druid, Chris Kelly, Patricia Shanahan, Paul Hill,
Lyne Lamoureux
------------------------------------------------------------------------

I am maintaining a FAQ list to address specifically programming issues
(not a general tutorial on Java). Please mail suggested FAQ entries
including answer to me at pvdl@best.com.
Question with answer gets you a credit in the FAQ.
Peter van der Linden, Sun Certified Java Programmer.

-- end --

