Monday, September 13, 2010

Using Java SignalHandling and ShutDownHook

  • Singal Handling

Here I only briefly talk about the the Java Signal handling under Unix/Linux using Sun's implementation; In Sun's implementation, there is an interface SingleHandler and a Single class, they are located in rt.jar file,for every signal you want to capure, you need create a corresponding instance for it, and then register it into the Singal's handlers:

1. Singal signal = new Signal( TERM );

2. YourSignalHandler youHandler = new YourSignalHandler();

3. Singal.handle( singal, youHandler);

Then your handler is ready to handle signals, you may use kill -TERM processId to send signal to your signal handler.

When you use singal handling with JVM, you need consider some signals have already been listened by the JVM, and signals can only be handled by one handler, if you want to handle it, you must tell JVM to ignore it using -Xrs option when you bring up the JVM( Sun JVM)

  • Shudown hook

Sometime, you want to do some cleanup when your application is shuting down, for example, shutdown your thread pool, close your connection pool and close files gracefully.

1. Shutdown hook is a class which extends Thread class, and can be installed using Runtime.getRuntime().addShutdownHook() or removed using Runtime.getRuntime().removeShutdownHook()

2. Each shudown hook will be started when the JVM terminating, and they are running simultaneously, so synchronization should be considered if ncessary.

3. Shudown hook will be invoked under the following scenarios:

  • Application normal exits, for example, calling System.exit(0), Runtime.exit(), or the last non-deamon thread exits
  • JVM is terminated by some signals, such as SIGTERM, SIGHUP, etc.

4. Shutdown hook will not be invoked when:

  • JVM Crash
  • Runtime.halt() is called.
  • JVM -Xrs option is specified when bring up the JVM

In my previous post, I have talked about how to break the blocking I/O, especailly about how to gracefully shutdown the listener, now we know we could put the serverSocket.close() into a shudown hook, and then user sends a SIGTERM signal to the JVM, the JVM will be terminated and invoke the shudown hook to close the server socket. When the shutdown hook(s) are executed, the JVM will wait until all shutdown hooks finish their job, so you must make sure all of your shutdown hook finish their jobs properly, otherwise the JVM will hung.

For more detailed information about shutdown hook and signal handling, please refer to :

Revelations on Java signal handling and termination

 

Posted via email from Progress

A few simple ways to break your blocking I/O operatio

Tranditional blocking I/O is not like Thread.sleep(), Object.wait(), Thread.join(), etc, it cannot interrupted by the Thread.interrupt() method, but the others list above could be interrupted and you will get InterruptedException.

In blocking I/O, such as ServerSocket.accept(), if no more connect requests coming, it will be blocked maybe for ever. If you create a listern listening on a port, but you want to shutdown it gracefully, you may choose the following ways to do that:

1. Create a client socket and call connect() to this listener's port:

        Socket client = new Socket();
        try {
            client.connect(new InetSocketAddress(this.IP, this.port));
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    This will make the ServerSocket.accept() break, and make the thread proceeds.

2. Keep a reference( i.e serverSocket) to the ServerSocket you created in the listener, later when you want to shutdown the listener, just call serverSocket.close(), this also break the ServerSocket.accept().

3. The third way is not so graceful, but if you don't care about what is runing, it works, just uses kill -9 to kill the process.

Posted via email from Progress

Friday, September 10, 2010

Print Java class/method name, line number in your log file

Sometime it's very helpful to print verbose information in the log file, of course it will have impact on your performance.

Get class name is very easy, but dynamically get the method name and line number at the point you put your log message need you get help from Throwable class,

When we call new Throwable(), in the constructor, it first call fillInStackTrace() method, after the object is created, we could call throwable.getStackTrace() which returns an array of StackTraceElement, StackTraceElement[0] will be the method which creates the Throwable() object, StackTraceElement[1] will be the one outside the preivous mehtod, and so on. For exampe:

Wednesday, September 8, 2010

Use of ThreadLocal class

ThreadLocal helps to maintain a separate copy of the value for each thread that use it, it is often used to prevent sharing in designs based on mutable Singletons or global variables.
Conceptually, you can think of a ThreadLocal as holding a Map that stores the thread specific values, but the real implementation is not this way, the read data actually stored in the Thread object itself.

In Thread class, there are two private variables:
ThreadLocal.Values localValues;
ThreadLocal.Values inheritableValues;

Here is how the real per-thread values are stored. (ThreadLocal.set()):

public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values == null) {
values = initializeValues(currentThread);
}
values.put(this, value);
}

Values values(Thread current) {
return current.localValues;
}

Values initializeValues(Thread current) {
return current.localValues = new Values();
}

From the above code, we may see that ThreadLocal set values into Thread object's
localValues variable.When the thread terminates, the thread-specific values can be GCed.

For details please see:
crazybob.org: Hard Core Java: ThreadLocal


Improve your Java code performance

1. JDK 1.5 and above provide some new features to replace some old implementations:

  • StringBuilder is a replacement of StringBuffer

StringBuffer instances are almost always used by a single thread,yet they perform

internal synchronization. It is for this reason that was essentially replaced by StringBuilder,

which is an unsynchronized

  • Vector and ArrayList, if you create and modify the Vector within a method, ArrayList

will have better performance

2. If you only need read data from a collection, Collections.unmodifiable() will return the read-only view of

the passed in colleciton, you don't need to create a copy of the data, and you will consume less memory,

make less impact on garbage collector, and make the program faster.

Posted via email from Progress

Monday, August 9, 2010

Using and Understanding PageContext in JSP

PageContext is an abstract class which extends javax.servlet.jsp.JspContext, it provides context information when JSP is used in servlet environment, it is obtained by calling JspFactory.getPageContext(), and released by calling JspFactory.releasePageContext().

PageContext provides a single API to access various scope namespaces. Obtains an instance of an implementation dependent javax.servlet.jsp.PageContext abstract class for the calling Servlet and currently pending request and response.

JspFactory.getPageContext() is typically called early in the processing of the _jspService() method of a JSP implementation class in order to obtain a PageContext object for the request being processed.

Invoking this method shall result in the PageContext.initialize() method being invoked. The PageContext returned is properly initialized.

All PageContext objects obtained via this method shall be released by invoking releasePageContext().

Signature:

public abstract PageContext getPageContext(Servlet servlet,
ServletRequest request,
ServletResponse response,
String errorPageURL,
boolean needsSession,
int buffer,
boolean autoflush)

Example:

public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {

PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;


try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();

For every request, there will be one PageContext instance created and populated properly( various scope values)

Before the _jspService() method return, it will invoke JspFactory.releasePageContext() method, results in the PageContext.release()

method is invoked.

...

} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}

Posted via email from Progress

Monday, July 19, 2010

When does SSL Handshake happen?

SSL protocol sits on top of the transport layer but below application layer in the OSI protocol.

So the SSL handshake happens after the accept() method returned, that is, after the TCP connection is

established.

When SSLSockets are first created, no handshaking is done so that applications may first set their communication preferences: what cipher suites to use, whether the socket should be in client or server mode, etc.

The initial handshake on this connection can be initiated in one of three ways:

  1. Calling startHandshake which explicitly begins handshakes, or
  2. Any attempt to read or write application data on this socket causes an implicit handshake, or
  3. A call to getSession tries to set up a session if there is no currently valid session, and an implicit handshake is done.

Posted via email from Progress

Sunday, July 18, 2010

SSL, KeyStore and Key password

SSL server socket can be created by:
  • Calling SSLServerSocketFactory: SSLServerSocketFactory.getDefault()
    The default implementation can be specified in $JREHOME/lib/security/java.security by
    ssl.ServerSocketFactory.provider, but by default, it is not specified, instead, a internal
    implementation is used( JSSE: com.sun.net.ssl.internal.ssl.SSLServerSocketFactoryImpl)

    When this (default) implementation is used, you must specify:
    • keystore using javax.net.ssl.keyStore, if not, an empty keystore object will be managed by the KeyManager
    • keystore passwrod using javax.net.ssl.keyStorePassword
      Notice here,for the getDefault() will lead to the default SSLContext, default
      KeyManager, default TrustManager. And the most important thing is, you can only
      specify the keystore password, there is no way to specify the keys' password
      the system properties.


      For the SSL Socket created by the calling of getDefault(),the specified Keystore and the keys in the keystore must have the same password.

      Only the default implementation and is used, requires the keystore password and the keys' password must be the same.
  • Using customized SSLContext to create SSLSocket
For example:


try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(secureKeyStore.asInputStream(keystorePath), secureKeyStore
.getKeyStorePassword());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, secureKeyStore.getCertificatePassword());
serverContext = SSLContext.getInstance(PROTOCOL);
serverContext.init(kmf.getKeyManagers(), SecureTrustManagerFactory
.getTrustManagers(), null);
} catch (Exception e) {
e.printStackTrace();
throw new Error("Failed to initialize the server-side SSLContext",
e);
}

In the code above, we may notice, the kmf.init(KeyStore keystore, char[] pass) method accepts two arguments, the second one specifies the password for the key(s) or certificate(s).

Note that only one password is used in this method, so the keystore must use the same
password for all the private keys it stores, and there is no requirements this password must
be the same as the keystore password( but the default implementation requires this).

If the keys in the keystore have different password, the JSSE KeyManagerFactory.init() mehtod will throw UnrecoverableKeyException. Some other implementation may just return the matched key(s), but JSSE does not.

Wednesday, July 7, 2010

valueOf methods of Short, Integer and Long

This is a very interesting, in the JDK implementation,
any number between -128 and 127, the JDK create a cache :

  
static class valueOfCache {
/**
* A cache of instances used by {@link Integer#valueOf(int)}
* and auto-boxing.
*/

static final Integer[] CACHE = new Integer[256];
static {
for(int i=-128; i<=127; i++) {
CACHE[i+128] = new Integer(i);
}
}
}


And the static valueOf() method:
 
/*If it is not necessary to get a new {@code Integer}
*instance,it is recommended to use this method instead
*of the constructor,since it maintains a cache of
*instances which may result in better performance.
*/
public static Integer valueOf(int i) {
if (i < -128 || i > 127) {
return new Integer(i);
}
return valueOfCache.CACHE [i+128];
}

Sometime this method gives a better performance,
but there are a lot of debates here.

Saturday, July 3, 2010

Hardden Tomcat 5.0/5.5

  • Embedded Tomcat 5.0
1. It uses CoyoteConnector, located in src/jakarta-tomcat-catalina\catalina\src\share \org\apache\coyote\tomcat5
2. In CoyoteConnector, it has a public method called initilize(), in this method, ProtocolHandler is instantiated
3. In org.apache.catalina.startup.Embedded class's start() method, it will iterate through all connectors and call their initialize() method,

In Embedded.createConnector(), it creates Connector object, and assign a ServerSocketFactory object to the connector,

//connector created and ServerSocketFactory assigned ( it will be CoyoteServerSocketFactory )

connector = embedded.createConnector((InetAddress)null, port, SSL);

if( SSL ){
if( connector instanceof CoyoteConnector ){
CoyoteConnector cc = (CoyoteConnector)connector;
CoyoteServerSocketFactory cssFactory =(CoyoteServerSocketFactory) cc.getFactory();
cssFactory.setCiphers( DEFAULT_CIPHERS ) ;
}
}
embedded.addConnector(connector);
embedded.start();

5. Because CoyoteConnector has a method called setCiphers(), this method works in Tomcat5.5, but for Tomcat5.0, use CoyoteServerSocketFactory.setCiphers() method

Friday, July 2, 2010

Little Endian and Big Endian

Endianness: is the ordering of individually addressable
sub-units (words, bytes, or even bits) within a longer data
word stored in external memory.
for example, the byte-order


Little Endian and Big Endian

In JNI, if the type is specified using java type, for example,
int a;
Then in JNI, we don't need to convert to little endian for Linux,
only those data in raw byte array, if we need convert them to same
data structure, for those int, short, long... , we need convert
them to local host format( linux is little endian, solaris is big endian)