java vs - What is the difference between Tomcat, JBoss and Glassfish?




performance weblogic (8)

I am starting to look into Enterprise Java and the book I am following mentions that it will use JBoss. Netbeans ships with Glassfish. I have used Tomcat in the past.

What are the differences between these three programs?


Answers

JBoss and Glassfish are basically full Java EE Application Server whereas Tomcat is only a Servlet container. The main difference between JBoss, Glassfish but also WebSphere, WebLogic and so on respect to Tomcat but also Jetty, was in the functionality that an full app server offer. When you had a full stack Java EE app server you can benefit of all the implementation of the vendor of your choice, and you can benefit of EJB, JTA, CDI(JAVA EE 6+), JPA, JSF, JSP/Servlet of course and so on. With Tomcat on the other hands you can benefit only of JSP/Servlet. However to day with advanced Framework such as Spring and Guice, many of the main advantage of using an a full stack application server can be mitigate, and with the assumption of a one of this framework manly with Spring Ecosystem, you can benefit of many sub project that in the my work experience let me to left the use of a full stack app server in favour of lightweight app server like tomcat.


Tomcat is just a servlet container, i.e. it implements only the servlets and JSP specification. Glassfish and JBoss are full Java EE servers (including stuff like EJB, JMS, ...), with Glassfish being the reference implementation of the latest Java EE 6 stack, but JBoss in 2010 was not fully supporting it yet.


jboss and glassfish include a servlet container(like tomcat), however the two application servers (jboss and glassfish) also provide a bean container (and a few other things aswell I imagine)


Both JBoss and Tomcat are Java servlet application servers, but JBoss is a whole lot more. The substantial difference between the two is that JBoss provides a full Java Enterprise Edition (Java EE) stack, including Enterprise JavaBeans and many other technologies that are useful for developers working on enterprise Java applications.

Tomcat is much more limited. One way to think of it is that JBoss is a Java EE stack that includes a servlet container and web server, whereas Tomcat, for the most part, is a servlet container and web server.


You should use GlassFish for Java EE enterprise applications. Some things to consider:

A web Server means: Handling HTTP requests (usually from browsers).

A Servlet Container (e.g. Tomcat) means: It can handle servlets & JSP.

An Application Server (e.g. GlassFish) means: *It can manage Java EE applications (usually both servlet/JSP and EJBs).


Tomcat - is run by Apache community - Open source and has two flavors Tomcat - Web profile - light weight which is only servlet container and does not support Java EE features like EJB, JMS etc. Tomcat EE - This is a certified Java EE container, this supports all Java EE technologies.

No commercial support available (only community support)

JBoss - Run by RedHat This is a full stack support for JavaEE and it is a certified Java EE container. This includes Tomcat as web container internally. This also has two flavors Community version called Application Server (AS) - this will have only community support Enterprise Application Server ( EAP) - For this, you can have subscription based license (It's based on number of Cores you have on your servers.)

Glassfish - Run by Oracle This is also a full stack certified Java EE Container. This has its own web container (not Tomcat). This comes from Oracle itself,so all new specs will be tested and implemented with Glassfish first. So, always it would support the latest spec. I am not aware of its support models.


It seems a bit discouraging to use Tomcat when you read these answers. However what most fail to mention is that you can get to identical or almost identical use cases with tomcat but that requires you to add the libraries needed (through Maven or whatever include system you use).

I have been running tomcat with JPA, EJBs with very small configuration efforts.


Apache tomcat is just an only serverlet container it does not support for Enterprise Java application(JEE). JBoss and Glassfish are supporting for JEE application but Glassfish much heavy than JBOSS server : Reference Slide


A Collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data. A collections framework W is a unified architecture for representing and manipulating collections.

The HashMap JDK1.2 and Hashtable JDK1.0, both are used to represent a group of objects that are represented in <Key, Value> pair. Each <Key, Value> pair is called Entry object. The collection of Entries is referred by the object of HashMap and Hashtable. Keys in a collection must be unique or distinctive. [as they are used to retrieve a mapped value a particular key. values in a collection can be duplicated.]


« Superclass, Legacy and Collection Framework member

Hashtable is a legacy class introduced in JDK1.0, which is a subclass of Dictionary class. From JDK1.2 Hashtable is re-engineered to implement the Map interface to make a member of collection framework. HashMap is a member of Java Collection Framework right from the beginning of its introduction in JDK1.2. HashMap is the subclass of the AbstractMap class.

public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }

« Initial capacity and Load factor

The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. Note that the hash table is open: in the case of a "hashcollision", a single bucket stores multiple entries, which must be searched sequentially. The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased.

HashMap constructs an empty hash table with the default initial capacity (16) and the default load factor (0.75). Where as Hashtable constructs empty hashtable with a default initial capacity (11) and load factor/fill ratio (0.75).

« Structural modification in case of hash collision

HashMap, Hashtable in case of hash collisions they store the map entries in linked lists. From Java8 for HashMap if hash bucket grows beyond a certain threshold, that bucket will switch from linked list of entries to a balanced tree. which improve worst-case performance from O(n) to O(log n). While converting the list to binary tree, hashcode is used as a branching variable. If there are two different hashcodes in the same bucket, one is considered bigger and goes to the right of the tree and other one to the left. But when both the hashcodes are equal, HashMap assumes that the keys are comparable, and compares the key to determine the direction so that some order can be maintained. It is a good practice to make the keys of HashMap comparable. On adding entries if bucket size reaches TREEIFY_THRESHOLD = 8 convert linked list of entries to a balanced tree, on removing entries less than TREEIFY_THRESHOLD and at most UNTREEIFY_THRESHOLD = 6 will reconvert balanced tree to linked list of entries. Java 8 SRC, stackpost

« Collection-view iteration, Fail-Fast and Fail-Safe

    +--------------------+-----------+-------------+
    |                    | Iterator  | Enumeration |
    +--------------------+-----------+-------------+
    | Hashtable          | fail-fast |    safe     |
    +--------------------+-----------+-------------+
    | HashMap            | fail-fast | fail-fast   |
    +--------------------+-----------+-------------+
    | ConcurrentHashMap  |   safe    |   safe      |
    +--------------------+-----------+-------------+

Iterator is a fail-fast in nature. i.e it throws ConcurrentModificationException if a collection is modified while iterating other than it’s own remove() method. Where as Enumeration is fail-safe in nature. It doesn’t throw any exceptions if a collection is modified while iterating.

According to Java API Docs, Iterator is always preferred over the Enumeration.

NOTE: The functionality of Enumeration interface is duplicated by the Iterator interface. In addition, Iterator adds an optional remove operation, and has shorter method names. New implementations should consider using Iterator in preference to Enumeration.

In Java 5 introduced ConcurrentMap Interface: ConcurrentHashMap - a highly concurrent, high-performance ConcurrentMap implementation backed by a hash table. This implementation never blocks when performing retrievals and allows the client to select the concurrency level for updates. It is intended as a drop-in replacement for Hashtable: in addition to implementing ConcurrentMap, it supports all of the "legacy" methods peculiar to Hashtable.

  • Each HashMapEntrys value is volatile thereby ensuring fine grain consistency for contended modifications and subsequent reads; each read reflects the most recently completed update

  • Iterators and Enumerations are Fail Safe - reflecting the state at some point since the creation of iterator/enumeration; this allows for simultaneous reads and modifications at the cost of reduced consistency. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.

  • Like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value.

public static void main(String[] args) {

    //HashMap<String, Integer> hash = new HashMap<String, Integer>();
    Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
    //ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();

    new Thread() {
        @Override public void run() {
            try {
                for (int i = 10; i < 20; i++) {
                    sleepThread(1);
                    System.out.println("T1 :- Key"+i);
                    hash.put("Key"+i, i);
                }
                System.out.println( System.identityHashCode( hash ) );
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }.start();
    new Thread() {
        @Override public void run() {
            try {
                sleepThread(5);
                // ConcurrentHashMap  traverse using Iterator, Enumeration is Fail-Safe.

                // Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
                for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
                    sleepThread(1);
                    System.out.println("T2 : "+ e.nextElement());
                }

                // HashMap traverse using Iterator, Enumeration is Fail-Fast.
                /*
                for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
                    sleepThread(1);
                    System.out.println("T2 : "+ it.next());
                    // ConcurrentModificationException at java.util.Hashtable$Enumerator.next
                }
                */

                /*
                Set< Entry<String, Integer> > entrySet = hash.entrySet();
                Iterator< Entry<String, Integer> > it = entrySet.iterator();
                Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
                while( entryEnumeration.hasMoreElements() ) {
                    sleepThread(1);
                    Entry<String, Integer> nextElement = entryEnumeration.nextElement();
                    System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
                    //java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
                    //                                          at java.util.HashMap$EntryIterator.next
                    //                                          at java.util.Collections$3.nextElement
                }
                */
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }.start();

    Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
    try {
        unmodifiableMap.put("key4", "unmodifiableMap");
    } catch (java.lang.UnsupportedOperationException e) {
        System.err.println("UnsupportedOperationException : "+ e.getMessage() );
    }
}
static void sleepThread( int sec ) {
    try {
        Thread.sleep( 1000 * sec );
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

« Null Keys And Null Values

HashMap allows maximum one null key and any number of null values. Where as Hashtable doesn’t allow even a single null key and null value, if the key or value null is then it throws NullPointerException. Example

« Synchronized, Thread Safe

Hashtable is internally synchronized. Therefore, it is very much safe to use Hashtable in multi threaded applications. Where as HashMap is not internally synchronized. Therefore, it is not safe to use HashMap in multi threaded applications without external synchronization. You can externally synchronize HashMap using Collections.synchronizedMap() method.

« Performance

As Hashtable is internally synchronized, this makes Hashtable slightly slower than the HashMap.


@See





java tomcat jboss glassfish enterprise