Saturday, March 29, 2008

Tomcat goodies on troubleshooting standalone server.

There are only really 3 things likely to go wrong during the stand-alone
Tomcat install:

(1) The most common hiccup is when another web server (or any process for that
matter) has laid claim to port 8080. This is the default HTTP port that
Tomcat attempts to bind to at startup. To change this, open the file:

$CATALINA_HOME/conf/server.xml

and search for '8080'. Change it to a port that isn't in use, and is
greater than 1024, as ports less than or equal to 1024 require superuser
access to bind under UNIX.

Restart Tomcat and you're in business. Be sure that you replace the "8080"
in the URL you're using to access Tomcat. For example, if you change the
port to 1977, you would request the URL http://localhost:1977/ in your browser.

(2) An "out of environment space" error when running the batch files in
Windows 95, 98, or ME operating systems.

Right-click on the STARTUP.BAT and SHUTDOWN.BAT files. Click on
"Properties", then on the "Memory" tab. For the "Initial environment" field,
enter in something like 4096.

After you click apply, Windows will create shortcuts which you can use
to start and stop the container.

(3) The 'localhost' machine isn't found. This could happen if you're behind a
proxy. If that's the case, make sure the proxy configuration for your
browser knows that you shouldn't be going through the proxy to access the
"localhost".

In Netscape, this is under Edit/Preferences -> Advanced/Proxies, and in
Internet Explorer, Tools -> Internet Options -> Connections -> LAN Settings.

Friday, February 22, 2008

Notes on Runnable Jars

You can easily package an application's entire set of classes and resources into a Java Archive (JAR). In fact, that is one goal of having jar files. Another is to let users easily execute the application stored in the archive. Why then are jar files second-class citizens in the Java universe—functioning only as archives—when they can be first class, right alongside native executables?

To execute a jar file, you can use the java command's -jar option. For example, say you have a runnable jar file called myjar.jar. Because the file is runnable, you can execute it like this: java -jar myjar.jar.

Alternatively, the Java Runtime Environment (JRE), when installed on an OS like Microsoft Windows, associates jar files with the JVM so you can double-click on them to run the application. These JARs must be runnable.

The question is: How do you make a JAR runnable?

The manifest file and the Main-Class entry

Inside most JARs, a file called MANIFEST.MF is stored in a directory called META-INF. Inside that file, a special entry called Main-Class tells the java -jar command which class to execute.

The problem is that you must properly add this special entry to the manifest file yourself—it must go in a certain place and must have a certain format. However, some of us don't like editing configuration files.

Let the API do it for you

Since Java 1.2, a package called java.util.jar has let you work with jar files. (Note: It builds on the java.util.zip package.) Specifically, the jar package lets you easily manipulate that special manifest file via the Manifest class.

For more details, refer to the link:

http://www.javaworld.com/javaworld/javatips/jw-javatip127.html

Saturday, December 8, 2007

Remote debugging an app deployed in tomcat

Just start tomcat using catalina.sh jpda start from /bin. The default options will start remote debugging in 8000. For details, read below.


How do I configure Tomcat to support remote debugging?

The short answer is to add the following options when the JVM is started: -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n There are a number of ways you can do this depending on how you normally start Tomcat: * Set environment variables JPDA_ADDRESS=8000 and JPDA_TRANSPORT=dt_socket and then start tomcat using catalina jpda start. * If you run Tomcat using service wrapper, check the documentation for the service to determine how to set the required JVM options. * If you start Tomcat from within an IDE, check the documentation for the IDE to determine how to set the required JVM options.

The port does not need to be set to 8000, it may be any value appropriate for your system.

Whilst this is very useful in development it should not be used in production because of both security and performance implications.

How do I remotely debug Tomcat using Eclipse?

This answer assumes that you have a project set up with all of the fixings and have some idea of what you're doing in this respect. If not then thats really outside the scope of this topic and more in the scope of you needing to go to [[WWW] eclipse.org] and read up on how to use your ide, and maybe practice a little bit before you come back to this. We're also going to assume you have some idea of what a debugger is and how to use one.

Make sure tomcat is started and that your app is deployed and the sources, etc are all defined as resources in your app. If you have a servlet or something, set a breakpoint where its sure to hit on the next request. Go to "Run->Debug...". Click on "Remote Java Applications", then click "New". Type in the title and all. Notice that port 8000 from the Tomcat instructions. Save and run. Eclipse will connect to the VM that Tomcat is running under. Wow, that was easy! Now go type the url to submit to your servlet or whatever in your browser. Boom you hit the breakpoint right? Have fun!

How do I remotely debug Tomcat using NetBeans IDE?

This answer assumes that you have correctly set up a NetBeans IDE project and that you know how to use the NetBeans IDE debugger. If not, please go to [WWW] http://www.netbeans.org/kb/using-netbeans/40/debug.html and read up on how to use NetBeans IDE and its debugger.

Make sure that Tomcat is started in debug mode as described above, that your application is deployed, and that the sources are all defined as resources in your application. If you have a servlet or JSP file, set a breakpoint where you think a problem might be occurring. Go to "Run->Attach Debugger". A dialog pops up to let you specify the following options:

  • Debugger: JPDA Debugger

  • Connector: SocketAttach

  • Host: The IP address of the host your Tomcat installation is running on (127.0.0.1 if it is your local machine).

  • Port: The port of your Tomcat debugging interface, which should be 8000 if you've followed the instructions above.

When you press OK, you have a debugging connection very similar to local debugging.

Note that NetBeans IDE has a second option -- you can debug JSP files and servlets locally using a Tomcat server that is bundled with the IDE. When you debug a JSP file or servlet in the IDE, the bundled Tomcat server automatically starts in debug mode, and the debugger connects to it.

Copied from source:

http://wiki.apache.org/tomcat/FAQ/Developing

Friday, November 16, 2007

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, try to use HashMap.

(http://www.jguru.com/faq/view.jsp?EID=430247)

Monday, November 12, 2007

Monday, October 8, 2007

Do You Know How to Optimize Your JVM?

Here is a video on "Optimize your JVM"

http://www.theserverside.com/news/thread.tss?thread_id=47121

source: theServerside.com

Wednesday, May 16, 2007

Useful JVM options for debugging.

To attach remote debugger to a stand alone java application, pass the following options to JVM.

${JAVA_HOME}/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=3345 JAVA_CLASS_NAME

* To make java process wait till debugger is attached, use suspend=y in the above options.

* To remote debug a war or ear application deployed in web or application container, set above options in web server or app server server.xml file.

* To provide more heap space to JVM, use options -Xms and -Xmx.

Tuesday, April 24, 2007

Java - Call by Value.

Revisiting the famous question - In Java, objects are passed by "Call by Value" or "Call by Reference" ? Many people say it is "Call by Reference" which is wrong based on Programming Languages Theory. The explanation can't be any better than this:

-------- Begin ---------
All parameters to methods are passed "by value." In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments. If you pass a double to a method, its parameter is a copy of whatever value was being passed as an argument, and the method can change its parameter's value without affecting values in the code that invoked the method. For example:
 class PassByValue {
public static void main(String[] args) {
double one = 1.0;

System.out.println("before: one = " + one);
halveIt(one);
System.out.println("after: one = " + one);
}

public static void halveIt(double arg) {
arg /= 2.0; // divide arg by two
System.out.println("halved: arg = " + arg);
}
}

The following output illustrates that the value of arg inside halveIt is divided by two without affecting the value of the variable one in main:
before: one = 1.0
halved: arg = 0.5
after: one = 1.0
You should note that when the parameter is an object reference, the object reference -- not the object itself -- is what is passed "by value." Thus, you can change which object a parameter refers to inside the method without affecting the reference that was passed. But if you change any fields of the object or invoke methods that change the object's state, the object is changed for every part of the program that holds a reference to it. Here is an example to show the distinction:
 class PassRef {
public static void main(String[] args) {
Body sirius = new Body("Sirius", null);

System.out.println("before: " + sirius);
commonName(sirius);
System.out.println("after: " + sirius);
}

public static void commonName(Body bodyRef) {
bodyRef.name = "Dog Star";
bodyRef = null;
}
}

This program produces the following output:
before: 0 (Sirius)
after: 0 (Dog Star)
Notice that the contents of the object have been modified with a name change, while the variable sirius still refers to the Body object even though the method commonName changed the value of its bodyRef parameter variable to null. This requires some explanation.

The following diagram shows the state of the variables just after main invokes commonName:

______________
main() | |
sirius------->| idNum: 0 |
| name --------+------>"Sirius"
commonName()----->| orbits: null |
bodyRef |______________|

At this point, the two variables sirius (in main) and bodyRef (in commonName) both refer to the same underlying object. When commonName changes the field bodyRef.name, the name is changed in the underlying object that the two variables share. When commonName changes the value of bodyRef to null, only the value of the bodyRef variable is changed; the value of sirius remains unchanged because the parameter bodyRef is a pass-by-value copy of sirius. Inside the method commonName, all you are changing is the value in the parameter variable bodyRef, just as all you changed in halveIt was the value in the parameter variable arg. If changing bodyRef affected the value of sirius in main, the "after" line would say "null". However, the variable bodyRef in commonName and the variable sirius in main both refer to the same underlying object, so the change made inside commonName is visible through the reference sirius.

Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory. If the Java programming language actually had pass-by-reference parameters, there would be a way to declare halveIt so that the preceding code would modify the value of one, or so that commonName could change the variable sirius to null. This is not possible. The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.

-- Arnold, K., Gosling J., Holmes D. (2006). The Java™ Programming Language Fourth Edition. Boston: Addison-Wesley.

-------- End ---------

Source: http://forum.java.sun.com/thread.jspa?threadID=719862&messageID=4155502

Monday, April 23, 2007

Using JHAT tool to analyze process running on JDK5.

JHAT is available only with JDK6. However it is possible to use this tool for analysis of a process running on JDK6.

Steps to use HAT tool on JDK5 in association with jHAT on JDK6.
**********************************************************

1. setup environment variables
------------------------------
$ export SA=/net/${JDK5_HOST}/tools/bin/sa15
$ export SA_HOME=/net/${JDK5_HOST}/tools/bin/sa15
$ export SA_JAVA=/net/${JDK6_HOST}/usr/jdk/entsys-j2se/bin/java

2. verify variables are set correctly
-------------------------------------
$ echo $SA ; echo $SA_HOME ; echo $SA_JAVA
/net/${JDK5_HOST}/tools/bin/sa15
/net/${JDK5_HOST}/tools/bin/sa15
/net/${JDK6_HOST}/usr/jdk/entsys-j2se/bin/java

3. generate preload_mappings thru dbx
-------------------------------------
$ /net/${JDK5_HOST}/${DBX_HOST}/bin/dbx -xexec32 -s dbxrc
(dbx) source /net/${JDK5_HOST}/tools/bin/dbxscripts/gen_pm.txt
(dbx) gen_pm
preload_mappings have been generated.
(dbx) quit

4. Generate core file using gcore to a running pid for processes that have not dumped core.

5. Use heapdumpproc.sh to generate heap.bin
--------------------------------------------
$ /net/${JDK5_HOST}/tools/bin/sa15/heapdumpproc.sh executable corefile

6. Start the http server
------------------------
/net/${JDK6_HOST}/${JAVA_HOME}/bin/jhat heap.bin

7. Review the heap dump at http://localhost:7000 - This is the default port.

Note:
------
* Results reported by this approach on JDK5 JVM may not be 100% accurate.
* The results are more accurate if the core is generated by a process crash instead of using gcore on a running pid.

Handling memory leaks in Java

Good discussion on handling memory leaks in Java using a real use case.
http://www-128.ibm.com/developerworks/java/library/j-leaks/