Tomcat Administration

Reasons for Using a Web Server Apache
You may be wondering why a separate Web server is needed when Tomcat already has an HTTP
Connector. Following are some reasons:
 PerformanceTomcat is inherently slower than a Web server. Therefore, it is better for the
Web server to serve up static content, while Tomcat handles the dynamic content (JSPs
and Servlets). Passing requests for static HTML pages, images, and style sheets through a
Servlet container written in Java is not as efficient compared to a Web server.
 SecurityAWeb server such as Apache has been around for much longer than Tomcat,
and has far fewer security holes.
 StabilityApache is much more stable than Tomcat. In the event of a Tomcat crash, the entire
Web site will not come down. Only the dynamic content served by Tomcat would be unavailable.
 ConfigurabilityApache is also far more configurable than Tomcat. Using Apache as a front end
enables you to take advantage of its rich functionality.
 Legacy supportWeb sites often have legacy code in the form of CGI programs. They might
also use scripting languages (such as Perl or Python) to implement specific functionality. Web
servers such as Apache have modules for Perl and Python, whereas Tomcat does not. Tomcat
does have limited support for CGI, however, using a special CGIServlet that mimics the CGI
functionality.
___________________________________________________________________________________________________
TOMCAT INSTALLATION:
Download  apache-tomcat-7.0.28.tar.gz and  jdk-7u3-linux-i586.tar.gz
# Tar  –xvzf apache-tomcat-7.0.28.tar.gz   –C  /opt
# Tar -xvzf jdk-7u3-linux-i586.tar.gz  –C  /opt
# vi .bash_profile
export JAVA_HOME=/opt/jdk1.7.0_03
export CATALINA_HOME=/opt/apache-tomcat-7.0.28
# source .bash_profile
# echo $JAVA_HOME; echo $CATALINA_HOME
/opt/jdk1.7.0_03
/opt/apache-tomcat-7.0.28
-- > http://localhost:8080/
Aapche & Tomcat with Mod_jk
# tar –xvzf  tomcat-connectors-1.2.37-src.tar.gz  -C  /opt/
# cd /opt/tomcat-connectors-1.2.37-src/native
# ./configure   --with-apxs=/opt/apache2/bin/apxs  
# make
# make install                    
# ls  –l /opt/apache2/modules   --- > Check mod_jk.so module in apache           
# vi /opt/apache2/conf/workers.properties
worker.list=node1
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.lbfactor=1

# vi /opt/apache2/conf/httpd.conf
LoadModule    jk_module     modules/mod_jk.so   
 JKWorkersFile    conf/workers.properties
<VirtualHost *:83>
     ServerName test.sapient.com
     DocumentRoot /opt/apache2/htdocs/test
     JKLogFile logs/mod_jk.log
     JKLogLevel error
     JKMount /*  node1
</VirtualHost>

 # /opt/apache-tomcat-7.0.28/bin/startup.sh

UserHit à http://test.sapient.com:83/  à We can see tomcat welcome page

Multiple instances of Tomcat
# cp  –r  apache-tomcat-7.0.28   apache-tomcat-7.0.28 _1 
# vi /opt/ apache-tomcat-7.0.28 _1/conf/server.xml
apache-tomcat-7.0.28 (server.xml)
apache-tomcat-7.0.28 _1 (server.xml)
<Server port="8005" shutdown="SHUTDOWN">
<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8080" protocol="HTTP/1.1"
<Connector port="8081" protocol="HTTP/1.1"
<Connector port="8009" protocol="AJP/1.3"
<Connector port="8010" protocol="AJP/1.3"

# /opt/ apache-tomcat-7.0.28/bin/catalina.sh;  tail  –f ../logs/catalina.out
#/opt/ apache-tomcat-7.0.28_1/bin/catalina.sh ;  tail  –f ../logs/catalina.out

# ps –ef | grep java
root     3535     1 44 14:37 pts/2    00:00:01 /opt/jdk1.7.0_03/bin/java -         Djava.util.logging.config.file=/opt/apache-tomcat-7.0.28/conf/logging.properties
root     3509     1 41 14:37 pts/2    00:00:01 /opt/jdk1.7.0_03/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat-7.0.28_1/conf/logging.properties -

To check which tomcat is running on which port
# netstat -antp|grep 8080
tcp        0      0 :::8080                     :::*                        LISTEN      3535/java
# netstat -antp|grep 8081
tcp        0      0 :::8081                     :::*                        LISTEN      3509/java

# vi /opt/apache2/conf/workers.properties
worker.list=node1,node2, loadbalancer,status
worker. node1.port=8009
worker. node1.host=localhost
worker. node1.type=ajp13
worker.node1.lbfactor=100
worker. node2.port=8010
worker. node2.host=localhost
worker. node2.type=ajp13
worker.node2.lbfactor=100
worker.loadbalancer.balance_workers=node1,node2    // Load-balancing behaviour
worker.loadbalancer.sticky_session=1
worker.status.type=status      // Status worker for managing load balancer

# vi /opt/apache2/conf/httpd.conf
Listen 83
Listen 84
JKWorkersFile    conf/workers.properties
<VirtualHost *:83>
     ServerName test.sapient.com
     DocumentRoot /opt/apache2/htdocs/test
     JKLogFile logs/mod_jk.log
     JKLogLevel error
     JKMount /*  node1
</VirtualHost>
<VirtualHost *:84>
     ServerName test.sapient.com
     DocumentRoot /opt/apache2/htdocs/
     JKLogFile logs/mod_jk.log
     JKLogLevel error
     JKMount /*  node2
</VirtualHost>
# /opt/apache2/bin/apachectl -k restart
http://test.sapient.com:83/  à connect to tomcat_1
http://test.sapient.com:84/  à connect to tomcat_2


Workers Properties File
worker.list=tomcat

worker.reference.socket_timeout=10000
worker.reference.socket_keepalive=true
worker.reference.connect_timeout=5000
worker.reference.connection_pool_size=30
worker.reference.cachesize=1
worker.template.prepost_timeout=10000
worker.template.connect_timeout=10000
worker.template.connection_pool_size=30
worker.template.socket_timeout=10
worker.template.retries=20


# Define App1
# modify the host as your host IP or DNS name.

worker.tomcat.reference=worker.reference
worker.tomcat.port=8009          # This Value should be an AJP Port No
worker.tomcat.host=172.17.100.213
worker.tomcat.type=ajp13
worker.tomcat.lbfactor=1
#worker.tomcat.cachesize=10
worker.tomcat.connection_pool_timeout=20

Connection Directive:
Host = localhost  //name of the appserver hostname or ip
Port=8009
socket_timeout=0  //Socket timeout (in sec) used between JK and remote host. If remote host does not respond in this time, JK will generate an error, and retry again. If set to zero (default) JK will wait for an infinite amount of time on all socket operations.
socket_connect_timeout = socket_timeout*1000 (in millisec)
socket_keepalive=False
____________________________________________________________________________________________________
Virtual Hosting in Tomcat
[root@test tomcat_1]# cp -r webapps host1
[root@test tomcat_1]# cp -r webapps host2
# vi /opt/tomcat_1/conf/server.xml
<Engine name="Catalina" defaultHost="localhost">
  <Host name="localhost"  appBase="webapps"/>     
  <Host name="www.host1.com"  appBase="host1"
            unpackWARs="true" autoDeploy="true">
     </Host>
   <Host name="www.host2.com"  appBase="host2"
            unpackWARs="true" autoDeploy="true">
      </Host>
 </Engine>
# vi /opt/tomcat_1/host1/ROOT/host1.html
<html><body> This is virtual host1</body></html>
# vi /opt/tomcat_1/host2/ROOT/host2.html
<html><body> This is virtual host2</body></html>

# vi /etc/hosts
192.168.10.102  www.host1.com www
192.168.10.102  www.host2.com www

____________________________________________________________________________________________________
JNDI: The Java Naming and Directory Interface (JNDI) is an application programming interface (API) for accessing different kinds of naming like CORBA, Java RMI, and EJB; and directory services like LDAP,NIS+.
The most common use case is to set up a database connection pool on a Java EE application server
Difference between ear,war,jar files
EAR is an EEnterprise Aapplication archive and may contain ejb JAR files, WAR files, and RAR (connector) files. They may also contain third-party libraries - but you have to know how to manipulate the Java extension facilities (e.g. MANIFEST.MF Class-Path directive) to make that work well.

WAR is an Web Aapplication archive and contains JSPs, "normal" HTTP served files (HTML, images, etc.), servlets, tag libraries, and such.
JAR is the "normal" Java Aapplication archive, but in this context it usually contains EJBs instead of code libraries or runnable (e.g. from outside an application container) applications.
JAR : JAVA Archives and it allows aggregating many files into One.It usually hold java classes in lib.
WAR : Web Application Archives and it stores xml,Java Classes and JSP for Web Application.
EAR : Enterprise Archives it combines JAR and WAR files into combined Archive

JDBC connection pooling (DBCP)
1. MySQL configuration
mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost IDENTIFIED BY 'javadude' WITH GRANT OPTION;
mysql> create database javatest;
mysql> use javatest;
mysql> create table testdata (id int not null auto_increment primary key, foo varchar(25), bar int);
Note: the above user should be removed once testing is complete!
mysql> insert into testdata values(null, 'hello', 12345);
mysql> select * from testdata;
+----+-------+-------+
| ID | FOO   | BAR   |
+----+-------+-------+
|  1 | hello | 12345 |
+----+-------+-------+
mysql>
2. Context configuration : Configure the JNDI DataSource to Context.
    maxActive: Maximum number of database connections in pool.. Set to -1 for no limit.
    maxIdle: Maximum number of idle database connections to retain in pool. Set to -1 for no limit. 
    maxWait: Maximum time to wait for a database connection to become available in ms, ex. 10 sec.     An Exception is thrown if this timeout is exceeded.  Set to -1 to wait indefinitely.
#vi  Server.xml
<Context>
  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
3. web.xml configuration
Now create a WEB-INF/web.xml for this test application.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>
4. Now create a simple test.jsp page for use later.
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<sql:query var="rs" dataSource="jdbc/TestDB">
select id, foo, bar from testdata
</sql:query>
<html> <head> <title>DB Test</title> </head>
  <body> <h2>Results</h2>
<c:forEach var="row" items="${rs.rows}">
    Foo ${row.foo}<br/>
    Bar ${row.bar}<br/>
</c:forEach>
</body></html>
____________________________________________________________________________________________________
Tomcat follow symbolic links
allowLinking="true" 
# vi context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/myapp" allowLinking="true">
</Context>

Allow or deny virtual hosting to accessible by users in tomcat
Use a valve to filter by IP or hostname to only allow a subset of machines to connect.
# vi Server.xml
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.1.*"></Valve>

Log path setting in Tomcat
# vi server.xml
<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
          prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
 </Host>

Response time logging in Tomcat
<Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs" prefix="timing." suffix=".log"
                 pattern="%t %U %s %D" resolveHosts="false" />

Turn on Servlet Reloading
# vim $CATLINA_HOME/conf/server.xml
below  <Host name="localhost" debug="0" appBase="webapps" />
                <DefaultContext reloadable="true"/>

Implement custom error pages
# vi web.xml
error-page>
   <error-code>404</error-code>
   <location>/error/404.html</location>
</error-page>
To allow directory browsing via Apache Tomcat
change the parameter "listings" in the file conf/web.xml from false to true.
# vim $CATLINA_HOME/conf/web.xml
search by /listings
<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
Note: To Secure directory listings -- > listing value should be false

Session Timeout Configuration
# vi web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
____________________________________________________________________________________________________
Tomcat Logging
Using logging.properties  ( To debug more logs)
# vi logging.properties 
org.apache.catalina.core.ContainerBase.[Catalina].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler

Using Log4j: Tomcat 6.0 uses Commons Logging throughout its internal code allowing the developer to choose a logging configuration. If we want to collect the detailed logging of tocat then we need to configure the external logging api like log4j 
Create a file called log4j.properties with the following content and save it into $CATALINA_BASE/lib
log4j.rootLogger=INFO, CATALINA   (// DEBUG)
# Define all the appenders
log4j.appender.CATALINA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.CATALINA.File=${catalina.base}/logs/catalina.
log4j.appender.CATALINA.Append=true
log4j.appender.CATALINA.MaxFileSize=10MB

log4j.appender.CATALINA.MaxBackupIndex=10
log4j.appender.CATALINA.Encoding=UTF-8
# Roll-over the log once per day
log4j.appender.CATALINA.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n

# same for
log4j.appender.LOCALHOST=org.apache.log4j.DailyRollingFileAppender
……
log4j.appender.MANAGER=org.apache.log4j.DailyRollingFileAppender
……
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Encoding=UTF-8
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern = %d [%t] %-5p %c- %m%n

# Configure which loggers log to which appenders
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=INFO, LOCALHOST
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]=\
  INFO, MANAGER
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]=\
  INFO, HOST-MANAGER
Download Log4J (v1.2 or later).
3.       Download or build tomcat-juli.jar and tomcat-juli-adapters.jar that are available as an "extras" component for Tomcat. See Additional Components documentation for details.
4.       This tomcat-juli.jar differs from the default one. It contains the full Apache Commons Logging implementation and thus is able to discover the presense of log4j and configure itself.
5.       Put log4j.jar and tomcat-juli-adapters.jar from "extras" into $CATALINA_HOME/lib.
6.       Replace $CATALINA_HOME/bin/tomcat-juli.jar with tomcat-juli.jar from "extras".
7.       Create $CATALINA_BASE/bin and $CATALINA_BASE/lib directories if they do not exist.
8.       Put log4j.jar and tomcat-juli-adapters.jar from "extras" into $CATALINA_BASE/lib
9.       Put tomcat-juli.jar from "extras" as $CATALINA_BASE/bin/tomcat-juli.jar
10.   If you are running with a security manager, you would need to edit the$CATALINA_BASE/conf/catalina.policy file to adjust it to using a different copy of tomcat-juli.jar.
11.   Delete $CATALINA_BASE/conf/logging.properties to prevent java.util.logging generating zero length log files.
12.   Start Tomcat
____________________________________________________________________________________________________
Tomcat Security
# vi /opt/tomcat_1/conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="vivek" password="vivek" roles="manager,admin"/>
</tomcat-users>
____________________________________________________________________________________________________
Configuring Tomcat for SSL
1. Generating the KeyStore file
#  /usr/java/jdk1.7.0/bin/keytool -genkey  -keyalg RSA -alias tomcat -keystore /opt/apache-tomcat-7.0.28/keys/tomcat.jks
Enter keystore password: sapient
Re-enter new password: sapient
What is your first and last name? [Unknown]:  vivek srivastav
What is the name of your organizational unit? [Unknown]:  ISST
What is the name of your organization?  [Unknown]:  sapient
What is the name of your City or Locality? [Unknown]:  Gurgoan
What is the name of your State or Province? [Unknown]:  Haryana
What is the two-letter country code for this unit?  [Unknown]:  IN
Is CN=vivek srivastav, OU=ISST, O=sapient, L=Gurgoan, ST=Haryana, C=IN correct? [no]:  yes
Enter key password for <tomcat>
        (RETURN if same as keystore password): sapient
Re-enter new password: sapient

2. Configuring Tomcat for using the Keystore file
# vi /opt/apache-tomcat-7.0.28/conf/server.xml
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="/opt/apache-tomcat-7.0.28/keys/tomcat.jks" keystorePass="sapient" />

If getting “Secure Connection Failed (Error code: sec_error_ca_cert_invalid)”
è Click on “you can add an exception”
è Click on “Add Exception”
è Get Certificate
è Confirm Security Exception

3. Import an certificate (e.g. server.crt)
# mv /opt/apache2/conf/server.crt   /opt/apache-tomcat-7.0.28/keys/.
# cd /opt/apache-tomcat-7.0.28/keys/
# /usr/java/jdk1.7.0/bin/keytool -import -trustcacerts -alias cert -file server.crt -keystore tomcat.jks
Enter keystore password: sapient
Re-enter new password: sapient
Owner: CN=o2vb, OU=ISST, O=O2, L=DL, ST=GGN, C=IN
Issuer: CN=o2vb, OU=ISST, O=O2, L=DL, ST=GGN, C=IN
Serial number: fb3b6d2ecd8932db
Valid from: Tue Oct 09 23:49:00 IST 2012 until: Wed Oct 09 23:49:00 IST 2013
Certificate fingerprints:
         MD5:  4C:4C:9C:93:F5:93:57:ED:2B:9D:B3:CA:CB:1D:97:C8
         SHA1: 3B:70:18:A2:0D:4B:59:FF:4E:5C:64:6D:11:28:BA:49:BA:BA:BD:E2
         SHA256: 3A:57:76:74:79:52:B7:81:FD:6F:2A:3D:A1:F0:FD:3C:36:C9:E9:F5:BD:B1:D5:6B:E5:15:09:73:63:3F:5D:D2
         Signature algorithm name: SHA1withRSA
         Version: 1
Trust this certificate? [no]:  yes
Certificate was added to keystore
Keystore certificates list
# /usr/java/jdk1.6.0_06/bin/keytool -list -v -keystore tomcat.jks
Generate a certificate signing request (CSR) for an existing Java keystore
# keytool -certreq -alias mydomain -keystore keystore.jks -file mydomain.csr
Check a stand-alone certificate
# keytool -printcert -v -file mydomain.crt
Check a particular keystore entry using an alias
# keytool -list -v -alias mydomain -keystore keystore.jks 
Delete a certificate from a Java Keytool keystore
# keytool -delete -alias mydomain -keystore keystore.jks
Change a Java keystore password
# keytool -storepasswd -new new_storepass -keystore keystore.jks
Export a certificate from a keystore
# keytool -export -alias mydomain -file mydomain.crt -keystore keystore.jks
List Trusted CA Certs
# keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
Import New CA into Trusted Certs
# keytool -import -trustcacerts -file /path/to/ca/ca.pem -alias CA_ALIAS -keystore $JAVA_HOME/jre/lib/security/cacerts
Source: https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
To check certificates validity
[tomcat@app4r]$ /usr/java/jdk1.6.0_06/bin/keytool -list -v -keystore Be.jks > abc
[tomcat@app4r]$ cat abc|grep -e "Alias" -e "Valid"
Alias name: o2_snowpatrol
Valid from: Fri Oct 08 10:25:11 BST 2010 until: Fri Apr 06 10:25:11 BST 2012
Alias name: tomcat
Valid from: Tue Nov 23 12:30:01 GMT 2010 until: Wed Nov 23 12:30:01 GMT 2011
Alias name: new_dsl_cert
Valid from: Mon Sep 15 01:00:00 BST 2008 until: Fri Sep 16 00:59:59 BST 2011
Alias name: imt_stage_snowpetrol
Certificate Handshake failure Issue
[tomcat@app4r certificates]$ wget 'https://sdpapi.ref.o2.co.uk/services/ViewPostalAddress_1_0'
--2013-05-10 14:37:17--  https://sdpapi.ref.o2.co.uk/services/ViewPostalAddress_1_0%20%3Chttps://sdpapi.ref.o2.co.uk/services/ViewPostalAddress_1_0%3E
Resolving sdpapi.ref.o2.co.uk... 82.132.158.136
Connecting to sdpapi.ref.o2.co.uk|82.132.158.136|:443... connected.
OpenSSL: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
Unable to establish SSL connection.
How to check
[tomcat@app4r certificates]$ openssl s_client -connect 82.132.158.136:443
CONNECTED(00000003)
depth=3 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
verify return:1
depth=2 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
verify return:1
depth=1 /C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
verify return:1
depth=0 /C=GB/ST=England/L=Berkshire/O=TELEFONICA UK LIMITED/OU=Operations/CN=sdpapi.ref.o2.co.uk
verify return:1
7172:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1086:SSL alert number 40
7172:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:
____________________________________________________________________________________________________
# sh catalina.sh run
How to take thread dump
# kill -3 java_pid ; tail –f catalina.out

HEAP

JCONSOLE ( Monitoring Heap Size & Garbage collector)
# ps -ef | grep java --- > get Java_PID
# /opt/jdk1.7.0_03/bin/jconsole Java_PID
# pkill jconsole


For the HotSpot Java VM:  The memory pools for serial garbage collection are the following.
Eden Space (heap): The pool from which memory is initially allocated for most objects.
Survivor Space (heap): The pool containing objects that have survived garbage collection of Eden space.
Tenured Generation or old Gen(heap): The pool containing objects that have existed for some time in the survivor space.
Permanent Generation (non-heap): The pool containing all the reflective data of the virtual machine itself, such as class and method objects. With Java VMs that use class data sharing, this generation is divided into read-only and read-write areas.
Code Cache (non-heap): The HotSpot Java VM also includes a code cache, containing memory that is used for compilation and storage of native code.

Garbage collection : In Java, the unused objects remain in memory until a garbage collection occurs and frees up the memory used by the objects.The garbage collection process is primarily governed by the configuration parameters of the heap. (Heap is that part of the physical memory which is used by the JVM to create objects).

Major GC vs Minor GC:
Young Generation is the pool of temporary objects which are not fully garbage collected initially. When these objects become old, they become part of the Old generation (This is referred as Minor GC) which are then fully garbage collected (referred as Major GC).
How to identify Major/Minor GC?
suppose you start your application as –
# java HelloWorld
to determine garbage collection, start your app as –
# java –verbose:gc HelloWorld
The output of above change should be something like –
GC 325407K-> 83000K (776768K), 0.2300771 secs
GC – Indicates that it was a minor collection (young generation).  If it had said Full GC then that indicates that it was a major collection (tenured generation).
325407K –  The combined size of live objects before garbage collection.
83000K –  The combined size of live objects after garbage collection.
(776768K) –  the total available space, not counting the space in the permanent generation, which is the total heap minus one of the survivor spaces.
0.2300771 secs – time it took for garbage collection to occur.

How to increase heap size in tomcat
Heap Size:  A Java Virtual Machine on 32-bit operating systems typically has a maximum heap size of 64Mb. The JVM heap space is where all Java objects are stored, as well as memory used by the garbage collector.
To increase min( -Xms) and max (-Xmx)  heap size, set the JAVA_OPTS
# vi /opt/tomcat_1/bin/catalina.sh
export JAVA_OPTS= -Xms256m -Xmx512m
How the things are in Production environment
# vi /app/tomcat-6.0.18/bin/catalina.sh
export JAVA_OPTS="-server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/tomcat-6.0.18/tomcat.hprof -Xms6144m -Xmx6144m -XX:MaxPermSize=512m -XX:NewRatio=2 -XX:SurvivorRatio=6 -Dcs.useEhcache=true -Dnet.sf.ehcache.enableShutdownHook=true -DnumOfDiskStores=10 -Dfile.encoding=UTF-8 -Dinsite.saveslotsonly=true -Dinsite.usemarkerassets=true"

How to monitor java heap configuration by Jmap
# ps -ef |grep java   -- >  root    6092     1  0 17:28 pts/3    00:00:01 /opt/jdk1.7.0_03/bin/java
# /opt/jdk1.7.0_03/bin/jmap -heap  6092
Attaching to process ID 6092, please wait...
Mark Sweep Compact GC
Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 266338304 (254.0MB)
   NewSize          = 1048576 (1.0MB)
   MaxNewSize       = 4294901760 (4095.9375MB)
   OldSize          = 4194304 (4.0MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 12582912 (12.0MB)
   MaxPermSize      = 67108864 (64.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 4980736 (4.75MB)
   used     = 1721760 (1.641998291015625MB)
   free     = 3258976 (3.108001708984375MB)
   34.56838507401316% used
Eden Space:
   capacity = 4456448 (4.25MB)
   used     = 1201520 (1.1458587646484375MB)
   free     = 3254928 (3.1041412353515625MB)
   26.961382697610293% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 520240 (0.4961395263671875MB)
   free     = 4048 (0.0038604736328125MB)
   99.2279052734375% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
tenured generation:
   capacity = 11075584 (10.5625MB)
   used     = 8240504 (7.858757019042969MB)
   free     = 2835080 (2.7037429809570312MB)
   74.40243331638314% used
Perm Generation:
   capacity = 12582912 (12.0MB)
   used     = 9002088 (8.585060119628906MB)
   free     = 3580824 (3.4149398803710938MB)
   71.54216766357422% used
Jinfo
# /opt/jdk1.7.0_03/bin/jinfo  6092
Attaching to process ID 6092, please wait...
JVM version is 22.1-b02
sun.boot.library.path = /opt/jdk1.7.0_03/jre/lib/i386
java.vm.vendor = Oracle Corporation
os.version = 2.6.18-164.el5
user.home = /root
user.timezone = Asia/Kolkata
java.specification.version = 1.7
catalina.home = /opt/tomcat_2
java.class.path = /opt/tomcat_2/bin/bootstrap.jar:/opt/tomcat_2/bin/tomcat-juli.jar
user.name = root
-Djava.util.logging.config.file=/opt/tomcat_2/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -


Automatically Generating a Heap Dump when OutOfMemory(OOM) Error
# vi /app/tomcat-6.0.18/bin/catalina.sh
export JAVA_OPTS="-server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/tomcat-6.0.18/tomcat.hprof

Manually Generating a Heap Dump
# ./jmap  –dump:file=<file_name>  <pid>
# ./jmap –dump:file=/opt/tomcat_2/tomcat.hprof  6092

Heap dump analysis by jhat
# cd /opt/jdk1.7.0_03/bin
# ./jhat -port 7000 /opt/tomcat_2/tomcat.hprof
Reading from /opt/tomcat_2/tomcat.hprof...
Started HTTP server on port 7000
Server is ready.
We can analysis heap dump on browser

Option and Default Value
Description
-XX:+AggressiveOpts
Turn on point performance compiler optimizations that are expected to be default in upcoming releases. (Introduced in 5.0 update 6.)
-XX:CompileThreshold=10000
Number of method invocations/branches before compiling [-client: 1,500]
-XX:MaxHeapFreeRatio=70
Maximum percentage of heap free after GC to avoid shrinking.
-XX:MaxNewSize=size
Maximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio. [1.3.1 Sparc: 32m; 1.3.1 x86: 2.5m.]
-XX:MaxPermSize=64m
Size of the Permanent Generation.  [5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.]
-XX:MinHeapFreeRatio=40
Minimum percentage of heap free after GC to avoid expansion.
-XX:NewRatio=2
Ratio of new/old generation sizes. [Sparc -client: 8; x86 -server: 8; x86 -client: 12.]-client: 4 (1.3) 8 (1.3.1+), x86: 12]
-XX:NewSize=2.125m
Default size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86: 1m; x86, 5.0 and older: 640k]
-XX:SurvivorRatio=8
Ratio of eden/survivor space size [Solaris amd64: 6; Sparc in 1.3.1: 25; other Solaris platforms in 5.0 and earlier: 32]
-XX:TargetSurvivorRatio=50
Desired percentage of survivor space used after scavenge.
-XX:-UseISM
Use Intimate Shared Memory
-XX:+UseLargePages
Use large page memory.
-XX:+UseStringCache
Enables caching of commonly allocated strings.
-XX:AllocatePrefetchLines=1
Number of cache lines to load after the last object allocation using prefetch instructions generated in JIT compiled code. Default values are 1 if the last allocated object was an instance and 3 if it was an array. 
Pause Time in GC: The length of time during which application execution is stopped while garbage
collection is occurring.
Design Choices
• Serial versus Parallel
With serial collection, while multiple CPUs are available, only one is utilized to perform the collection. When parallel collection is used, the task of garbage collection is split into parts and those subparts are executed simultaneously, on different CPUs. The simultaneous operation enables the collection to be done more quickly.
• Concurrent versus Stop-the-world
When stop-the-world garbage collection is performed, execution of the application is completely
suspended during the collection. Alternatively, one or more garbage collection tasks can be executed
concurrently, that is, simultaneously, with the application. Typically, a concurrent garbage collector
does most of its work concurrently, but may also occasionally have to do a few short stop-the-world
pauses. Stop-the-world garbage collection is simpler than concurrent collection, since the heap is
frozen and objects are not changing during the collection. Its disadvantage is that it may be
undesirable for some applications to be paused. Correspondingly, the pause times are shorter when
garbage collection is done concurrently, but the collector must take extra care, as it is operating over
objects that might be updated at the same time by the application. This adds some overhead to
concurrent collectors that affects performance and requires a larger heap size.
• Compacting versus Non-compacting versus Copying
After a garbage collector has determined which objects in memory are live and which are garbage, it
can compact the memory, moving all the live objects together and completely reclaiming the
remaining memory. After compaction, it is easy and fast to allocate a new object at the first free
location. A simple pointer can be utilized to keep track of the next location available for object
allocation. In contrast with a compacting collector, a non-compacting collector releases the space
utilized by garbage objects in-place, i.e., it does not move all live objects to create a large reclaimed
region in the same way a compacting collector does. The benefit is faster completion of garbage
collection, but the drawback is potential fragmentation. In general, it is more expensive to allocate
from a heap with in-place deallocation than from a compacted heap. It may be necessary to search the
heap for a contiguous area of memory sufficiently large to accommodate the new object. A third
alternative is a copying collector, which copies (or evacuates) live objects to a different memory area.
The benefit is that the source area can then be considered empty and available for fast and easy
subsequent allocations, but the drawback is the additional time required for copying and the extra
space that may be required.

GC Logs
8746.664: [GC 8746.664: [ParNew: 1118528K->6000K(1258304K), 0.0692770 secs] 1118528K->6000K(4054528K), 0.0693720 secs] [Times: user=0.13 sys=0.01, real=0.08 secs]
19625.935: [Full GC 19625.935: [CMS: 0K->5886K(2796224K), 0.1273050 secs] 244248K->5886K(4054528K), [CMS Perm : 21247K->21092K(21248K)], 0.1274740 secs] [Times: user=0.10 sys=0.02, real=0.13 secs]
19626.075: [GC [1 CMS-initial-mark: 5886K(2796224K)] 17295K(4054528K), 0.0008640 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
19626.076: [CMS-concurrent-mark-start]
19627.828: [Full GC 19627.828: [CMS19627.890: [CMS-concurrent-mark: 0.062/1.814 secs] [Times: user=2.69 sys=0.07, real=1.82 secs]
21155.807: [CMS-concurrent-mark-start]
21155.912: [CMS-concurrent-mark: 0.105/0.105 secs] [Times: user=0.20 sys=0.01, real=0.10 secs]
21155.912: [CMS-concurrent-preclean-start]
21155.962: [CMS-concurrent-preclean: 0.047/0.050 secs] [Times: user=0.09 sys=0.00, real=0.05 secs]
21155.962: [CMS-concurrent-abortable-preclean-start]
 CMS: abort preclean due to time 21160.988: [CMS-concurrent-abortable-preclean: 0.421/5.026 secs] [Times: user=0.90 sys=0.02, real=5.03 secs]
21160.988: [GC[YG occupancy: 530699 K (1258304 K)]21160.988: [Rescan (parallel) , 0.1831550 secs]21161.172: [weak refs processing, 0.0000470 secs] [1 CMS-remark: 9334K(2796224K)] 540034K(4054528K), 0.1833000 secs] [Times: user=0.19 sys=0.00, real=0.18 secs]
21161.172: [CMS-concurrent-sweep-start]
21161.178: [CMS-concurrent-sweep: 0.006/0.006 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
21161.178: [CMS-concurrent-reset-start]
21161.184: [CMS-concurrent-reset: 0.006/0.006 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
Heap
 par new generation   total 1258304K, used 733988K [0x00000006e0000000, 0x0000000735550000, 0x0000000735550000)
  eden space 1118528K,  65% used [0x00000006e0000000, 0x000000070ccc9318, 0x0000000724450000)
  from space 139776K,   0% used [0x000000072ccd0000, 0x000000072ccd0000, 0x0000000735550000)
  to   space 139776K,   0% used [0x0000000724450000, 0x0000000724450000, 0x000000072ccd0000)
 concurrent mark-sweep generation total 2796224K, used 9285K [0x0000000735550000, 0x00000007e0000000, 0x00000007e0000000)
 concurrent-mark-sweep perm gen total 94332K, used 62446K [0x00000007e0000000, 0x00000007e5c1f000, 0x0000000800000000)

Enable GC (Garbage Collector) in Tomcat
# vi catalina.sh
Export JAVA_OPTS= -Xloggc: /app/tomcat-6.0.18/CS7.0/cs_tomcat/logs/gc.log  -verbose:gc -XX:+PrintGCDetails  -XX:+PrintGCTimeStamps
Here -Xloggc: is path of GC logs
-verbose:gc
Prints some GC info
-XX:+PrintHeapAtGC
Prints detailed GC info including heap occupancy before and after GC
-XX:+PrintGC
Outputs basic information at every garbage collection
-XX:+PrintGCDetails
Provide information such as the size of live objects before and after garbage collection for the various generations, the total available space for each generation, and the length of time the collection took.
-XX:+PrintGCTimeStamps
Prints the garbage collection time stamps to help with debugging.

Partial garbage collection:
1.612: [GC [PSYoungGen: 12998K->1568K(18496K)] 12998K->1568K(60864K),0.0054130 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
Full garbage collection:
1.617: [Full GC (System) [PSYoungGen: 1568K->0K(18496K)] [PSOldGen: 0K->1483K(42368K)] 1568K->1483K(60864K) [PSPermGen: 9458K->9458K(21248K)],0.0294590 secs] [Times: user=0.02 sys=0.00, real=0.03 secs]



Types of Garbage Collector
The Serial Collector: -XX:+UseSerialGC
(default  & stop-the-world collector)
1. Uses only one GC thread for the GC operation
2. Used for small application.
3. Tenured Generation GC done in serial threads.
The Parallel Collector(Throughput Collector): -XX:+UseParallelGC
(stop-the-world collector)
1. Uses multiple GC threads for the GC operation .
2. Young Generation GC done in parallel threads
Parallel Old Generation Collector:                                   -XX:+UseParallelOldGC
1. This garbage collector is set for high throughput
2. Certain phases of an ‘Old Generation’ collection can be performed in parallel, speeding up a old generation collection..
The Concurrent Low Pause Collector(CMS):                            -XX:+UseConcMarkSweepGC
Steps of GC: - initial mark, - concurrent marking, - remark, - concurrent sweeping
1. Uses only one GC thread for the GC operation
2. This garbage collector is set for low pause time. It will result in a Java application that has a lower average throughput, but much   shorter CPU-intensive garbage collections. This option is required in environments that have response time constraints.
Incremental Low Pause Collector: -XX:+UseTrainGC
Serial vs Parallel collector
Ø  Both the serial and parallel collectors cause a stop-the-world during the GC.  A serial collector is a default copying collector which uses only one GC thread for the GC operation, while a parallel collector uses multiple GC threads for the GC operation.
Parallel vs CMS collectors:
Ø  The parallel is a 'stop-the-world' collector, while the CMS stops the world only during the initial mark and remark phases. During the concurrent marking and sweeping phases, the CMS thread runs along with the application's threads.

if you wish to combine both parallelism and concurrency in your GC, you can use the following:
-XX:UserParNewGC for the new generation (multiple GC threads)
-XX:+UseConcMarkSweepGC for the old generation (one GC thread, freezes the JVM only during the initial mark and remark phases)

Collectors operate on the young generation: -XX:+UseSerialGC, -XX:+UseParallelGC, XX:+UseParNewGC
Collectors operate on the old generation: -XX:+UseParallelOldGC, -XX:+UseConcMarkSweepGC
Thread States: There are 6 thread states
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
Download jtda-cli.jar
To see the usage: /usr/java/jdk1.6.0_06/bin/java -jar jtda-cli.jar –help
To Analyze thread tump: # cat catalina.out_23_05_2013_02 | /usr/java/jdk1.6.0_06/bin/java -jar jtda-cli.jar
____________________________________________________________________________________________________
Tomcat with LDAP integration
# vi /opt/apache-tomcat-7.0.28/conf/server.xml
  <Realm className="org.apache.catalina.realm.JNDIRealm" debug="99"
       connectionName="cn=Manager,dc=example,dc=com"
       connectionPassword="vivek"
       connectionURL="ldap://localhost:389"
       userPattern="uid={0},dc=example,dc=com"
       roleBase="dc=example,dc=com"
       roleName="cn"
       roleSearch="memberUid={1}"/>

# vi ../webapps/ROOT/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true">
  <display-name>Welcome to Tomcat</display-name>
  <description> Welcome to Tomcat</description>
<security-constraint>
    <web-resource-collection>
          <web-resource-name>Logging Area</web-resource-name>
          <description>
              Authentication for registered users.
          </description>
          <url-pattern>/*</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
    </web-resource-collection>
        <auth-constraint> <role-name>*</role-name> </auth-constraint>
    </security-constraint>
<security-role>  <role-name>*</role-name>  </security-role>
    <login-config>
          <auth-method>BASIC</auth-method>
        <realm-name>Please enter your Username</realm-name>
</login-config>
</web-app>

# ./catalina.sh start; tail -f ../logs/catalina.out
Now once we start the Tomcat and visit your website, following popup will be shown.
____________________________________________________________________________________________________
Single Sign-On Implementation
Using Single Sign-on, it is possible to eliminate this annoying repetition (provided the user name and password are identical for each sign-on, and usually authenticating against the same Tomcat Realm).
The Single Sign-on Valve caches credentials (passwords) on the server side, and will invisibly authenticate users as they traverse between Web applications on a given virtual host. Without activating this Valve, the user will be prompted to authenticate for each and every protected Web application

<Host name="localhost" ...>
  ...
  <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
  ...
</Host>
Attribute
Description
className
Java class name of the implementation to use. This MUST be set toorg.apache.catalina.authenticator.SingleSignOn.
requireReauthentication
Default false. Flag to determine whether each request needs to be reauthenticated to the securityRealm. If "true", this Valve uses cached security credentials (username and password) to reauthenticate to the Realm each request associated with an SSO session. If "false", the Valve can itself authenticate requests based on the presence of a valid SSO cookie, without rechecking with the Realm.
cookieDomain
Sets the host domain to be used for sso cookies.

How SSO work in two applications

Web Application A (http://WebApplicationA/)
Web Application B (http://WebApplicationB/)

User logs into Web Application A. He clicks on a link inside Web Application A page (of the kind): http://WebApplicationB/go?sessionId=ABC&user=me@me.com

When Application B receives this request, it makes a http call to Application A to verify this information.
In other words it sends a http request (server to server) like: http://WebApplicationA/verifyUserSession?sessionId=ABC&user=me@me.com. WebApplication A checks its list of logged-in users/sessions and responds with a VERIFIED or FAILURE.

If the response was VERIFIED, WebApplicationB knows this is a logged in user inside WebApplicationA - and it proceeds to create a session for the user, and allows him in. 


Configuring Customized User Directories
Some sites like to allow individual users to publish a directory of web pages on the server. For example, a university department might want to give each student a public area, or an ISP might make some web space available on one of its servers to customers that don't have a virtually hosted web server. In such cases, it is typical to use the tilde character (~) plus the user's name as the virtual path of that user's web site:
http://www.cs.myuniversity.edu/~username
http://members.mybigisp.com/~username
Tomcat gives you two ways to map this on a per-host basis, using a couple of special Listener elements. The Listener'sclassName attribute should be org.apache.catalina.startup.UserConfig, with the userClass attribute specifying one of several mapping classes. If your system runs Unix, has a standard /etc/passwd file that is readable by the account running Tomcat, and that file specifies users' home directories, use the PasswdUserDatabase mapping class:
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html"
userClass="org.apache.catalina.startup.PasswdUserDatabase"/>
Web files would need to be in directories such as /home/users/ian/public_html or /users/jbrittain/public_html. Of course, you can change public_html to be whatever subdirectory into which your users put their personal web pages.
In fact, the directories don't have to be inside of a user's home directory at all. If you don't have a password file but want to map from a user name to a subdirectory of a common parent directory such as /home, use the HomesUserDatabase class:
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html" homeBase="/home"
userClass="org.apache.catalina.startup.HomesUserDatabase"/>
In this case, web files would be in directories such as /home/ian/public_html or /home/jasonb/public_html. This format is more useful on Windows, where you'd likely use a directory such as C:\home.
These Listener elements, if present, must be inside of a Host element, but not inside of a Context element, as they apply to theHost itself.

Tomcat Interview Questions Link

# vi .bash_profile
export ANT_HOME=/opt/apache-ant-1.9.1/
export PATH=$ANT_HOME/bin:$PATH
export JAVA_HOME=/usr/jdk1.7.0_03/

# vi /opt/build/build.xml
<?xml version="1.0"?>
<project name="my-app" basedir="." default="usage">
  <property file="build.properties"/>
<path id="catalina-ant-classpath">
    <fileset dir="${tomcat.lib}">
        <include name="catalina-ant.jar"/>
        <include name="tomcat-coyote.jar"/>
        <include name="tomcat-util.jar"/>
    </fileset>
    <fileset dir="${tomcat.bin}">
                <include name="tomcat-juli.jar"/>
    </fileset>
</path>
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask">
       <classpath refid="catalina-ant-classpath"/>
    </taskdef>
<target name="deploy">
<copy file="sample.war" todir="${tomcat.deployment}"/>
<antcall target="startTomcat"/>
</target>
<target name="startTomcat">
<exec executable="${tomcat.bin}/startup.sh"/>
</target>
<target name="stopTomcat">
<exec executable="${tomcat.bin}/shutdown.sh"/>
</target>
</project>

# vi /opt/build/build.properties
tomcat=/opt/apache-tomcat-7.0.40/
tomcat.lib=${tomcat}/lib
tomcat.deployment=${tomcat}/webapps
tomcat.bin=${tomcat}/bin

Put sample.war into /opt/build/
# ant deploy