Thursday, March 18, 2010

How to get the invocation hierarchy in Java?

In Java, we can see the invocation hierarchy sometimes in Java. Especially, the log4j can log the class into log file with package name, method and line even. How can we implement the similar functionality?

First, how can we get the invocation class and method? Stack trace.

StackTraceElment[] ste = new Throwable().getStackSTrace();

In the array of StackTraceElement, we can find the hierarchy of current stack. By this, we can get the invocation map of whole stack.

StackTraceElment APIs:
String getClassName()
Returns the fully qualified name of the class containing the execution point represented by this stack trace element.
String getFileName()
Returns the name of the source file containing the execution point represented by this stack trace element.
int getLineNumber()
Returns the line number of the source line containing the execution point represented by this stack trace element.
String getMethodName()
Returns the name of the method containing the execution point represented by this stack trace element.

In Java 5, The Thread introduced two new methods: getStackTrace() and getAllStackTraces(). Now we don't need to use (new Throwable()).getStackTrace() and by using Thread.getCurrentThread().getStackTrace() to get the stack trace info. Not only doing so, but also we can get stack trace of other threads if we have the enough permission.

Stub caching and concurrent reuse problems in Axis

Reference Stub caching and concurrent reuse problems

Somebody tried to cache the generated stubs for reusing by concurrent clients
because instantiating of them takes too long. But every time he started 4+ concurrent clients for the same web-service, he would receive some weird exceptions from the core of Axis. This happened only in case of caching the stubs and not issue for creating new stub for every client but the performance.

Some people replied the question and mentioned the cache of stub was not hoped and the internals of the stubs may screw up if cached! If you are using the usual no
args constructor of the stub, the stub may need to create its own configuration context and that may take significant time. You can cache the config context and create the stub passing in your config context, instead of caching stub.

In the mail list, also somebody mentioned they had found two important factors to keep in mind when reusing stubs:

  1. The stubs are not thread safe, so you cannot use the same stub in
    two concurrent threads

  2. Recently discovered that even the stub constructor is not thread safe! So two concurrent threads cannot call the constructor at the same time.



If you have a typical architecture that reuses client processing threads, then each needs their own stub but once it creates a stub it can continue to use that indefinitely.

Another useful thing to do is:

options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, new Boolean(true));