Wednesday, November 11, 2009

Enabling invoker servlet in apache tomcat 6.0.x

The invoker servlet is disabled in web.xml of latest apache tomcat 6.0 versions. It is not advisable to use this for the following reasons:

1. Security risk.

2. Configuration hiding - There is NO way to determine which servlets are used vs which are not used. In web.xml, every servlet is declared and mapped. In that one file you instantly have a road map to how the webapp works.

3. Back doors. Servlets which are mapped can be alternately called via the invoker by class name. Since the URL is different, all security constraints might be ignored since the URL pattern is VERY different.

4. Back doors. Bad programmers make it easier to do bad things.

5. Back doors. It may be common to use common 3rd party jars in a shared area. If that shared jar has servlets in them and that servlet has a hole in it, bad things happen.
Configuration hiding - it's important enough to say twice. Explicit declaration while a PITA, will be more helpful in the maintenance scheme of your webapp.


To enable it for quick testing:

Step-1: In home dir / conf / web.xml file, uncomment servlet definition.

Step-2: In home dir / conf / web.xml file, uncomment servlet mapping.

Step-3: In home dir / conf / context.xml, change parent element Context to
Context privileged="true" reloadable="true"

Reference:
Tomcat invoker servlet evil faqs

Thursday, September 17, 2009

Differences between HashMap and HashTable

Both provide key-value access to data. The Hashtable is one of the original collection classes in Java. HashMap is part of the new Collections Framework, added with Java 2, v1.2.

The key difference between the two is that access to the Hashtable is synchronized on the table while access to the HashMap isn't. You can add it, but it isn't there by default.

Another difference is that iterator in the HashMap is fail-safe while the enumerator for the Hashtable isn't. If you change the map while iterating, you'll know.

And, a third difference is that HashMap permits null values in it, while Hashtable doesn't.

For new code, use HashMap as much as possible.

If you want Keys in HashMap to be Case - Insensitive, follow this technique:
http://www.velocityreviews.com/forums/t140140-case-insensitive-keys-using-collections.html
* Store keys in LowerCase while popluating the map.
* Always use .LowerCase() on lookupKey before doing a get()

Complexity of Lookup on HashMap is not alway O(1). It depends on HashMap size. If multiple keys in HashMap match a lookupKey, then it traverses linear O(n) on matched Keys.

4 Ways to traverse HashMap - Link

Tuesday, September 15, 2009

All about try-catch-finally

try {
statements;
} catch (exceptionType1 identifier1) { // one or multiple
statements;
} catch (exceptionType2 identifier2) {
statements;
}
...
} finally { // one or none
statements;
}

* must include either one catch clause or a finally clause
* can be multiple catch clauses but only one finally clause
* the try statements are executed until an exception is thrown or it completes successfully

* a compile-error occurs if the code included in the try statement will never throw one of the caught checked exceptions (runtime exceptions never need to be caught)
* if an exception is thrown, each catch clause is inspected in turn for a type to which the exception can be assigned; be sure to order them from most specific to least specific
* when a match is found, the exception object is assigned to the identifier and the catch statements are executed
* if no matching catch clause is found, the exception percolates up to any outer try block that may handle it
* a catch clause may throw another exception

* if a finally clause is included, it's statements are executed after all other try-catch processing is complete
* the finally clause executes wether or not an exception is thrown or a break or continue are encountered

Note
====
* If a catch clause invokes System.exit() the finally clause WILL NOT execute.

Friday, July 17, 2009

Note on Garbage collection of circular references.

Question:
=========
I have 2 objects; A and B.
A has a reference to B and B has a reference to A.
If A and B are not referenced by any other objects are they eligible for garbage collection?

Answer:
=======
Yes, they will be collected.* Most people think the GC uses reference counting to keep track of referenced objects. In that case, A and B would both have a non-zero reference count and not be collected. Sun's JVM (1.1.x, 1.2) uses a mark-and-sweep algorithm (and I think most others do as well). It starts at a base point (I can't remember off hand what the base point is, it's something like all runnable thread classes) and starts following the references from there (like walking a tree). If something s reachable from a base point it is noted as such. After walking through all references, those not marked as reachable are removed. Since neither A nor B is reachable from the root, they will be removed.
Note that 1.2 introducted concepts such as strong references, weak references, and phantom references. 1.3 has a significantly more complex GC. In all cases however, the above more or less holds true. Sun hs documentation on the new refernce types as well as the HotSpot GC.
*The GC is obviously different in each JVM, but all JVMs I know of can handle this case correctly. There may be some that don't.

Reference:
==========
http://www.coderanch.com/t/322042/Java-General-advanced/java/Garbage-collection-circular-references

Thursday, July 16, 2009

Quick steps to get heap dumps in glassfish app Server.

Step-1: export JAVA_HOME=
change ports in setup.xml if required.

Step-2: cd /glassfish

Step-3: chmod -R 777 ./lib

Step-4: ./lib/ant/bin/ant -f setup.xml

Step-5: ./bin/asadmin start-domain domain1
Get pid for the server process.

Step-6: Run following commands.

bash-3.00# kill -3 12617 if 12617 is the pid

bash-3.00# jmap -dump:format=b,file=/tmp/java_app-heap.bin 12617
Dumping heap to /tmp/java_app-heap.bin ...
Heap dump file created

bash-3.00# jhat -J-Xmx326m /tmp/java_app-heap.bin
Reading from /tmp/java_app-heap.bin...
Dump file created Thu Jul 16 20:18:55 PDT 2009
Snapshot read, resolving...
Resolving 1202039 objects...
Chasing references, expect 240 dots................................................................................................................................................................................................................................................
Eliminating duplicate references................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

Step-7: Access heap by browsing http://host:7000/

Approach to find memory leaks in Java

Note: Use the latest JDK 6, because it has the latest tools, with lots of bug fixes and improvements. All the later examples assume that JDK6’s bin directory is in the PATH.

Step 1. Start the application.
------------------------------
Start the application as you usually do:
java -jar java_app.jar

Alternatively, you could start java with hprof agent. But this is not required to use jhat and debug for memory leaks. Java will run slower, but the huge benefit of this approach is that the stack traces for created objects will be available which improves memory leak analysis greatly:

java
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-agentlib:hprof=heap=dump,file=/tmp/hprof.bin,
format=b,depth=10
-jar java_app.jar

When the application is up, perform various actions that you think might lead to memory leaks.

For example, if you open some documents in your app, the memory graph could rapidly go up. If closing the docs and invocation of full garbage collection did not bring the memory back to normal level, there is probably a leak somewhere.You might use jconsole from JDK 6 to see the memory consumption graph to have a clue whether memory leak is present or not:
jconsole
It will pop up a dialog with a list of Java applications to connect to. Find the one with java_app.jar and connect. Also, jconsole allows to invoke full GC providing nice button just for that.


Step 2. Find the application pid.
================================
Find out the application’s process id via:
jps

It will print something like:
15976 java_app.jar
7586 startup.jar
22476 Jps
12248 Main
5437 Bootstrap
In our case the pid is 15976.


Step 3. Dump the heap into file.
================================
Dump heap into the file:

jmap -dump:format=b,file=/tmp/java_app-heap.bin 15976

We just told jmap to dump the heap into /tmp/java_app-heap.bin file, in binary from (which is optimized to work with large heaps). The third parameter is the pid we found in Step 2.

Alternatively, if you started java with hprof agent, you could just use Ctrl-\ on Solaris/Linux or Ctrl-Break on Windows to dump heap into the file, specified in hprof agent arguments.


Step 4. Visualize the heap.
===========================
Use jhat tool to visualize the heap:

jhat -J-Xmx326m /tmp/java_app-heap.bin

Jhat will parse the heap dump and start a web server at port 7000. Connect to Jhat server by pointing your browser to:

http://localhost:7000

And start investigating.

Jhat allows you to see what objects are present in the heap, who has references to those objects, etc.

Here are some tips:
--------------------
* Investigate _instances_, not _classes_.
* Use the following URL to see the instances: http://localhost:7000/showInstanceCounts/
* Use “Reference Chains from Rootset” (Exclude weak refs!!!) to see who’s holding the instance.

******************************************************************************

Monday, July 13, 2009

JVM parameters for web containers to enable GC logging

-Xloggc:/tmp/gc.log -XX:+PrintClassHistogram -XX:+PrintGCTimeStamps

Wednesday, May 6, 2009

Easy way of testing class files

If code base is large and takes time to build, we can do the following to quickly test our fix.

1. Build class files in the sub directory where you made code change.

2. Prepare a jar file in the following format:
* Suppose package name is com.sun.identity.authentication for your class file, then create folder structure ~/ws/com/sun/identity/authentication in your workspace. Copy newly built class file into com/sun/identity/authentication. Do jar -cvf ~/test.jar * in your workspace ~/ws.

3. Place the complete path of this jar file like /home/lakshman/test.jar as first entry in classpath of your webserver server.xml file or app server domain.xml

4. Restart container.

Your fix will kick in and you can test your fix.

Friday, February 13, 2009

Unix tip

To reset a file to 0 bytes without making it stale, do
cp /dev/null filename

To find MAC address of a Solaris box, do:
arp host-name
This works for users with no root permission.