s-hub1.bbnplanet.com!news.bbnplanet.com!newshub2.home.com!newshub1.home.com!news.home.com!news1.best.com!news.idiom.com!nntp2.ba.best.com!shellx.best.com!not-for-mail
Subject: Java Programmers FAQ
Date: 1 Sep 1997 17:31:39 -0700
Summary: This posting answers frequently-asked questions by Java programmers

Archive-name: computer-lang/java/programmers-faq
Posting-Frequency: twice-weekly
URL: http://www.best.com/~pvdl
Copyright: (c) 1997 Peter van der Linden
Maintainer: Peter van der Linden (pvdl@best.com)

A list of Frequently Asked Questions (with answers) for Java programmers.
Most of the Java FAQ's here are intended for experienced programmers.  
To distinguish this from other Java FAQs, this is the "Programmer's FAQ" 
and will be posted mostly in comp.lang.java.programmer, comp.lang.java.help,
comp.lang.java.gui, and comp.answers. 

Latest copy of this FAQ is available at:  http://www.best.com/~pvdl

This FAQ reflects the latest and most current version of Java: JDK 1.1.3.

0. A WORD FROM OUR SPONSOR
1. LOOKING FOR INFORMATION
2. COMPILERS, ETC.
3. LANGUAGE ISSUES
4. AWT and related topics
   4.0 AWT
   4.1 APPLETS
   4.2 BROWSERS
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

-------------------------------------------------------------------------
0. A WORD FROM OUR SPONSOR

This Java FAQ is compiled and maintained as a service to the Java community.
Please consider these books when you are looking for a programming text.
You can get more info on these books at http://www.best.com/~pvdl

0.1   "Not Just Java"  by Peter van der Linden, $35
      publ 1997 Sun Press/Prentice-Hall, ISBN 0-13-864638-4

   This should be your first book on Java -- and it doesn't teach Java
   programming.  Instead, this book describes the trends and implications 
   of Java and related technologies. Clear explanations with diagrams 
   covering Java, CORBA, thin clients, network computers, RMI, 
   multi-tier systems, Java threads, ActiveX, OLE, JavaBeans, JDBC, etc.
   For engineers, executives, and all the job titles in between.

0.2   "Just Java Second Ed."  by Peter van der Linden, $35
       publ 1996 Sun Press/Prentice-Hall, ISBN 0-13-272303-4

   An introduction to Java Programming, for people who can already program
   in another language.  Filled with common sense examples, and anecdotes
   from the computer industry.  Learning Java is enjoyable, stimulating fun
   with this book.  Comes with a CD including the compiler and sample code.

0.3  "Expert C Programming" by Peter van der Linden, $35,
     publ 1994 Sun Press/Prentice-Hall, ISBN 0-13-177429-8.

   Everyone's *second* book on C.  Unix Review gave it "5 stars".  
   "Expert C Programming" teaches you the tips and techniques 
   used by the very best C programmers in the world.  Based on a decade in
   Sun's compiler and OS groups.

These books can be ordered online from http://www.cbooks.com
Or by phone from Quantum Books 617 494-5042 (in USA) during business hours.
   
-------------------------------------------------------------------------
1. LOOKING FOR INFORMATION

1.1 What is the best way to refer someone to the FAQ when they ask a question
    I know is answered there?

A.  The Java Programmers FAQ <http://www.best.com/~pvdl> gives the answer to 
    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, providing an incentive to go there next time.)

1.2  Where can I look at the definitive Java Language Specification?

A.   This is available online at:

      http://java.sun.com/docs/books/jls/html/index.html     (Java 1.0)

          and the Java 1.1 update at:

      http://java.sun.com/docs/books/jls/html/1.1Update.html

     This is also available as a book in printed form (details at website).


1.3 Where can I find a full list of Java books and book reviews?

A.     http://lightyear.ncsa.uiuc.edu/~srp/java/javabooks.html

1.4 How do I search Deja News for past postings on Java topics, e.g. the FAQ?

A.  Go to   http://www.dejanews.com/home_sf.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).

    This makes finding information very easy.

    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?

A.  Look at http://java.sun.com/products/jdk/1.1/knownbugs/index.html

    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://www.javasoft.com:80/cgi-bin/bugreport.cgi

    You can even send in an RFE or ease-of-use issue there!

    If you go to the JDC (that's the Java Developer's Connection) you can
    do a keyword search against the internal Javasoft bugtraq database,
    looking by keyword or bug number.   JDC has free registration.
    http://developer.javasoft.com  should do it.

    Also, there's longer list of known bugs at:
        http://www2.vo.lu/homepages/gmid/java.htm

1.6 Is there a Java port to Windows 3.1?

A.  IBM's ADK1.02 beta 3 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 [anyone know the version?]
    Microsoft is preparing a Win3.1 port of the JDK.

    You should also consider JavaSoft's JavaPC $100 kit that converts a 
    PC into a thin client Java system.  Details are sparse as yet, 
    but this is probably more for business users than personal PCs.

    A list of JDK ports is available from
          http://java.sun.com/products/jdk/jdk-ports.html

1.7 I see a lot of postings from magazines soliciting Java articles.
    Are these legitimate?

A.  Anyone considering writing for the "Java Developer's Journal", or
    any other Sys-Con publication, should be aware that there have been 
    several instances of programmers complaining that JDJ has not paid
    them for commissioned articles.  
    
    Another programmer reported that he was not paid by Sys-Con for an
    article for their Delphi magazine.   There is a pattern of programmers
    complaining that SYS-CON has not paid them.   
    Programmer beware, and please don't support magazines that are in 
    conflict over payment with their programmer contributors.
    
1.8  What are the good folks at project Gnu doing with Java?

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

1.9  Where can I find information about Java Certification?

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/sunservice/suned/java_certification.html

     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.

A. Check out the section "Naming Conventions" in the language specification
        http://java.sun.com/docs/books/jls/html/6.doc.html#11186


-------------------------------------------------------------------------
2. COMPILERS, ETC.

2.1  Why did I get an OutOfMemory error when porting working code 
    from jdk 1.02 -> 1.1

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?

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?

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/Jack/

2.4  Where can I find a byte code obfuscator?

A.     HashJava: http://www.blackdown.org/~kbs/hashjava.html
       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.0 and 1.1:

        http://www.monmouth.com/~neil/Obfuscate.html

2.5  Which program is used to create .zip files, compatible with the java* 
     programs? (eg classes.zip, moz3_0.zip)

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

     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);
        Unix command: zip -r0 classes.zip <directories>
     2. Make sure the main class has no directory beside it inside the
        archive, but your packages do;
     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.   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 .class file to a binary executable, .exe on a PC?

A.  Some companies make products that do this, but it takes away one of the
    most significant benefits of Java: portability of executables.  
    Consider carefully why you want to do this, 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?

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.
  
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:
         /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 a real pain.  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?

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 the
     compiler 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?

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.
     On Solaris, make sure that the environment variable
     LD_LIBRARY_PATH includes the path of your shared library.

-------------------------------------------------------------------------
3. LANGUAGE ISSUES
3.1 Why doesn't my "hello world" program work?

A.  Two very common causes of failure are:
    * the 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.
      In JDK 1.1.2, it is generally an ERROR if the user sets the CLASSPATH!
      (except that use of RMI apparently still requires it).

3.2 How can I program linked lists if Java doesn't have pointers?

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 memory management 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.3 What is the true story about how parameters are passed in Java? Is is
    by value or by reference?

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?

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 ...

3.5 Why is String a final class?  I often want to override it in some way.

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.6 What happened to "private protected"?

A. It first appeared in JDK 1.0 FCS (it had not been in the Beta's).  Then it
   was removed in JDK 1.0.1.   It was complicated to explain, it was an
   ugly hack syntax-wise, and it didn't fit consistently with the other 
   access modifiers.   More people disliked it than liked it, and 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?

A. When you define a constructor for a class, unless you explicitly
   call the superclass's constructor at the start, a call to the
   superclass's 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's constructor
   with the right parameters.

3.8  Why does <unexpected> happen in Java floating point?

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://www.javasoft.com/products/jdk/1.1/compatibility.html#incompatibilities
 http://www.javasoft.com/doc/language_specification/javalang.doc.html#1466
 http://www.javasoft.com/doc/language_specification/javalang.doc.html#5899

    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 Why do I get the compiler error message
     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("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 either to declare test with an explicit initial value of null, or
    (better) to print out the e.getMessage() string of the exception.

3.10 Why do I get this compiler error message?

   public static void main(String[] args)  {
                                            ^
                                            Statement expected.
       public static final float Conversion_Factor = 39.37; 
       ^
       Type expected.

A.  Variable declarations inside are never given the
    "public", "static", or "final" keywords.  They are not
    public or static because they are local to a method.
    They are not final by convention.
    Move your constant declarations outside the method.
    They are usually put at the beginning of the class.

3.11 Why do I get this compiler error message?

    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
     Thing.java:96: Can't access protected method clone in class 
     java.lang.Object. OtherThing is not a subclass of the current class.

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 I transform a char into the corresponding int value,
    that represents the code value of the char?

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?

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's constructor is provided
    for you.  If the superclass doesn't have a no-arg constructor, see 3.9

3.15 How do I allocate a multidimensional array?

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 
        Int Iarr[] = new Int[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.
             import java.rmi.server.*;

             RemoteObject ro;

      versus:

             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"?

A.   A feature introduced in JDK 1.1.
     They are literals of type "Class" that hold a value representing
     any class.  There is even a value to represent "void", like this:

        Class myCl1 = Character.class;
        Class myCl2 = Void.class;
        Class myCl3 = Object.class;

     You might use it like this:
        Class cl = thing.getClass();
        if (cl.equals(myCl1))
            System.out.println("It's a Character class");


3.18  How do I copy the contents of an array (with primitive type contents)
      to another array?

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.  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.   It was always a terrible idea, as it went outside the
      boundaries of defined behavior in COBOL, and was subject to being
      broken in any compiler release.

      In any event, intialization 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?

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?

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 java.lang.Math were not final, you could instantiate a local copy
    with a shorter name, but the final prevents it.   

    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?

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?
           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)

-------------------------------------------------------------------------
4. AWT and related topics

4.0 AWT
4.0.1 Why do I get this when using JDK 1.1 under X Windows?
     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.2 Why is GridBagLayout so hard to use?

A.  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 waste any effort on GBL, there are better 
    alternatives available now, and it will be replaced by the SwingSet
    "SpringLayout" Springs & Struts style layout manager to be introduced 
    as part of the Java Foundation Classes with JDK 1.2.

4.0.3 How do you change the font type and size of text in a TextArea?

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.4  MyClass 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.

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 
    "Ariel" 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()


4.0.5  Is it possible to draw a polygon or a line more than 1 pixel wide?

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.6  I use add(Component) to add Components to the Container. Is there 
      any way to explicitly set the z-order of these Components?

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 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.7 When I call repaint() repeatedly, half my requests get lost and 
     don't appear on the screen.  Why is this?

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.8  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.9  When I start a mouse 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?

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.10 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?

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 that has no knowledge of the other g.drawing() you 
     have done.

4.0.11 But couldn't the AWT just remember what has been drawn to a Graphics
     context, and replicate that instead of calling paint()?

A.   It could, 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.12  How can I get the dimensions and resolution of the screen?

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.13  How do I allow for the size of the title bar and border when I draw
     a Frame?

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().

4.0.14. When I run the Swing demo on Win95 I get an error  "Out of environment 
      space"

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.15  How do I resize a List? I had a List defined as
        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.

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.16  How can my program tell when a window is resized?

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.17 How do I get back to a normal echo after I have used
       TextField.setEchoChar('*');

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.18 How do I clear the contents of a TextArea?

A.   Set it to a null String with this:    area.setText("");

4.0.19  What are those preferredSize() and minimumSize() methods in Component?

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.20  How can I force a synchronization of the graphics state, e.g. of
    a cursor change, or an animation frame to be rendered?

A.  This is done by the sync() method in the toolkit.  So just use:
       AnyComponent.getToolkit().sync();

4.0.21 How do I plot a single pixel to the screen?

A.   Use g.drawLine(x1,y1,x1,y1) to draw a line one pixel in length.

4.0.22  How can I tab between components?

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.1  APPLETS

4.1.1  What is the difference between an application, and applet and a servlet?

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.
    A Servlet is an application, but (like an applet) requires a context
    in which to run, namely web-server software.  Servlets are used like
    CGI, but allows 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.

    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 My applet works on my machine, but fails when I put it on our web server.
    Why? 

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 I use an image as the background to my applet?
     How do I set the background color of my applet the same as the browser?

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 the applet's background transparent?

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 do file I/O from an applet?

A.  See answer to question 6.8.

4.1.6 How do you get a MenuBar/Menu in an applet?

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:
        Container parent = getParent();
        while (! (parent instanceof Frame) )
                parent = parent.getParent();
        Frame theFrame = (Frame) parent;

    This second suggestion 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.7  Can I get rid of the message "Warning:Applet Window"
     along the bottom of my popup windows in my Applet?

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.
     
    Making the call
.requestPrivilege("UniversalTopLevelWindow");
    before creation of the Frame eliminates the message, if the 
    security manager passes it.


4.1.8 When I subclass Applet, why should I put setup code in the
        init() method?  Why not just a constructor for my class?

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.9  How do I pull a non-class file, such as a .gif, out of a jar file?

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 {
                img = tk.createImage(
                        (java.awt.image.ImageProducer)
                        imageURL.getContent());
        }
        catch (java.io.IOException ex) {
                        System.out.println(ex);
        }

     (Like anything involving Jar files, this is from JDK 1.1 on).

4.1.10  I want to know about {applets,applications} but the lousy book I bought 
        just talks about {applications,applets}.  What can I do?

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.  

    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.2  BROWSERS

4.2.1  When will my favorite browser support Java 1.1?

A:  Netscape Communicator 4.0 supports most new features of Java 1.1,
    but not the two most important ones: the new Event model, and Beans.
    Communicator is scheduled to fully support Java 1.1 in Fall 1997, and
    it will use "smart update" to change your copy of the browser (with
    your "ok") without requiring a full new download.
    URL: http://developer.netscape.com/support/faqs/champions/java.html#21

    Sun's HotJava browser fully supports the JDK 1.1 features.

    Internet Explorer 4.0, anticipated to be released in Fall 1997,
    will fully support Java 1.1, ... apart from the pieces of the language
    that Microsoft is saying they will not support: RMI, JFC, JNI, JAR etc.
    
    Some people have speculated that Microsoft is just trying to slow down
    the drive to Java, by spreading fear, uncertainty, doubt, and that in
    fact sooner or later they will be forced to support portable Java, not 
    try to undermine it.  Until that day, savvy developers need to consider
    portability when they choose their development tools.

4.2.2  Is it possible to set and retrieve cookies from Java, in a manner
      that is compatible with all browsers supporting cookies?

A.  Short answer: no.
    Longer answer: probably no.
    Ultimate answer: The DevEdge site on Netscape's home page has a 
    javascript-java example on getting cookies. 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?

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.


4.2.4  So, why can't Netscape reload the applet when you press the Reload button?

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 Microsoft CAB files or Java JAR files?

A.  The question contains its own answer.  

        CAB format is a Microsoft-only format
     
        JAR format is the Java standard format, based on PKZIP format
        including data compression.  JARs were introduced with JDK 1.1

   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 with compression turned on.
   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>

   The same reader says that Microsoft will support JAR format with
   Internet Explorer 4.0.

 
-------------------------------------------------------------------------
5. CORE LIBRARIES
5.1 I can't seem to change the value of an Integer object once created.

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 I print from a Java program?

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. 

    To print in JDK 1.0.2, some people have suggested using Jentec's JENI. 
    (The Java Enterprise Network Interface).  JENI is a set of classes that 
    provides applets with file, print, email, and directory services to lots 
    of different protocols and locally without the applet having to change 
    or even be aware which is being used.

    JENI is free and available at "http://www.jentec.com". For an example of
    how to print, see "http://www.jentec.com/live/jeni/PrintingAFile.html".
    To save a file, see
       "http://www.jentec.com/live/jeni/CreatingAFile.html".

5.3 What are the properties that can be used in a PrintJob?

A.  The properties are
      awt.print.destination   - can be "printer" or "file"
      awt.print.printer       - print command
      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 any package in Java to handle HTML?

A.  No, Java 1.1 does not have a core library widget that automatically 
    formats HTML.  At least one person has written one though.
    Search at http://www.gamelan.com or http://www.yahoo.com for details.

5.5 Why don't Dialogs work the way I want them to?

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 find information about the sun.* classes in the JDK?

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.

5.7 How do you read environment variables from with a Java program?

A.  Environment variables are not used in Java, as they are not platform
    portable.  The Mac doesn't have environment variables for example.
    Use properties instead.    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      (MS-DOS)
    This sets the "foo" property to the value of the environment 
    variable foo.  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


5.8  How do you use the Date class to display the current time in my
     timezone?   Date.toString() always uses PST. [jdk 1.1] (Pacific 
     Standard Time -- the zone covering California where JavaSoft is).

A.   To make things easier for debugging Sun has decided that
     the toString() method should always use one format, 
     if you want a different format you should use the new
     internationalization routines.

     As a Date is stored internally in GMT the obvious choice
     for a standard format is... PST time? JavaSoft is in the PST zone
     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"));

        or even:

        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.

   Don't forget this code too, to prevent GMT being interpreted as
   GMT+1:00 hour.
        // + 1 is to work around bug in GregorianCalendar
        // XXX - need FIX
        // should probably be formatter.format( this );
        // or formatter.format(new Date());

        return formatter.format( new Date(getTime() + 1) );
   
5.9 How are dates represented in Java?

A.  java.util.Date stores dates as integers representing the number of
    seconds 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.  It is a poorly-conceived representation, 
    spanning just the years 1901-2038, and more classes were added 
    in JDK 1.1 to try to fix it up.  They didn't really improve matters. 
    Note that this differs from the Java specification which says that
    Dates should be stored as a long, and contain milliseconds since the
    Epoch.  That actually gives a reasonable range (although making dates
    before the Epoch be negative is still suspect, as it doesn't correspond
    to the real world representation).
    Dates are the lemon of Java, as Roedy Green truly notes.

    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.

5.10  That may be, but how do I extract day, month, year from a Date?

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 all this junk will be fixed once and for all in a future release.

    The Calendar, DateFormat, and even TimeZone classes will give you 
    the timezone of your system (wherever you are).  
    The default time zone for SimpleDateFormats is PST (i.e. California).

5.11 What kind of different date formats are allowed for the Date constructor
     with the string parameter.

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.12 How do I get Java talking to a Microsoft Access database?

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 2nd Ed."
    mentioned in the sponsorship section of this document.

    Note that the Microsoft Java kit does not support JDBC-ODBC access.
    Also check the JDBC FAQ listed at the end of this document.

5.13 I can't seem to change the current working directory.

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.14 How do I create a Vector of ints?

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.15 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?

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.16 How do I get random numbers?

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:

        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 gracefully 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 (incl.):

        Random r = new Random();
        int j = (Integer.MAX_VALUE & r.nextInt()) % (high-low+1) + low;

     The sentence 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.

     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.
        [... to be continued... ]

5.17  What does "deprecated" mean?  I got this in a compiler error message.

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.18  Where/why should I use the Enumeration interface?

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() );
       }

    You should look for opportunities in your own data structures to
    implement Enumeration, anywhere where the structure has repeated
    elements.



-------------------------------------------------------------------------
6. I/O

6.1  How do I read a String/int/boolean/etc from the keyboard?

     The easiest way is to pick up the source for the 100% pure Java
     class EasyIn from http://www.best.com/~pvdl   (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.
     

6.2  Why do I have trouble with System.out.println()?
 
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.3 How do I write to the serial port on my PC using Java?

    NOTE: This answer needs to be proved by a practical example.
    We don't have a satisfactory example of this so far.  Provide one, and
    get your name in the FAQ for all time!
A.  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.
    Some people say that writing a formfeed at the end of the file is needed.

    The bigger problem is if you wish to
    change the characteristics of the port (e.g. baud rate, parity, etc).
    Java currently offers no portable way to do this.  You will need to
    use a native method, or execute a system command. 
    At least two companies have written a library to drive the port on
    Windows 95, NT, OS/2.  See 
                http://www.sc-systems.com
                http://www.cd.com/portio

    In addition, there is a Unix serial port utility available with
    source at:
http://www.blackdown.org/java-linux/downloads/Private/jarvi/rxtx-1.1.1p2.tar.gz

6.4 How do I append to a file?

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.

6.5  Is it possible to lock a file using Java ?

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 three 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 delete" and have all processes (Java 
        and non-Java) follow the same protocol: if the file was deleted by you, 
        you have the lock, and you create the file again to give up the lock.
     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.  

6.6  How do I make the keyboard beep in Java?

A.   In JDK 1.1, java.awt.Toolkit has the method beep().  
     It does not work on NT 4.0 (bug).

6.7 How do I execute a command from Java?
    How do I do I/O redirection in Java using exec() ?

A.  See answer to question 10.4


6.8 How do you do file I/O from an applet?

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);
           URLConnection uc = url.openConnection();
           DataInputStream dis = new DataInputStream(uc.getInputStream());
           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 (custom written)
    - listening on a socket for data from applets
    - CGI script
    - Java RMI (remote method invocation)

    In particular:
    1. Or 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.
    2. 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).

    Also see the answer to question 5.2 regarding the JENI library.


6.9  I used a C program to write a binary file.  When I instatiate a
    DataInputStream on the file in Java, and try to readInt, I do not
    get the correct numbers.  Why is this?

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;
       }

6.10  How do I make I/O faster?  My file copy program is slow.

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.11  How do I do formatted I/O of floating point numbers?

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.

    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.12 How do I read numbers in exponential format in Java?

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.13  I'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.

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.14  How do I delete a directory in Java?

A.  JDK 1.0 did not support directory removal.
    JDK 1.1 does support 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?

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 have to Runtime.getRuntime.exec() to do "df" on unix or "dir" on 
   Windows right now.

-------------------------------------------------------------------------
7. NETWORKING & DISTRIBUTED OBJECTS
7.1 Should I use CORBA in preference to RMI?  Or DCOM? Or what?

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.

    In July 1997, Sun announced that it was aligning RMI to work more
    closely with CORBA, and perhaps even use IIOP as its on the wire
    protocol.   This will take some additions to IIOP to support the
    pieces that RMI uses.

    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 Why does <my java debugger/IDE/other> hang for a couple of minutes
    if my Windows PC is not dialed up to the Internet?

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 avoid the problem by giving your system another way to
    resolve DNS names.  Edit the hosts file for your system (found in
    %windir%\hosts on Win95 and %windir%\system32\drivers\etc\hosts on NT)
    so that localhost and the full domain name are both mentioned.  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

    [If any networking guru's have improvements to this process, send'em in!]

    There is a longer, different procedure at http://www.best.com/~pvdl
    Please send me mail (pvdl@best.com) if either or both of these work
    or don't work for you, so I can update the FAQ.

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
         Socket sock = new Socket("155.152.5.1", 23);
    triggers the exception.  Why?

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");
    should always work. 

    [Note: this info is still to be confirmed.  Net guru's?]


7.4 I am using JDK 1.1.1 on Windows95, and when I start jdb I get
    "Uncaught exception: java.lang.UnsatisfiedLinkError no winawt 
     in shared library path"

    The same program works OK using jdk1.1

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.5 I want to pass a class file to willing recipients who are using
    my applet.   Any ideas how?

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.6 How do you succeed with new URL(someURL) from behind a proxy server? 

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.8 I 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:
     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.8  My socket code looks good, but is broken!

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.9  How do I map between IP address and hostname?
   In Java 1.1 (earlier releases were buggy) use:
   
   String host = InetAddress.getByName("211.10.2.119").getHostName();

7.10  How do I embed an anchor in a URL?   Just putting it as part of the
    string in the constructor doesn't work.

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.11 RMI seems to have stopped working for me in JDK 1.1.  Why is this?

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://www.javasoft.com/products/jdk/1.1/docs/guide/rmi/index.html
   * Dedicated FAQs on RMI and Object Serialization
     http://chatsubo.javasoft.com/current/faq.html
   * Mailing list RMI-USERS@JAVASOFT.COM with archive at 
     http://chatsubo.javasoft.com/email/rmi-users/
     Visit the archive!


-------------------------------------------------------------------------
8. MULTI-MEDIA
8.1 Why won't my audio file play?

    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

8.2 Does Java support Animated GIFs?  

    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.  You can use cliprect() with a negative x coordinate 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.1  How 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.3  Does Java support transparent GIFs?

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.4 How do I play video in Java?

A.  Use the Java Media Framework Player API

    The spec can be found at  
    http://www.javasoft.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.5 How can I play *.au files from an application?

A. You've got 2 options:

   a.  Use the AudioClip class in sun.audio
       http://www.javaworld.com/javaworld/javatips/jw-javatip24.html
       If you take this option, you can only play AU files.  Worse, your
       code is no longer 100% pure Java, as it relies on a vendor library.

   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.6 How do I read in an image file, in an application?

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?

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".  This tells the system, "whoops, I'd better create 
     the peer for this Component right away).  addNotify will be
     called for you when you add your component to a container.

     If you override addNotify(), don't forget to call super.addNotify()
     in your overriding version.

8.8  How can I force 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.

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 I save an Image file to disk in jpg or gif format?

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.best.com/~pvdl
    [pointers to other sites welcome]

8.10  What causes this problem?
    $ 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.11 How can I convert between GIF and JPEG formats?

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.  Far better to pick the right format in the first place.

    For more info see the JPEG FAQ at http://www.faqs.org/faqs/jpeg-faq/


8.12  If you have an InputStream (rather than a file) that contains an Image,
      how can you display it?

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 (8888 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:8888/")

     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?

A.   The Java Media Framework coming in JDK 1.2 will support this.
     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.


-------------------------------------------------------------------------
9. SECURITY

9.1 What is a "trusted applet"?

    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 with Java and viruses?  What is the blackwidow virus?

    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 are legitimate commercial products of that name).
    If anyone has more concrete information about a virus that can attack a 
    Java applet (again, this is thought to be impossible), please could 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?

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.4  Where can I find crypto libraries for Java?

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
   

9.5  How do I find out what these terms mean?

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.
   

-------------------------------------------------------------------------
10. Java IDIOMS

10.1 How do I convert a String to an int?

A.  There are several ways.   The most straightforward is:
       int i = Integer.parseInt(<String>);
    or i = Integer.parseInt(<String>,<int radix>);

    Note: there are similar classes for Double, Float, Long, etc.
       int i = Integer.valueOf(my_str).intValue();
    also works but involves the creation of an extra object.

10.2 How do I convert an int to a string?

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.3  How do I print the hex value of an int?

A.    Another way is    
          int i = 0xf1;
          System.out.println("i is hex " + Integer.toHexString(i) );

10.4 How can you send a function pointer as an argument?

    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.5 How do I execute a command from Java?
    How do I do I/O redirection in Java using exec() ?

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.6  OK, how do I read the input from a command?

A.  As before, 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 = data.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.7  How do I compile code which has a cyclic dependency, i.e
      class pkg1.X contains a reference to class pkg2.Y  ?

A.    You throw both classes at the compiler at the same time.
           javac pkg1/X.java   pkg2/Y.java


10.8  How can I store the errors from the javac compiler in a DOS file?
      javac foo.java > errorfile seems not to work
 
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.9 How can I pretty-print Java source?

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.10  What 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.

       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.11  What is the difference between  "a & b" and "a && b" ?

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.12  If I create a thread, and then null out the reference to it, what
     happens to the thread?  Does it get interrupted or what?

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.13  How do I calculate the number of days between two dates?

A.  There is no API for this (there should be), but you can calculate
    it by hand, like this:

        long duration = laterDate.getTime() - earlierDate.getTime();
        long nDays = duration / (24 * 60 * 60 * 1000);

10.14  How can 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?

A.  Look at the java.version system property with:
      String ver = System.getProperty("java.version");


-------------------------------------------------------------------------
11. FOR C and C++ AFFICIONADOS
   
11.1 How do I translate C/C++ into Java or vice-versa?

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/
         http://www.cs.wustl.edu/~schmidt/java_notes.html

    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.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 whackers.

11.2 How are finalizers different from C++ destructors?

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.3 What's the Java equivalent of sizeof()?

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.

11.4 Does Java have the equivalent of "const" arguments in C and C++?

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.5 Are there any hacks around this?

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.6 How can I write C/C++ style assertions in Java?

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.

    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.

       public class AssertionException extends RuntimeException {
           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.7  How do I do stuff like scanf and sscanf in C/C++?
      And how do I do stuff like sprintf, e.g.
        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 (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 source for details.


11.8 Does anything like the C++ Standard Template Library exist for Java ?

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/
    [Some Java vendors are bundling it with their next release]


-------------------------------------------------------------------------
12. FURTHER RESOURCES

12.1 Useful URLS

    Latest copy of this FAQ:  http://www.best.com/~pvdl/

    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.htm
       good JDBC FAQ:  http://www.yoyoweb.com/Javanese/JDBC/FAQ.html
       general Java: http://java.miningco.com/
       tutorial:  
              http://www.javasoft.com:80/nav/read/Tutorial/index.html
              http://www.phrantic.com/scoop/onjava.html

    Java Book lists: 
              http://lightyear.ncsa.uiuc.edu/~srp/java/javabooks.html
              http://www.netcharts.com/majug/reviews.html
              http://www.avena.net/~dong/book.htm
              http://wwwiz.com/books

    Javasoft site: http://java.sun.com

    General sharing and exchange of Java info:
              http://www.gamelan.com
              http://www.JavaShareware.com

12.2 Newsgroups
    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, IFC, JFC, AFC, Vibe, etc etc
      comp.lang.java.beans           Software components in Java

  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 .


12.3  Are there any Java libraries for sorting, etc?

A.  A sort class has not yet been made part of the standard library.
    It should be.  Until then, 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 
    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.


12.4  Why doesn't somebody write a shell in Java?  Then they could use it on
    all platforms!

A.  Somebody has done just that.  Look at   http://www.jsh.net/


12.5  Are there any URLs for other libraries?

A.  Indeed, there are.
     The Java3D Repository   http://java3d.sdsc.edu/


-------------------------------------------------------------------------

Acknowledgements:
Original FAQ  copyright February 1997 Peter van der Linden

Contributions 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,
Jake Cormier, Ian Macgregor, Mike Faulkner, Rich Koch, Rick Simkin, 
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, Rob Mayoff, Derek Snider, Tom Lane,
David Boydston, Andy Godwin, John F. Dumas, Doug Bell, David J. Biesack,
Tiger Quimpo, Martin Hugh Rogers


[<your name here>: send in a suggested FAQ *with the answer*]

----

I am maintaining a FAQ list to address specifically programming issues
(not a general tutorial on Java).  Please feel free to mail me entries for it.
Question with answer gets you a credit in the FAQ.
I can be emailed at:  pvdl@best.com
Sun Certified Java Programmer.

-- end -- 
-- 
Peter van der Linden,                     Java Programmer's FAQ
Certified Java Programmer.                --->    http://www.best.com/~pvdl
