FAQ on Advanced Topics by Roseanne Zhang
                                             http://bobcat.webappcabaret.net/javachina/faq/a_01.htm

The questions and answers here are my selective postings on jGuru, JavaRanch, ChinaJavaWorld in order to answer others' questions. After a while of doing this, I realized that a lot of similar questions are being asked again and again.

The purpose of creating this page is to let people in the future have a place to look for answers. People don't need to answer the same question again and again.

Software reusability is extremely important. OO analysis, design, and programming are invented for this purposes. So does the component-based software. Design patterns are discovered for reusing other's design ideas. This page is created for reusing my own answers. Hopefully, this page will make your learning process a little easier.

We all work together to make a difference!

Table of Contents

Swing, AWT, etc

Applets, Servlets, etc

Immutable, etc.

Security, Cryptography, etc.

Zip, Unzip, etc.

JDBC, etc.

JavaMail, etc.

Tutorials

Memory Leaks, GC, etc

Computer Algorithms

Java and multi-platforms

Miscellaneous


Swing, AWT, etc.

Q. Why do you think Swing is based on AWT, w/o peers, it does not work?
A:
Swing is based on AWT, without peers, it does not work. The things on the top of windows are pure Java. The new MAC OS X does even better and more depend on the native stuff, and work more efficient and prettier.

Also, on some Unix systems without GUI support, Swing will not work since the OS does not provide the native peers. Of course, it will work on these Unix system such as X-windows, Linux, Mac OS X, and ... Unless, you want to do a lot of extra work (such as an emulator), and then that should credit to you, not Swing any more...


Linked from Sun's Swing Tutorial, Mixing Heavy and Light Components
one of the primary design goals for Swing was that it be based on AWT architecture.

Read Graphic Java Master the JFC, 3rd edition, by David M. Geary p6 Nearly all Swing components are lightweight. The only exceptions are Swing's top-level containers: frames, applets, windows, and dialogs. Because lightweight components are rendered in their container's window instead of a window of their own, lightweights must ultimately be contained in a heavy weight container...
Read the fine prints, please! I'm serious! People tend to read what they like or what they think to read. Sun actually prefers you read that way too. Swing is not a good GUI product, it never was, and it will never be. Sorry to tell the truth. A story of Creative writerOnce I was writing a document for our new security system. After I put all the goodies, I put a section of limitations. They were deleted by proofreading process. I needed to be honest and also needed to avoid liability problems in the future. Finally, I figured out a way to pass the proofreading. I added a line: "The new system improved the security substantially." which actually should be read as "The new system has limitations." The proofreader actually laughed and said "You found a diplomatic way to say that!" Do you see any similarity from the following quotes?

Java API doc - Provides a set of "lightweight" (all-Java language) components that, to the maximum degree possible, work the same on all platforms.
My translation would be "Something must be impossible to him/her."

Q. How to make JFrame size fit the component on the frame?
A: Use pack() before setVisible().
Here is a simple example.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class EventTest extends JFrame implements ActionListener{
  private JButton bn1, bn2, bn3;
  public EventTest(){
    super("Event Test");
    Container container = getContentPane();
    container.setLayout(new FlowLayout());
    bn1 = new JButton("JButton 1");
    bn2 = new JButton("JButton 2");
    bn3 = new JButton("JButton 3");
    bn1.addActionListener(this);
    bn2.addActionListener(this);
    bn3.addActionListener(this);
    container.add(bn1);
    container.add(bn2);
    container.add(bn3);
    setLocation(400, 300);
    pack();
    setVisible(true);
  }

  public static void main(String[] args) {
    EventTest eventTest = new EventTest();
    eventTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  public void actionPerformed(ActionEvent event){
    Object o = event.getSource();
    if (o instanceof JButton) {
      JButton bn = (JButton)o;
      JOptionPane.showMessageDialog(this, bn.getText() + " clicked");
    }
  }  
}

  • Q. How to switch and test GUI Look and Feel?
    A: Easy! Here is an example.
    We use JComboBox to switch Look and Feel.
    import javax.swing.*;
    import java.awt.event.*;
    
    class LFTest {
      JFrame myfrm;
      JTextField txtTest;
      JPanel panel;
      JComboBox cmbTest;
      String[] lfstrs = {"com.sun.java.swing.plaf.motif.MotifLookAndFeel",
                         "javax.swing.plaf.metal.MetalLookAndFeel",
                         "com.sun.java.swing.plaf.gtk.GTKLookAndFeel",      
                         "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"};
      String lfs;
    
      public static void main(String[] args) {
        new LFTest();
      }
    
      LFTest() {
        try {
          lfs = UIManager.getSystemLookAndFeelClassName();
          UIManager.setLookAndFeel(lfs);
          myfrm=new JFrame("Test For Look and Feel ");
          txtTest=new JTextField("We are changing look and feel by selecting in the combobox");
          cmbTest=new JComboBox(lfstrs);
          
          cmbTest.addItemListener(new MyItemListener());
          cmbTest.setSelectedItem(lfs);
          panel=new JPanel();
          panel.add(txtTest);
      
          panel.add(cmbTest);
          myfrm.getContentPane().add(panel);
          myfrm.pack();
    
          myfrm.setVisible(true);
          myfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        } 
        catch (Exception e) {
          System.err.println("Could not switch to look and feel " + lfs);
        }
      }
      class MyItemListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
          if (e.getStateChange() == ItemEvent.SELECTED) {
            try {      
              lfs = (String)e.getItem();
              UIManager.setLookAndFeel(lfs);
              SwingUtilities.updateComponentTreeUI(myfrm);          
              myfrm.pack();
            }
            catch (Exception ex) {
            }
          }
        }
      }
    }
    

    Q. How to hide a column from JTable, but not remove the data?
    A: Here is the code.
         TableColumnModel colMdl = jtbl.getColumnModel(); 
         // Hide password column, the column still in the tablemodel
         colMdl.removeColumn(colMdl.getColumn(2));
    

    Q. How to show a picture full screen in a JFrame?
    A: Simple!
    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class BG3 extends JFrame  {
      private int w = 800;
      private int h = 600;
    
      MyCanvas canvas;
    
      public BG3() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container container = getContentPane();
    
        canvas = new MyCanvas();
        container.add(canvas);
    
        setSize(w, h);
        setVisible(true); 
      }
    
      public static void main(String arg[]) {
        new BG3();
      }
    }
    
    class MyCanvas extends Canvas {
      String fName = "Flowers006.JPG";
      Image displayImage = null;
        
      MyCanvas() {
        displayImage = Toolkit.getDefaultToolkit().getImage(fName);
    
        MediaTracker mt = new MediaTracker(this);
        mt.addImage(displayImage, 1);
        try {
          mt.waitForAll();
        } 
        catch (Exception e) {
          System.out.println("Exception while loading.");
        }
    
        if (displayImage.getWidth(this) == -1) {
          System.out.println("File " + fName + " does not exist!");
          System.exit(0);
        }
      }
        
      public void paint(Graphics g) {
        g.drawImage(displayImage, 0, 0, getWidth(), getHeight(), this);
      }
    }
    
    

    Q. How to add images into JList?
    A: Easy, just add JLabel with image into the list instead of text.
    However, you need to have a custom ListCellRenderer to handle the select/unselect event. Here is a working sample code.
    import javax.swing.*;
    import java.awt.*;
    import java.util.*;
    public class JListWithImages extends JList {
      public JListWithImages() {
        setCellRenderer(new CustListCellRenderer());
      }
      public static void main(String[] args) {
        JFrame frame = new JFrame("JList with Images Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel pnl = new JPanel();
    
        Vector vector = new Vector();
        ImageIcon img1 = new ImageIcon("res/img1.gif");   
        ImageIcon img2 = new ImageIcon("res/img2.gif");   
        JLabel lbl1 = new JLabel("selection 1", img1, JLabel.LEFT);
        JLabel lbl2 = new JLabel("selection 2", img2, JLabel.LEFT);
        vector.addElement(lbl1);
        vector.addElement(lbl2);
        JListWithImages lstWImgs = new JListWithImages();
        lstWImgs.setListData(vector);
        JScrollPane s = new JScrollPane(lstWImgs);
        s.setPreferredSize(new Dimension(200, (img1.getIconHeight()+2)*vector.size()));
    
        pnl.add(new JLabel("List with Images: ", JLabel.RIGHT));
        pnl.add(s);
        frame.getContentPane().add(pnl);
        frame.pack();
        frame.setVisible(true);
      }
      class CustListCellRenderer implements ListCellRenderer {
        public Component getListCellRendererComponent(JList list, 
                                                      Object value, 
                                                      int index, 
                                                      boolean isSelected, 
                                                      boolean cellHasFocus) {
          JLabel lbl = (JLabel)value;
          lbl.setOpaque(true);      
          lbl.setBackground(isSelected ? Color.black : Color.white);
          lbl.setForeground(isSelected ? Color.white : Color.black);
          return lbl;
        }
      }
    }
    

    Q. How to show a webpage in Swing?
    A: It is possible, but the effect is not very good unless the webpage is extremely simple.
    Use JEditorPane. It initially shows a simple Sun's demo page, it works fine. However, ft you change it to some a little more complicated page, you will see the problem. It certainly cannot replace the read browser.
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    public class SimBrower extends JFrame implements ActionListener{
      JEditorPane edtPane = new JEditorPane();
      JLabel lbl = new JLabel("Type URL:", JLabel.RIGHT);
      String samurl = "http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/TextSamplerDemoHelp.html";  
      public SimBrower(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel pnl = new JPanel();
        pnl.add(lbl);
        JTextField urlFld = new JTextField(60);
        lbl.setLabelFor(urlFld);
        urlFld.addActionListener(this);
        urlFld.setActionCommand("url");
        urlFld.setText(samurl);
        pnl.add(urlFld);
        getContentPane().add(pnl, BorderLayout.NORTH);
        setEditorPane(samurl);
        JScrollPane scrPane = new JScrollPane(edtPane);
        scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        getContentPane().add(scrPane);
        setSize(800, 600);
        setVisible(true);
      }
      public void actionPerformed(ActionEvent evt) {
        String s = evt.getActionCommand( );
        if (s.equals("url")) {
          JTextField src = (JTextField)evt.getSource();
          String surl = src.getText();
          setEditorPane(surl);
        }    
      }
      private void setEditorPane(String s) {
        try {
          URL url = new URL(s);
          edtPane.setPage(url);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
      public static void main(String[] args) {
        SimBrower frm = new SimBrower("Simple Brower");
      }
    }
    

    Q. Can we do MDI in Swing?
    A: Yes, we can.
    MDI: Multi-Document Interface. You can use JInternalFrame and JDesktopPane. See here How to Use Internal Frames

    Applets, Servlets, etc.

    Q. What is meant by "Sandbox Model" as in case of an applet?
    A:
    Applets are designed to run in a sandbox. This means they don't get access to the local machine and they can only talk to the server they came from.An unsigned applet cannot connect to a server other than the server it was downloaded from. There are also similar restrictions about the port used.An applet cannot receive incoming connections. An applet is not allowed to send out broadcast UDP messages.Applets are not allowed to go rooting around in the local file systems of their executing hosts.Applets use a ClassLoader inside the browser to do the download, and both the major browsers don't consider the local CLASSPATH for code, because they don't want to pick up code lying about on the user's hard drive -- security risk.If you want to break out of that sandbox, you need to establish a trusted relationship with the applet in which case the applet can behave similar to an application.

    Q. What are the benefits by using param tags for an applet? Why not put them in the code?
    A: Important benefits:
    1) It is extremely useful when using JSP/Servlet, the parameters can be dynamically generated by the client action, circumference, time, etc. etc. The HTML page would be dynamically generated in that case. Your applet can change the looking, behavior, etc. on the fly. 2) Even in the static html case, you can change the applet by changing you html without recompiling your applet, which would be a huge benefit too.

    Q. How can you achieve applet to servlet commuincation and vice versa?
    A:
    Applet - Servlet : Using AppletContext.ShowDocument(url, target) and put your info into the url String. Servlet - Applet: Servet write the parameters for Applet to use. Remember Applet is at the client side; Servlet is at the Server side. Other than above, the regular Socket, RMI can be used too.

    Q. What is the difference between HttpServletResponse.sendRedirect method and the RequestDispacher.forward method?
    A:
    The forward method is limited only forward to the resources on the server, but it is faster. The sendRedirect method does not have the limit. http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/RequestDispatcher.html

    Q. Why are local variables always thread safe?
    A:
    Local variables are stored on the Thread calling stack. They are NOT shared between different calling threads. This is true in almost any programming languages, unless you declare the local variable as static such as in c/c++/VB, and then it is shared. However, Java does not allow that to happen. It does not matter it is static method or instance method. However, be cautious when your method modifies something else which is not local. That is when synchronized keyword needs to be kicked in. There is one thing in Java easily causes confusion. Java objects created local are not stored on thread calling stacks. They are always on the heap, only the local references are stored on the calling stack. If you make those objects available outside the local range, it will become thread unsafe. For example, if you store it in to the HttpSession, it is not thread safe any more.This is very different than c++ local objects, such as Object o; which is truely local. The Java object created local is equivalent to c++, Object* p = new Object(); which can be used outside of the local range.

    Q. Why does obfuscated JavaBeans break my JSP application?
    A:
    Obfuscated code will break Java reflection. When your code uses reflection, Obfuscator is usually not an option. JSP communicates with JavaBeans using introspection, which in turn uses reflection. That is why. Everything has a limit, this a good example for that. Do we have a way to get around it? Yes, of course. You need to manually change the obfuscated code to meet the introspection requirement. It would be a headache for sure!

    Q. Why cannot I see my modification on my JSP even I do a refresh? Is that a tomcat problem?
    A: No, it is not tomcat, but your IE or your proxy server.
    It will happen quite often. Every developer experiences the same.

    If you are only developing and display on your local machine, it is easy. The followings would be I do in that order.

    1. Refresh, of course
    2. Go to IE explorer properties dialog, delete all offline files, your problem is solved.
    If you upload your code on a server, then access the website, then you need to play cat and mouse games with them. Try let the proxy server know your page need to be updated. Do the same 2 items as on your local machine, if it does not work, the do the followings:
    1. Temporaly rename your page to something else, and access the "new" page.
    2. Shutdown my website for a minute, and access it, the proxy will give me 404. Then restart.
    Other people might have some more creative way, let me know!!!

    Q. How to force people re-login when session expired?
    A: Take care it in your LoginJavaBean.
    Make your LoginJavaBean life cycle is Session, the login status is an instance variable of your LoginJavaBean. The value is default to false. The problem is solved. You don't need to do any extra work to handle your situation!!!! Put the login status where it belongs to, the LoginJavaBean, or whatever name you call it.

    The basic OO concept: let everyone take care oneself. Let God take care of everyone!!!!


    Immutable, etc.

    Q. How can we make a class immutable?
    A:
    Make class final (nobody can derive from it) and all the attributes(data members) private. Don't give any access methods which could change its attributes (such as setAge(int age) except constructors.See jdk String.java for sample code.

    Q. What if the constructor take a mutable object reference as parameter, or a data member is a reference to a object, is this class still mutable?
    A:
    Constructor seems opening a hole here, if we only copy a reference of an object as a data member (attribute), since the object being referred might change. However, what is the definition of immutable class? "A String object is immutable, that is, its contents never change, while an array of char has mutable elements. "
    ----quotation from JLS 10.9 I think as long as the data member (contents of the class) cannot be changed, the class is immutable. If the data member refers to something else, the change of something else does not necessary mean the class is mutable, since they are NOT contents of the class, only their references are. This is similar to the difference between aggregation and composition in UML (or OO). The object is destroyed; the composition parts disappear too. The aggregation can be still there. The immutable object can be GC-ed, but the something-else which its data member referring to can be still there. This might not be something in the mind of Java creators. Who knows? They might change their minds too. The Human Factors...A real world immutable class example: A printed book sits on a shelf of a library can reasonably be considered as an immutable class (object). It has references to White House, US. and some websites. The references in the book will never change, but the president sitting there and the contents of the websites will constantly change, as we all know...

    Q. If you really want the referred object to be the contents of the class instance (OO/UML: composition, not aggregation), what to do?
    A:
    1) In C++, use objects instead object pointers as data members.2) In Java, use deep clone to make the object only be referred by this class. When the class instance is GC-ed, all its data member objects will be GC-ed too since the unique references.

    Q. Why immutable class must be final?
    A:
    If class A is not final but immutable, and then we can set class B extends A, and change the behaviour of class B. By doing this, we successfully mutated class A. Since class B ISA class A. class A is not immutable any more.In other words: class B is a mutation from class A, therefore if class A is not final, and then class A is mutable. Just like we are all mutation from ancient African. At least some scientist said so. There are some different opinions on this issue. See the following link for details. Have some fun too.
    Flaming discusion on final vs. immutableMake sure you read the above.

    Q. What are the compulsive reasons to make a class like String immutable?
    A:
    There are in fact two reasons for the immutable String and other classes. First is to lock an object from being modified. This allows you to pass the object to another part of your software without worry that your reference to it will be corrupted. The second reason is less obvious. In Java all methods, members, and class names are String. Because they are String, you cannot modify them at run time. This helps guarantee that the software has a high level of security against both hacking and corruption.Another immutable class added was BigInteger. BigInteger is very useful for creating large encryption keys.Several related questions:
    • Does immutable made String class more efficient?
      No, Java String class is most famous for its inefficiency. All major coding guidelines (including Sun's) will advise use less String class, and use StringBuffer instead. Since whenever you need do something on it, you actually need to build a new one, and put the old one for GC. String literal pooling is just a small remedy for a big disease. Read here for some of the ugliness of Java (String class included): The Java IAQ:Infrequently Answered Questions, read question 12, please. An empty new String() takes 40 bytes!!! That is why C# puts String as a value-type.
    • How about other wrapper classes such as Integer or Boolean?
      See Java.lang.reflect package, immutability of those classes is extremely critical for Java reflection to work safely and correctly.
    • Are Boolean/Integer/Long/etc. classes basic building blocks of Java Language?
      No, they are not. boolean/int/long/etc. are!! If Boolean/Integer/Long/etc. were the basic building blocks of Java language, Java would be dead by now!!! They partially contribute to the slowness of using reflection.

    JavaMail, etc.

    Q. How to use sun.net.smtp.SmtpClient to send mail?
    A:
    General to say, you'd better use JavaMail and JAF to meet your all mail needs. However, using sun.net.smtp.SmtpClient is just a simple short cut.This will work for you!
    import sun.net.smtp.SmtpClient;
    import java.io.PrintStream;
    
    public class Mail {
      public static void main (String args[]) throws Exception {
        String host = "mail.localdomain.com";   // replace localdomain with yours
        String from = "aa@bb.com";              // does not matter
        String to   = "javachina@hotmail.com";  // a real mailing address
    
        SmtpClient smtp = new SmtpClient(host);
        smtp.from(from);
        smtp.to(to);
    
        PrintStream out = smtp.startMessage();
        out.println("To: " + to);
        out.println("Subject: Hello SmtpClient");
    
        // blank line between headers and message
        out.println();  
        out.println("This is a test message.");
    
        out.flush();
        out.close();
        smtp.closeServer();
      }
    }
    

    Security, Cryptography, etc.

    Q. Why do we have so many encryption algorithms? What are the differences?
    A: A rough description:
    • If the encryption/decryption are done by the same party, symmetric algorithm is the way to go. Blowfish is a new and better symmetric encryption algorithm. DES is another one... I used Blowfish encryption; our product has just shipped to Disney.
    • RSA is for encrypting by one party and decrypting by another party. RSA or other Public/Private Key pair system (e.g. D-H Public-Key Directory) solved the famous key transportation problem. Read a very good introductory from here: Introduction To Cryptography
    • MD5, SHA or other one-way digest encryption algorithm is for encrypting password, which means you never want to decrypt it back. I used it on our project team login page for a little more than a year now...Different encryption algorithms solve different problems and are used for different purposes...
    • One thing worths mention is MD5/SHA is not secure any more, thanks the Chinese lady, great methimatician Wang Xiaoyun and her team. You can attach the MD5 encrypted password to get access to the protected database etc. It is hard, but not practically impossible any more.
    • You can find the article from here

    Q. What is salt? Why we need salt?
    A:
    Suppose you are a thief and try to get bank transmitting information pattern. You deposit $100; and then you listen to the message on line. Then you deposit another $100, and then do the same. Before long, you know the encrypted transmitting pattern of that $100, even you don't know how to decrypt it. That will make the bank venerable to be attacked by sending false information to the central database or another branch. However, if the bank adds salt before encryption, the listener/thief will not get the pattern so easily. Adding salt make imitating information much harder.

    Q. How to protect my database username/password on the server?
    A: Username/password for access database?
    Don't put them in your source code, don't put them on the server with clear text. It should be encrypted. We use encrypted jndi to do the job.. Can it be reverse engineered, yes, but very hard. When the hacker gets it, we already changed the username/password. Haha!

    Q. When we should use an obfuscator, when we should not? How to make decisions?
    A: Software safty is a complicated issue, there is no one-fit-all solutions.
    The answer is it depends...
    • Small application, mobile games, etc. Obfuscation is absolutely necessary! Otherwise, you have no way to sell your software! You are commiting suicide. You ship one out, everyone gets your source code, everybody can modify it a little bit, and says this is mine. You need not only to obfuscate the jar file, but also all resources, and all the images, even all the text. You try to play as many tricks on the software as possible. Can it be reverse engineered? Yes, it still can be. However, you waste too much time to do that, you cost more than you develop a new software by yourself.
    • Huge application, extremely complicated application, there is no need to obfuscate it. It is because reverse engineering effort costs too much, and gain almost nothing. We developed a $20M worth software in Java, majorly in math, a huge company used $0.5M for just testing it, and got all our jars. We knew they wanted to steal our source code from the very beginning. However, we let them get the jars. They wasted their money, and got nothing. This company applied for bankrupcy protection recently.
    • If your application size is in-between, not too big, not too small, make your best judgement, make your own decision.

    Q. Why do you say SHA-1 or MD5 one way encryption is no longer safe any more? Can it be reversed to original clear text?
    A: Since a new efficient algorithm is developed to crack them by by a Chinese Lady Dr. Xiaoyuan Wang and her team early 2005.
    See here: http://www.systemexperts.com/tutors/CryptographicHashUpdate.pdf.
    • Should I still use SHA-1 or MD5 to encrypt my password. Answer is yes until you find a better way. It is much safer than clear text.
    • Can it be reversed to original clear text? No, it is theoreticall impossible. Why?
      1. Any data can be encrypted to MD5, the set of original data is infinite large set.
      2. MD5 can be only 128 bits, or you make it even bigger, it is still a limited set.
      3. Therefore, different data can be encrypted to the same encryption.
      4. The crack is actually creating a data which will encrypted to the same value.

    Zip, Unzip, etc.

    Q. How to use java.util.zip package to upzip file?
    A: You can use the following code snippet:
    // to upzip
      File file = new File(zipfilename);
      ZipFile zipFile = new ZipFile(file);
      Enumeration enum = zipFile.entries();
      byte [] buf = new byte[1024];
      while (enum.hasMoreElements()){
        ZipEntry zipEntry  = (ZipEntry) enum.nextElement();
        // loop through each one
        // you work out the rest
      }               
    

    JDBC, etc.

    Q. How can I get the record count from the return ResultSet?
    A:
    You can't, unless you go through it. This is because ResultSet is not a container class. If you use VC++/VB CRecordSet/RecordSet class, the answer would be exact the same. They don't load all the data from database for you, but load data for you when you need it. From functional point of view, it is more like an iterator with DB access.

    Tutorials

    Q. How to make an executable Jar file?

    Q. Obfuscator FAQ

    Q. How to make your first JSP page work on Tomcat?

    Memory Leaks, GC, etc

    Q. What do you mean Java has mem-leak, why is it different than C++ mem-leak?
    A:
    In c/c++, memory leak is "programmer forgets to de-allocate memory", since c/c++ does not have Garbage Collection (GC).

    Java does not have c/c++ meaning of memory leak, since GC.However, Java does have its own meaning of memory leak, which is memory use growing with loitering objects. In other words, programmer keeps more object references than they needed.

    /*
     * an example in C++ 
     */
    void method1()
    {
      Object *p = new Object();
    
      // a lot of code here
    
      //if you forgot this delete line, mem-leak happens
      delete p;
    }
    
    /**
      * an example in Java 
      */
    void method3()
    {
      Object o = new Object();
    
      // a lot of code here, but don't attach or return o to some other place
    
      //it will not cause mem-leak if you don't put this line, 
      //since GC will do it for you
    
      o = null; // not necessary, but nice to have
    }
    
    
    /**
      * another example in Java 
      */
    void method3(AnotherObject ao)
    {
      Object o = new Object();
    
      // a lot of code here
      ao.afield = o;
      // a lot of code here too
    
      //it will cause mem-leak if you don't put this line, 
      // even after the above process, object o is never been used again
      //since GC will not do it for you. ao keeps o's reference, 
      //if you call this function many times with diferent ao, 
      // you will get OutOfMemoryException.
    
      o = null; // necessary now
    }
    

    Computer Algorithms

    Q. I have 2 large arrays of objects, what is more efficient algorithm to know they contain the exact same members other than the nested loop comparison?
    A:
    1) first thing, compare length, if not equal, gone!
    2) Make copy of each, O(n)
    3) Sort both copy, O(n * lg n)
    4) Compare each pair O(n)
    Over all O(n * lg n)It is much better than nested loop, which is O(n*n). If the n = 13,000,000,000, use your calculator, you will see huge speed difference. Of course, if n = 130, the nested loop algorithm is simple and better. Since the time saving on computing does not worth the programming effort and the overhead of the complicated algorithms.How to compare two Objects? Define a java.util.Comparator for the object you want to compare, and then the algorithm would be the same.Since speed is the major concern, do not use Vector, use array instead, according to some research; Vector is at least 3 times slower than straight array.Here is an example of how to use Comparator:
    http://www.geocities.com/developergrp/Code/SortBy.htm

    Q. My JTree is too slow, it traverses some large directory tree. Should I use DFS or BFS?
    A:
    Terminology explanation first
    • DFS: Depth First Search algorithm for traversal a graph. Recursion and stack are used to do the job.
    • BFS: Breadth First Search algorithm for traversal a graph. Using queue instead of stack.
    • Tree is a special graph, a non-cyclic direct graph.
    Which algorithm should used for traversal a directory tree, which is used for GUI by using JTree?
    • You should not traverse the directory tree at all. What you only need is to display the top-level nodes and find out which directory is non-empty. If it is not empty, put a dummy node under it, to make that node display correctly. When user clicks it, load the real data on as-leaded bases.
    • This is called Proxy Design Pattern; it saves your time and resources. Read GoF's book for details.
    • I used working on millions history records tree in VC++. Should I traverse the entire tree, no matter DFS or BFS, my program would die, and I would have been fired. I used Proxy pattern, even I did not know the pattern name then. Open folder on demand. When user close a folder, I need to unload some tree nodes by choosing Least Recent Used (LRU) nodes and use a dummy nodes again to save system resources and memory. Never use Depth First Search (DFS) in GUI tree, please!

    Q. Recursion and overflow discusion: Why the two almost identical code work differently?
    class TestRecursion{
      public static void main(String args[]){
        System.out.println(sum2(8000)); //OK
        System.out.println(sum1(8000)); //Stack Overflow
      }
    
      static long sum1(long a) {
        if (a == 1) 
          return 1;
        return a + sum1(a - 1);
      }
    
      static long sum2(long a) {
        if (a == 1) 
          return 1;
        return sum2(a - 1) + a; 
      }
    }
    
    A: This was a question raised by a member of cjsdn
    This is a real excellent example for teach recursion and stack overflow.

    What I did?

    1. Modified the code a little bit, I tried to make it more brief and symmetric. That is the code above.
    2. Compiled it and see the output error, reduced the recursion number to see the error disappeared. This proved the code is correct, but has problems.
    3. I used javap -c TestRecursion to disassembled the code. Saved the assembly code for sum1 and sum2 in 2 files.
    4. I used examdiff software to compare the assembly code of the two functions, and see the difference. The different parts are high-lighted with red lines in the following picture.
    5. Now, it is obvious what is wrong with sum1, since it put "a + ", it causes the int "a" is stored on the stack, which take memory. One int is almost nothing, but 8000 int(s) are enough to bring stack overflow much sooner than sum2, which add "a" after recursive calls of sum2.
    6. hat is it!!!
    Here is the javap disassembely out put text.
    javap -c TestRecursion
    Compiled from "TestRecursion.java"
    class TestRecursion extends java.lang.Object{
    TestRecursion();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   ldc2_w  #3; //long 8000l
       6:   invokestatic    #5; //Method sum2:(J)J
       9:   invokevirtual   #6; //Method java/io/PrintStream.println:(J)V
       12:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       15:  ldc2_w  #3; //long 8000l
       18:  invokestatic    #7; //Method sum1:(J)J
       21:  invokevirtual   #6; //Method java/io/PrintStream.println:(J)V
       24:  return
    
    static long sum1(long);
      Code:
       0:   lload_0
       1:   lconst_1
       2:   lcmp
       3:   ifne    8
       6:   lconst_1
       7:   lreturn
       8:   lload_0
       9:   lload_0
       10:  lconst_1
       11:  lsub
       12:  invokestatic    #7; //Method sum1:(J)J
       15:  ladd
       16:  lreturn
    
    static long sum2(long);
      Code:
       0:   lload_0
       1:   lconst_1
       2:   lcmp
       3:   ifne    8
       6:   lconst_1
       7:   lreturn
       8:   lload_0
       9:   lconst_1
       10:  lsub
       11:  invokestatic    #5; //Method sum2:(J)J
       14:  lload_0
       15:  ladd
       16:  lreturn
    
    Here is the examdiff screen shot. Please pay attention to the underlined difference..

    Q. What is the usage and algorithm of a HashTable?
    A: A quick lesson for HashTable etc.
    The discussion here is not Java specific, but also applies to Java. A HashTable are a mechanism to store all potential objects. The hashCode is the key to decide where to store it or to pick it up. If you have a mechanism to easily calculate the hashCode for each object, you can store and find or search the object close to O(1) time. That is much better than binary search in O(log(n)) time. However, since potential number of different objects is infinitely large, the HashTable cannot be infinitely large to make each possible hashCode has a storage cell for it. Different objects have the same hashCode is not only unavoidable, but also necessary for real storage problem. That is called collision. How to solve collision problem?
    • Rehash, recalculate the hashCode according to certain rule, and store it in the new location. If the new location has also occupied by another object, rehash again?
    • Make each storage unit has a grow-able bucket (linked-list, black-red tree, etc.). If you find the first one is not what you want, use equals() to compare to the next...
    • ...
    The collision resolving mechanism makes the searching time a little bigger than O(1):
    • O(average rehashing number)
    • O(average bucket size) for linked-list
    • O(log(average bucket size)) for black-red tree or other binary search tree
    It is very good for search intensive applications, such as compiler or Internet search engine, etc.. Java makes the hashCode build into each object itself. Good or bad? I think both. The good side makes our code simpler. The bad side makes each object unnecessarily bigger. It also makes some of our programmers not understand the basic data structure any more.Why do you think hashCode make Java object unnecessarily bigger?
    Since any Java class directly or indirectly extends Object, it does inherit the extra size of hashCode. You have no way to avoid it, no matter you need it or not. That is my point.

    Q. An SelectionSort code
    public class SelectionSort{
      public static void sort(int[] a){
        int temp;
        int j = 0;
        int minIx = 0;
        for (int i = 0; i < a.length; i++){
          minIx = i;
          for(j = i+1; j < a.length; j++) {
            if (a[minIx] > a[j]) {
              minIx = j;
            }
          }
          temp = a[minIx];
          a[minIx] = a[i];
          a[i] = temp;
        }
      }
      public static void printArray(int[] a){
        for(int i=0; i < a.length; i++){
          System.out.print(a[i]);
          if (i < a.length-1) {
            System.out.print(", ");
          }
          else {
            System.out.println();
          }
            
        }
      }
      public static void main(String[] args){
        int[] a = {10, 35, 8, 6, 8, 89, 76, 76, 4, 90, 78};
        sort(a);
        printArray(a);
      }
    }
    

    Java and multi-platforms


    Q. Can I develop Java application on Windows, and deply it on unix? If yes, how??
    A: Answer is yes, Java is platform independent.
    There are no differences in tomcat, ant, and many other pure java programs. If you don't download the exe file, but zip or tar.gz. You can use them on windows or unix or others.

    I used to work in a place, our jars could build on windows or unix, and deployed to HP-UX, solaris, windows, or linux. The things I needed to take care were:

    1. Our native build, you all know, c/c++ code are platform dependent.
    2. Our batch files needed to have a Unix shell script version. See ant/tomcat bin directory for practical examples.
    3. Environment variable settings needed to be adjusted in each individual machine, let alone platforms. of cource!

    Q. Can I put unix operating system on Windows?
    A: Yes, use cygwin!
    It is a gnu software, and it is great!

    Q. How to download and install cygwin?
    A: Here are some tips.
    1. Choose a nearest mirror to download, it is an entire unix operating system, it is huge.
    2. Do not install at the same time as download.
    3. Use default option first, you can add on later when you need.
    4. Do keep your download directory carefully, do not change/delete the weird directory name!!! This will save you huge amount of time when you need add-ons.
    5. cygwin home page

    Miscellaneous

    Q. Can we dynamically set classpath when JVM is running?
    A: No, you cannot!
    You can use System.setProperty("java.class.path", "yourNewClassPath"); to set it, and even use System.out.println(System.getProperty("java.class.path")); to read it back. However, JVM will ignore them all together. After JVM started, the classpath cannot be changed, period.Then, how can I load classes not on my classpath? Try to use URLClassLoader to do the job. However, that is another big and important topic, which worth writing a chapter for it. There are many pitfalls and gotchas there, read Dr. Ted Neward's white pappers here When a static not a static?

    Q. Is it possible to get environmental variables from Java?
    A:
    It is hard, but possible.Jakarta ant has a task, which has a static method can get environment variables.
    org.apache.tools.ant.taskdefs.Execute
    
    static java.util.Vector getProcEnvironment() 
    //Find the list of environment variables for this process.
    
    You can either use it, or learn from it, since it is open source.

    Q. How to avoid and fixed memory leaks in Java?
    A:
    Unlike C++, programmers are responsible to deal with the alllocation of the memory. If programmer forgets to do that, the tools detect the memory leak and report it. The job is easier for the tools.

    In java, programmers usually think the GC is responsible to deal with the alllocation of the memory. Officially, Java should not have memory leak. However, it is far from the truth. Java memory leak is actually unintentional retain of object references, which means the object is no longer needed, but still be referred somewhere. This kind of memory leak is much harder to detect.

    Read here, it is the CTO of a tool JProbe: http://industry.java.sun.com/javaone/99/event/0,1768,618,00.html

    What we can do? From my experience, we can do the followings:

    1. Recycle huge objects, do your own memory management. Pooling is one way to do it. Using an arrays to recycle them is another simple way, create new one only when the recycling array is empty. I used to do this in c around the x286 time. />
    2. When an object is not in use any more, explicitly set it to null. But this will depend on the conscious of your programmers.
    3. When you use tools (like JProbe or the BoundsChecker in the old days). Find the area which uses memory most, and refactor (redesign/code) that part.

    Q. If a table in a database contents a large amount of rows, which is over the capacity of the client computer's memory, how can I do to list all these rows in my application?
    A:
    This question is actually beyond the scope of JDBC, but a good design one. Partition them, put them in different folders (such as JTree). Using Proxy design pattern, and fake (surrogate) nodes to represent them. Load on demand (user wants to see a specific folder). Collapse the folder using strategies like LRU (Least Recent Used). Etc. etc. There are many ways to handle this. What to use depends on the specifics of your application. Just a few hints, which might help you think. You might invent a new way to do it too. Be creative!

    Q. Why I found that something in Java is not perfect, some are not very object oriented, etc, etc?
    A:
    You are right; Java is not or far from perfect!Why? Language laws are not laws of physics. Human thinking processes are not always optimized. A lot of things in languages (Java included) may have very good reasons, and a lot of them may be just opposite.Here is a question: Why "ea" in HEAVY and "ea" in REASON sound very different in English?Don't spend a lot of time on these kinds of research. Sometimes, the answer is "No answer" or "Unknown human factors". See The Java IAQ:Infrequently Answered Questions. by Dr. NorvigI'm a Java advocator, but you will find some ugly part of Java there. Java is not perfect, neither are any other computer languages. Future languages (such as ChineseTea or Bankok are included!IMHO: Just find the quotation (facts in Java) from JLS, and then end of the discussion!

    Q. What are the differences between aggregation and association? Can you give a clear-cut Java example?
    A: Aggregation and association are a PARTSOF or HASA relationship between objects, they are two forms of composition. Aggregation is a strong form of Composition.
    Examples: Engine is a part of a car. Book has several chapters and many references. Aggregation usually refers to the relationship in which the whole dies; the parts die too. When a book is destroyed, the chapters of the book are also physically destroyed. However, the other books, articles, websites referred by the book are not going to be destroyed. And you know that.The differences between aggregation and association are more OO concepts/design differences than clear-cut code differences. Especially in Java, since all objects are allocated in heap, almost you always have a way to survive the parts if you twist your code a little. However, in C++, there is a clear-cut code difference. I just use the book/chapters/references relationship as the example here. In the following code, the 2 chapters will be destroyed when the book destructor is called no matter how you twist your code. The references will not be affected.
    class Book {   
      private:      
        Chapter chapter1, chapter2;      
        Reference *pref1, *pref2;   
      public:      
        Book();      
        virtual ~Book();       
        void setReferences(Reference* pRef1, Reference* pRef2);   
        // other stuff      
    }       
    

    Q. How to get sizeof() in Java?
    A: You cannot get an accurate size of object in Java.
    There is no way to accurately measure the size of object in Java as C sizeof() method. I guess that is intentional to hide some poor memory management problem in Java. Another thing is different JVM can have different implementation as well as different sizes. Read here to know a little more, a little old, but still useful: The Java IAQ:Infrequently Answered QuestionsHowever, you can do estimation, such as write an object or 100 object to a file, use the file size to estimate the size of the object.

    Q. How to launch a browser with specified html file in windows environment?
    A:
    Here is the code:
    Runtime rt = Runtime.getRuntime();
    Process ps = rt.exec("cmd /c \"start " +  htmlfname + "\"");
    
    Q. Is Java definitly slower than C++?
    A:
    Have you investigated, researched, compared, and then concluded Java is a lot slower?

    From my practice and compare with VC++. When number of iterations is low, VC++ can be faster than Java. The problem to solve was SLDP 1+1 algorithm on a huge telephone network 610ms vs. 1085ms (Java). Please do not think it is a simple problem, believe me or not, the code written beofre me by someone else needed to run more than 12 hours. It is the power of a good algorithm!!!

    When my code became much more complicated and number of iterations increases huge, Java can be much faster than VC++, 26s vs. 12s (Java). Both code uses the same algorithm, written by the same programmer, and I was much more proficient on VC++ than Java then, run on the same machine, and solve the same real world problem ( a huge telephone company network surviving and optimization 1 + 1 problem, including new optical line recommendation).

    You might be wondering, why I wrote them twice in 2 different languages. That was a long story, and I'd better not to post it here.

    For scientific calculation, the general opinion on speed seems:

    Fortran > C > C++ > Java

    However, on high iteration case, Java can be faster than C++.

    Java > C++

    JIT or HotSpot plays a beautiful role here.


    Q. A simple shellscript for search directory tree
    A:
    Since Microsoft intentional disabled window explorer's good search capability since XP, we need something like this. However, you need to install cygwin first.
      #!/bin/bash -x
      searchfor=$1
      for line in `find . -name "*.java"`
      do
        grep -n -H $searchfor $line
      done
    

    Q. Can you give simple example on Java reflection API?
    A: Yes, here you are!
    import java.lang.reflect.Method;
    import java.lang.reflect.Field;
    class A {     
      public static final String staticField = "this is the value of the staticField"; 
      public String instanceField = "this is the value of the instanceField"; 
      public static int aStaticMethod() {
        return 3; 
      } 
      public int aInstanceMethod() {
        return 4; 
      } 
      public int aInstanceMethodWithParams(int a, int b) {
        return a+b; 
      } 
    }
    
    public class ReflectionDemo {
      public static void main(String[] args) {
        try {
          // Get Class object
          Class cls = Class.forName("org.javachina.ex1.A");
     
          // Get Fields
          Field sfld1 = cls.getField("staticField");      
          Field ifld2 = cls.getField("instanceField");      
          System.out.println(sfld1);    
          System.out.println(ifld2); 
    
          // Get Filed's values
          System.out.println(sfld1.get(null));    
          System.out.println(ifld2.get(new A()));    
       
          // Get Methods
          System.out.println(cls.getMethod("aStaticMethod", null));    
          System.out.println(cls.getMethod("aInstanceMethod", null));    
          Class[] ary = new Class[]{int.class, int.class};
          System.out.println(cls.getMethod("aInstanceMethodWithParams", ary));
    
          // Get all declared Methods
          Method[] mary = cls.getDeclaredMethods();
          for (int i=0; i<mary.length; i++) {
            System.out.println("here: " + mary[i]);    
          }
        }
        catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
        catch (NoSuchFieldException e) {
          e.printStackTrace();
        }
        catch (IllegalAccessException e) {
          e.printStackTrace();
        }
        catch (NoSuchMethodException e) {
          e.printStackTrace();
        }
      }
    }
    

    Q. How to get IP address from hostname?
    A: Simple, see the following code.
    import java.net.*;
    public class HostToIP {    
      public static String fromHostToIP(String hostname) {        
        String ipStr = "";        
        try {            
          InetAddress addr = InetAddress.getByName(hostname);            
          byte[] ipAddr = addr.getAddress();            
          for (int i = 0; i < ipAddr.length; i++) {                
            if (i > 0) {                    
              ipStr += ".";                
            }                
            ipStr += ipAddr[i] & 0xFF;            
          }        
        } 
        catch (UnknownHostException e) {        
          e.printStackTrace();
        }        
        return ipStr;    
      } 
      public static void main(String[] args) {
        String hostName = "webappcabaret.net";
        if (args.length > 0 && args[0].trim().length() > 0) {
          hostName = args[0];
        }
        System.out.println(HostToIP.fromHostToIP(hostName));    
      }
    }