Welcome to the Java Blog, written by me with the sole purpose of talking about Java & Web technologies. I'm aiming this blog at other Java developers with the deeper aspects of writing code and resolving technical issues. Hopefully I can blog about some really interesting topics as I come across them. Mr. Patricia Seybold said, "If you learn to program in Java, you’ll never be without a job!"
Thursday, February 26, 2009
Java Collections
The Collections API is a set of classes and interfaces that support operations on collections of objects.
Example of classes: HashSet, HashMap, ArrayList, LinkedList, TreeSet and TreeMap.
Example of interfaces: Collection, Set, List and Map.
DIFFERENCE : Iterator and ListIterator
Iterator : Enables you to cycle through a collection in the forward direction only, for obtaining or removing elements
ListIterator : It extends Iterator, allow bidirectional traversal of list and the modification of elements
DIFFERENCE : HashMap and HashTable
1. The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn’t allow nulls).
2. HashMap does not guarantee that the order of the map will remain constant over time.
3. HashMap is non synchronized whereas Hashtable is synchronized.
4. Iterator in the HashMap is fail-safe while the enumerator for the Hashtable isn't.
DIFFERENCE : Set and list
A Set stores elements in an unordered way and does not contain duplicate elements, whereas a list stores elements in an ordered way but may contain duplicate elements.
DIFFERENCE : Vector and ArrayList
Vector is synchronized whereas ArrayList is not. The Vector class provides the capability to implement a growable array of objects. ArrayList and Vector class both implement the List interface. Both classes are implemented using dynamically resizable arrays, providing fast random access and fast traversal. In vector the data is retrieved using the elementAt() method while in ArrayList, it is done using the get() method. ArrayList has no default size while vector has a default size of 10. when you want programs to run in multithreading environment then use concept of vector because it is synchronized. But ArrayList is not synchronized so, avoid use of it in a multithreading environment.
DIFFERENCE : Array and Arraylist
An ArrayList is resizable, where as, an array is not. ArrayList is a part of the Collection Framework. We can store any type of objects, and we can deal with only objects. It is growable. Array is collection of similar data items. We can have array of primitives or objects. It is of fixed size. We can have multi dimensional arrays.
DIFFERENCE : Enumeration and Iterator
The functionality of Enumeration interface is duplicated by the Iterator interface. Iterator has a remove() method while Enumeration doesn't. Enumeration acts as Read-only interface, because it has the methods only to traverse and fetch the objects, where as using Iterator we can manipulate the objects also like adding and removing the objects.So Enumeration is used when ever we want to make Collection objects as Read-only.
DIFFERENCE : Enumeration, ArrayList, Hashtable and Collections and Collection
Enumeration: It is series of elements. It can be use to enumerate through the elements of a vector, keys or values of a hashtable. You can not remove elements from Enumeration.
ArrayList: It is re-sizable array implementation. Belongs to 'List' group in collection. It permits all elements, including null. It is not thread -safe.
Hashtable: It maps key to value. You can use non-null value for key or value. It is part of group Map in collection.
Collections: It implements Polymorphic algorithms which operate on collections.
Collection: It is the root interface in the collection hierarchy.
HOW : Make hashmap synchronized
Note on Some Important Terms
1) Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a hashtable will have to acquire a lock on the object while others will wait for lock to be released.
2) Fail-safe is relevant from the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object "structurally”, a concurrent modification exception will be thrown. It is possible for other threads though to invoke "set" method since it doesn’t modify the collection "structurally”. However, if prior to calling "set", the collection has been modified structurally, "IllegalArgumentException" will be thrown.
HashMap can be synchronized by
Map m = Collections.synchronizeMap(hashMap);
Java Garbage Collection
In Java, it is good idea to explicitly assign null into a variable when no more in use. In Java on calling System.gc() and Runtime.gc(), JVM tries to recycle the unused objects, but there is no guarantee when all the objects will garbage collected. Garbage collection is an automatic process and can't be forced. There is no guarantee that Garbage collection will start immediately upon request of System.gc(). Once an object is garbage collected, It can no longer become reachable again.
Garbage collection does not guarantee that a program will not run out of memory. It is possible for programs to use up memory resources faster than they are garbage collected. It is also possible for programs to create objects that are not subject to garbage collection.
Java Abstract Class
1. Abstract class is a class which contain one or more abstract methods, which has to be implemented by sub classes. An abstract class can contain no abstract methods also i.e. abstract class may contain concrete methods. A Java Interface can contain only method declarations and public static final constants and doesn't contain their implementation. The classes which implement the Interface must provide the method definition for all the methods present.
2. Abstract class definition begins with the keyword "abstract" keyword followed by Class definition. An Interface definition begins with the keyword "interface".
3. Abstract classes are useful in a situation when some general methods should be implemented and specialization behavior should be implemented by subclasses. Interfaces are useful in a situation when all its properties need to be implemented by subclasses
4. All variables in an Interface are by default - public static final while an abstract class can have instance variables.
5. An interface is also used in situations when a class needs to extend an other class apart from the abstract class. In such situations its not possible to have multiple inheritance of classes. An interface on the other hand can be used when it is required to implement one or more interfaces. Abstract class does not support Multiple Inheritance whereas an Interface supports multiple Inheritance.
6. An Interface can only have public members whereas an abstract class can contain private as well as protected members.
7. A class implementing an interface must implement all of the methods defined in the interface, while a class extending an abstract class need not implement any of the methods defined in the abstract class.
8. The problem with an interface is, if you want to add a new feature (method) in its contract, then you MUST implement those method in all of the classes which implement that interface. However, in the case of an abstract class, the method can be simply implemented in the abstract class and the same can be called by its subclass
9. Interfaces are slow as it requires extra indirection to to find corresponding method in in the actual class. Abstract classes are fast
10.Interfaces are often used to describe the peripheral abilities of a class, and not its central identity, E.g. an Automobile class might
implement the Recyclable interface, which could apply to many otherwise totally unrelated objects.
Note: There is no difference between a fully abstract class (all methods declared as abstract and all fields are public static final) and an interface.
Note: If the various objects are all of-a-kind, and share a common state and behavior, then tend towards a common base class. If all they
share is a set of method signatures, then tend towards an interface.
Similarities:
Neither Abstract classes nor Interface can be instantiated.
Wednesday, February 25, 2009
Installing SSL Certificate on Java Based Web Servers
<%JAVA_HOME%>/bin/keytool -import -trustcacerts -alias
Use the same process for the site certificate using the keytool command, if you are using an alias then please include the alias command in the string. Example:
<%JAVA_HOME%>/bin/keytool -import -trustcacerts -alias yyy -file yahoo.cer -keystore [domain.key/cacerts.jks/...]
Certificate keystore file name may vary from server to server.
The password is then requested.
EXAMPLE BELOW :
Enter keystore password: (This is the one used during CSR creation)
The following information will be displayed about the certificate and you will be asked if you want to trust it (the default is no so type 'y' or 'yes'):
Owner: CN= Root, O=Root, C=US
Issuer: CN=Root, O=Root, C=US
Serial number: 111111111111
Valid from: Fri JAN 01 23:01:00 GMT 1990 until: Thu JAN 01 23:59:00 GMT 2050
Certificate fingerprints:
MD5: D1:E7:F0:B2:A3:C5:7D:61:67:F0:04:CD:43:D3:BA:58
SHA1: B6:GE:DE:9E:4C:4E:9F:6F:D8:86:17:57:9D:D3:91:BC:65:A6:89:64
Trust this certificate? [no]:
Then an information message will display as follows:
Certificate was added to keystore
All the certificates are now loaded and the correct root certificate will be presented. Now we have to restart the web server.
Tuesday, February 24, 2009
Java Database Connection Pool Implementation
The Java Database Connect API (JDBC) is supported by all major database vendors as well as many small databases. To access a database through JDBC you first open a connection to the database, resulting in a Connection object. A Connection object represents a native database connection and provides methods for executing SQL statements. The database connection pool described in this article consists of manager class that provides an interface to multiple connection pool objects.
The database connection pool class, DBConnectionPool, provides methods to
- get an open connection from the pool,
- return a connection to the pool,
- release all resources and close all connections at shutdown.
The manager class, DBConnectionManager, is a wrapper around the DBConnectionPool class that manages multiple connection pools. It
- loads and registers all JDBC drivers,
- creates DBConnectionPool objects based on properties defined in a properties file,
- maps connection pool names to DBConnectionPool instances,
- keeps track of connection pool clients to shut down all pools gracefully when the last client is done.
The DBConnectionPool class
The DBConnectionPool class represents a pool of connections to one database. The database is identified with a JDBC URL. A JDBC URL consists of three parts: the protocol identifier, the driver identifier and the database identifier (the format is driver specific). The pool also has a name used by the clients and optionally a user name and password and a max connection limit. If you develop a web application where all users can execute some database operations but others are restricted to authorized users, you can define one pool for the general user and another pool for the restricted group using the same JDBC URL but different user names and passwords.
Constructor
The DBConnectionPool constructor takes all values described above as its parameters:
public DBConnectionPool(String name, String URL, String user,It saves all parameter values in its instance variables.
String password, int maxConn) {
this.name = name;
this.URL = URL;
this.user = user;
this.password = password;
this.maxConn = maxConn;
}
Get an open connection from the pool
The DBConnectionPool class provides two methods for checking out a connection. They both return an existing Connection if one is available, otherwise they create a new Connection. If no Connection is available and the max number of connections have been reached, the first method returns null but the other waits until an existing Connection is checked in.
public synchronized Connection getConnection() {Connection con = null;
if (freeConnections.size() > 0) {
// Pick the first Connection in the Vector
// to get round-robin usage
con = (Connection) freeConnections.firstElement();
freeConnections.removeElementAt(0);
try {
if (con.isClosed()) {
log("Removed bad connection from " + name);
// Try again recursively
con = getConnection();
}
}
catch (SQLException e) {
log("Removed bad connection from " + name);
// Try again recursively
con = getConnection();
}
}
else if (maxConn == 0 || checkedOut < con =" newConnection();">All Connection objects in the pool are kept in a Vector, named freeConnections, when they are checked in. If there is at least one Connection in the Vector getConnection() picks the first one. As you will see later, Connections are added to the end of the Vector when they are checked in so picking the first ensures an even utilization to minimize the risk that the database disconnects a connection due to inactivity.
Before returning the Connection to the client, the isClosed() method is used to verify that the connection is okay. If the connection is closed, or an exception is thrown, the method calls itself again to get another connection.
If no Connection is available in the freeConnections Vector the method checks if the max connection limit is specified, and if so, if it's been reached. A maxConn value of 0 means "no limit". If no limit has been specified or the limit has not been reached, the method tries to create a new Connection. If it's successful, it increments the counter for the number of checked out connections and returns the Connection to the client. Otherwise it returns null.
The newConnection() method is used to create a new Connection. This is a private method that creates a Connection based on if a user name and a password have been specified or not.
private Connection newConnection() {The JDBC DriverManager provides a set of getConnection() methods that takes a JDBC URL plus other parameters, for instance a user name and a password. The DriverManager uses the URL to locate a JDBC driver matching the database and opens a connection.
Connection con = null;
try {
if (user == null) {
con = DriverManager.getConnection(URL);
}
else {
con = DriverManager.getConnection(URL, user, password);
}
log("Created a new connection in pool " + name);
}
catch (SQLException e) {
log(e, "Can't create a new connection for " + URL);
return null;
}
return con;
}
The second getConnection() method takes a time-out parameter, with a value in milliseconds for how long the client is willing to wait for a connection. It's implemented as a wrapper around the first getConnection() method:
public synchronized Connection getConnection(long timeout) {The local startTime variable is initialized with the current time. A while loop first try to get a connection. If it fails, wait() is called with the the number of milliseconds we are prepared to wait. wait() returns either when another thread calls notify() or notifyAll(), as you will see later, or when the time has elapsed. To figure out if wait() returned due to a time-out or a notification, the start time is subtracted from current time and if the result is greater than the time-out value the method returns null. Otherwise getConnection() is called again.
long startTime = new Date().getTime();
Connection con;
while ((con = getConnection()) == null) {
try {
wait(timeout);
}
catch (InterruptedException e) {}
if ((new Date().getTime() - startTime) >= timeout) {
// Timeout has expired
return null;
}
}
return con;
}
Return a connection to the pool
The DBConnectionPool class also provides a method for returning a connection to the pool. The freeConnection() method takes the returned Connection object as its parameter.
public synchronized void freeConnection(Connection con) {The Connection is added to the end of the freeConnections Vector and the counter for number of checked out connections is decremented. The notifyAll() is called to notify other clients waiting for a connection.
// Put the connection at the end of the Vector
freeConnections.addElement(con);
checkedOut--;
notifyAll();
}
Shutdown
Most Servlet Engines provide some method for graceful shutdown. The database connection pools need to be notified about this event so that all connections can be closed correctly. The DBConnectionManager class is responsible for coordinating the shutdown but it's the DBConnectionPool class that closes all connections in the pool. The release() method is called by the DBConnectionManager.public synchronized void release() {This method loops through the freeConnections Vector and closes all Connections. When all Connections have been closed they are removed from the Vector.
Enumeration allConnections = freeConnections.elements();
while (allConnections.hasMoreElements()) {
Connection con = (Connection) allConnections.nextElement();
try {
con.close();
log("Closed connection for pool " + name);
}
catch (SQLException e) {
log(e, "Can't close connection for pool " + name);
}
}
freeConnections.removeAllElements();
}
The DBConnectionManager class
The DBConnectionManager class is implemented according to the Singleton pattern described in many design books. A Singleton is a class with just one instance. Other objects can get a reference to the single instance through a static method (class method).
Constructor and getInstance()
The DBConnectionManager constructor is private to prevent other objects to create instances of the class.
private DBConnectionManager() {Clients of the DBConnectionManager calls the getInstance() method to get a reference to the single instance.
init();
}
static synchronized public DBConnectionManager getInstance() {The single instance is created the first time this method is called and a reference is then kept in the static variable named instance. A counter for the number of DBConnectionManager clients is incremented before the reference is returned. This counter is later used to coordinate the shutdown of the pools.
if (instance == null) {
instance = new DBConnectionManager();
}
clients++;
return instance;
}
Initialization
The constructor calls a private method called init() to initialize the object.
private void init() {The getResourceAsStream() method is a standard method for locating an external file and open it for input. How the file is located depends on the class loader but the standard class loader for local classes searches for the file in the CLASSPATH, starting in the directory where the class file is located. The db.properties file is a file in the Properties format containing key-value pairs that define the connection pools. The following common properties can be defined:
InputStream is = getClass().getResourceAsStream("/db.properties");
Properties dbProps = new Properties();
try {
dbProps.load(is);
}
catch (Exception e) {
System.err.println("Can't read the properties file. " +
"Make sure db.properties is in the CLASSPATH");
return;
}
String logFile = dbProps.getProperty("logfile",
"DBConnectionManager.log");
try {
log = new PrintWriter(new FileWriter(logFile, true), true);
}
catch (IOException e) {
System.err.println("Can't open the log file: " + logFile);
log = new PrintWriter(System.err);
}
loadDrivers(dbProps);
createPools(dbProps);
}
drivers
A space separated list of JDBC driver class names logfile
The absolute path for a log file
Another set of properties are used for each pool. The property name starts with the name of the connection pool:
.url The JDBC URL for the database
.maxconn The max number of connections in the pool. 0 means no limit.
.user The user name for the pool
.password The corresponding password
The url property is mandatory but all the others are optional. The user name and the matching password must be valid for the database defined by the URL.
Below is an example of a db.properties file for a Windows platform, with a pool for an MySQL database.
drivers=com.mysql.jdbc.DriverNote that the backslashes (\) in a Windows path must be duplicated since a backslash in a properties file is also used as an escape character.
logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt
mysql.maxconn=100
mysql.url=jdbc:mysql://localhost:3306/test
mysql.user=root
mysql.password=root
The init() method creates a Properties object and loads the db.properties file. It then reads the logfile property. If a log file hasn't been specified a file named DBConnectionManager.log in the current directory is used instead. As a last resort, System.err is used for log messages.
The loadDrivers() method loads and registers all JDBC drivers specified by the drivers property.
private void loadDrivers(Properties props) {loadDrivers() uses a StringTokenizer to split the drivers property value into a string for each driver class name and and then loops through all class names. Each class is loaded into the JVM and an instance is created. The instance is then registered with the JDBC DriverManager and added to a private Vector. The drivers Vector is used at shutdown to deregister all drivers from the DriverManager.
String driverClasses = props.getProperty("drivers");
StringTokenizer st = new StringTokenizer(driverClasses);
while (st.hasMoreElements()) {
String driverClassName = st.nextToken().trim();
try {
Driver driver = (Driver)
Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
log("Registered JDBC driver " + driverClassName);
}
catch (Exception e) {
log("Can't register JDBC driver: " +
driverClassName + ", Exception: " + e);
}
}
}
Next the DBConnectionPool objects are created by the private createPools() method.
private void createPools(Properties props) {An Enumeration of all property names is created and scanned for property names ending with
Enumeration propNames = props.propertyNames();
while (propNames.hasMoreElements()) {
String name = (String) propNames.nextElement();
if (name.endsWith(".url")) {
String poolName = name.substring(0, name.lastIndexOf("."));
String url = props.getProperty(poolName + ".url");
if (url == null) {
log("No URL specified for " + poolName);
continue;
}
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxconn = props.getProperty(poolName + ".maxconn", "0");
int max;
try {
max = Integer.valueOf(maxconn).intValue();
}
catch (NumberFormatException e) {
log("Invalid maxconn value " + maxconn + " for " +
poolName);
max = 0;
}
DBConnectionPool pool =
new DBConnectionPool(poolName, url, user, password, max);
pools.put(poolName, pool);
log("Initialized pool " + poolName);
}
}
}
.url
. When such a property is found, the pool name is extracted, all properties for the corresponding connection pool are read and a DBConnectionPool object is created and saved in an instance variable named pools. pools is a Hashtable, using the pool name as the key and the DBConnectionPool object as the value. Get and return a connection
The DBConnectionManager provides the getConnection() and freeConnection() methods used by the clients. All of them take a pool name parameter and relay the call to the corresponding DBConnectionPool object.public Connection getConnection(String name) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
return pool.getConnection();
}
return null;
}
public Connection getConnection(String name, long time) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
return pool.getConnection(time);
}
return null;
}
public void freeConnection(String name, Connection con) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
pool.freeConnection(con);
}
}
Shutdown
Finally, the DBConnectionManager has a method called release(). This method is used for graceful shutdown of the connection pools. Each DBConnectionManager client must call the static getInstance() method to get a reference to the manager. As you could see above, a client counter variable is used in this method to keep track of the number of clients. The release() method is called by each client during shutdown and the client counter is decremented. When the last client calls release(), the DBConnectionManager calls release() on all DBConnectionPool objects to close all connections.public synchronized void release() {When all DBConnectionPool objects have been released, all JDBC drivers are deregistered.
// Wait until called by the last client
if (--clients != 0) {
return;
}
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements()) {
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while (allDrivers.hasMoreElements()) {
Driver driver = (Driver) allDrivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log("Deregistered JDBC driver " + driver.getClass().getName());
}
catch (SQLException e) {
log(e, "Can't deregister JDBC driver: " +
driver.getClass().getName());
}
}
}
Example of a Servlet using the connection pool
The Servlet API defines a Servlet's life cycle like this:- Servlet is created then initialized (the init() method).
- Zero or more service calls from clients are handled (the service() method).
- Servlet is destroyed then garbage collected and finalized (the destroy() method).
- in init(), calls DBConnectionManager.getInstance() and saves the reference in an instance variable.
- in service(), calls getConnection(), performs all database operations, and returns the Connection to the pool with freeConnection().
- in destroy(), calls release() to release all resources and close all connections.
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TestServlet extends HttpServlet {
private DBConnectionManager connMgr;
public void init(ServletConfig conf) throws ServletException {
super.init(conf);
connMgr = DBConnectionManager.getInstance();
}
public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
Connection con = connMgr.getConnection("mysql");
if (con == null) {
out.println("Can't get connection");
return;
}
ResultSet rs = null;
ResultSetMetaData md = null;
Statement stmt = null;
try {
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM EMPLOYEE");
md = rs.getMetaData();
out.println("Employee data");
while (rs.next()) {
out.println("");
for (int i = 1; i < md.getColumnCount(); i++) {
out.print(rs.getString(i) + ", ");
}
}
stmt.close();
rs.close();
}
catch (SQLException e) {
e.printStackTrace(out);
}
connMgr.freeConnection("mysql", con);
}
public void destroy() {
connMgr.release();
super.destroy();
}
}
Open Source Ajax Frameworks
Google Web Toolkit
Google Web Toolkit (GWT) is an open source Java software development framework that makes writing AJAX applications like Google Maps and Gmail easy for developers who don't speak browser quirks as a second language. Writing dynamic web applications today is a tedious and error-prone process; you spend 90% of your time working around subtle incompatibilities between web browsers and platforms, and JavaScript's lack of modularity makes sharing, testing, and reusing AJAX components difficult and fragile. GWT lets you avoid many of these headaches while offering your users the same dynamic, standards-compliant experience. You write your front end in the Java programming language, and the GWT compiler converts your Java classes to browser-compliant JavaScript and HTML |
ICEfaces
ICEfaces is an integrated Ajax application framework that enables Java EE application developers to easily create and deploy thin-client rich Internet applications (RIA) in pure Java. ICEfaces leverages the entire standards-based Java EE ecosystem of tools and execution environments. Rich enterprise application features are developed in pure Java, and in a pure thin-client model. There are no Applets or proprietary browser plug-ins required. ICEfaces applications are JavaServer Faces (JSF) applications, so Java EE application development skills apply directly and Java developers are isolated from doing any JavaScript related development. |
DWR
DWR is a Java open source library which allows you to write Ajax web sites. It allows code in a browser to use Java functions running on a web server just as if it was in the browser. DWR works by dynamically generating Javascript based on Java classes. The code does some Ajax magic to make it feel like the execution is happening on the browser, but in reality the server is executing the code and DWR is marshalling the data back and forwards. |
Echo2
Echo2 is the next-generation of the Echo Web Framework, a platform for developing web-based applications that approach the capabilities of rich clients. The 2.0 version holds true to the core concepts of Echo while providing dramatic performance, capability, and user-experience enhancements made possible by its new Ajax-based rendering engine. |
SweetDEV RIA
SweetDEV RIA is a complete set of world-class Ajax tags in Java/J2EE. It helps you to design Rich GUI in a thin client. SweetDEV RIA provides you Out-Of-The-Box Ajax tags. Continue to develop your application with frameworks like Struts or JSF. SweetDEV RIA tags can be plugged into your JSP pages. |
ThinWire
ThinWire is an development framework that allows you to easily build applications for the web that have responsive, expressive and interactive user interfaces without the complexity of the alternatives. While virtually any web application can be built with ThinWire, when it comes to enterprise applications, the framework excels with its highly interactive and rich user interface components. |
ItsNat, Natural AJAX
ItsNat is an open source (dual licensed GNU Affero General Public License v3/commercial license for closed source projects) Java AJAX Component based Web Framework. It offers a natural approach to the modern Web 2.0 development. ItsNat simulates a Universal W3C Java Browser in the server. The server mimics the behavior of a web browser, containing a W3C DOM Level 2 node tree and receiving W3C DOM Events using AJAX. Every DOM server change is automatically sent to the client and updated the client DOM accordingly. Consequences: pure (X)HTML templates and pure Java W3C DOM for the view logic. No JSP, no custom tags, no XML meta-programming, no expression languages, no black boxed components where the developer has absolute control of the view. ItsNat provides an, optional, event based (AJAX) Component System, inspired in Swing and reusing Swing as far as possible such as data and selection models, where every DOM element or element group can be easily a component.Singleton Pattern in Java
How the Singleton pattern works
Here’s a typical example of Singleton:
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
// Private constructor suppresses generation of a (public) default constructor
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
The classic Singleton does not use direct instantiation of a static variable with declaration — it instantiates a static instance variable in the constructor without checking to see if it already exists:
public class ClassicSingleton {
private static ClassicSingleton INSTANCE = null;
private ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(INSTANCE == null) {
INSTANCE = new ClassicSingleton();
}
return INSTANCE;
}
}
The Singleton class’s default constructor is made private, which prevents the direct instantiation of the object by other classes using the new keyword. A static modifier is applied to the instance method that returns the Singleton object; it makes this a class level method that can be accessed without creating an object.
When you need Singleton
Singletons are truly useful when you need only one instance of a class, and it is undesirable to have more than one instance of a class.
When designing a system, you usually want to control how an object is used and prevent users (including yourself) from making copies of it or creating new instances. For example, you can use it to create a connection pool. It’s not wise to create a new connection every time a program needs to write something to a database; instead, a connection or a set of connections that are already a pool can be instantiated using the Singleton pattern.
The Singleton pattern is often used in conjunction with the factory method pattern to create a systemwide resource whose specific type is not known to the code that uses it. An example of using these two patterns together is the Abstract Windowing Toolkit (AWT). In GUI applications, you often need only one instance of a graphical element per application instance, like the Print dialog box or the OK button.
Watch out for potential problems
Although the Singleton design pattern is one of the simplest design patterns, it presents a number of pitfalls.
Construct in multi-threaded applications
You must carefully construct the Singleton pattern in multi-threaded applications. If two threads are to execute the creation method at the same time when a Singleton does not exist, both must check for an instance of the Singleton, but only one thread should create the new object. The classic solution to this problem is to use mutual exclusion on the class that indicates that the object is being instantiated. This is a thread-safe version of a Singleton:
public class Singleton
{
// Private constructor suppresses generation a (public) default constructor
private Singleton() {}
private static class SingletonHolder
{
private final static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
}
For an alternative solution, you can add the synchronized keyword to the getInstance() method declaration:
public static synchronized Singleton getInstance()
Think ahead about cloning prevention
You can still create a copy of the Singleton object by cloning it using the Object’s clone() method. To forbid this, you need to override the Object’s clone method, which throws a CloneNotSupportedException exception:
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
Consider making the singleton class final
You may want to make the Singleton class final to avoid sub classing of Singletons that may cause other problems.
Remember about garbage collection
Depending on your implementation, your Singleton class and all of its data might be garbage collected. This is why you must ensure that there must be a live reference to the Singleton class when the application is running.