Tomcat – How To’s

Application Lifecycle

How to create a new application in my Tomcat instance

At its most basic, simply place your WAR file in the webapps directory of your instance. See Deploying Applications for the details. However, if you stop here, your application will only be accessible by URLs that identify your Tomcat instance by port such as:

https://tomcat.www.purdue.edu:8445/Confluence

If you notify Web Services of your application’s name, we will add it to a list in the F5 load balancers so that the port number is no longer needed yielding a URL like:

https://tomcat.www.purdue.edu/Confluence/

How to deploy my application to qa and/or production

Use the Web Services Deploy Tool. Unique to the Tomcat environment, there is a roll-back option after you have deployed your application provided you do not leave the final screen. This allows you to confirm that your application launched successfully and is operating normally before you commit.

How to retire an application in my Tomcat instance

For the development server, you can simply remove the WAR file from the webapps directory of your instance. Tomcat will notice and will clean up the unpacked application.

For the qa and production servers, please contact Web Services to request that we remove the application. If you intend to retire the application permanently, please also let us know that we can remove the mapping in the F5 that masks the port numbers in URLs.

How to tell which tier my application is running in

We provide a Java system property that can be read to determine which tier is currently running your application. We recommend that you keep tier-specific functionality to a minimum, but recognize that selected URLs or other values may need to be different between development, qa, and production.

You can access the property with

System.getProperty("edu.purdue.itap.itso.webservices.Tier");

The returned valued will be

edu.purdue.itap.itso.webservices.Tier Property Values
Value Service Tier
dev Development
qa QA
prod Production

 

Database Connections

How to request a database connection

Web Services will create a JNDI reference in your Tomcat instance for your application. To do this, we need to know the type of database (mySQL, Oracle, SQL Server, etc.), the name of the database, the server hosting the database, the database username, the database password, and what JNDI reference you want the database to have. Send this information (DO NOT INCLUDE THE PASSWORD!) to Web Services to create a ticket. We will contact you to obtain the appropriate password via secure means.

For example, to access an Oracle database named mydatabase hosted by ITaP’s DBA group, you would request:

Dbase Type: Oracle 
Dbase Name: mydatabase 
Dbase Host: ITaP Oracle 
Dbase User: db_user 
Dbase Password: DO NOT PROVIDE THIS IN EMAIL!!! 
JNDI name: jdbc/myjndi

Or, if the same database were served by ITaP’s DBA group as a SQL Server database, you would request:

Dbase Type: SQL Server 
Dbase Name: mydatabase 
Dbase Host: itassqlprod01 
Dbase User: db_user 
Dbase Password: DO NOT PROVIDE THIS IN EMAIL!!!
JNDI name: jdbc/myjndi

DO NOT send the database password in email or in a ticket! Instead, send the message or create the ticket, and when we receive it, we’ll call you for the password (the username is safe). Also, if you do not know the database hostname and ITaP hosts the database, just tell us that and we’ll work with the DBAs to identify the host.

How to reference this JNDI

Add one or more ResourceLink entries to your META-INF/context.xml file such as:

<?xml version="1.0" encoding="UTF-8"?>

<Context> 
    <ResourceLink
        name="jdbc/ics/infdbd"
        global=jdbc/ics/infdbd"
        type="javax.sql.DataSource" />
</Context>

The name field specifies what the resource is known to your application by (what’s in your web.xml file), and the global field specifies what the resource is known by to the server (what’s in server.xml). Finally, the type field specifies what Java type the resource is.

The Java Security Manager

How to figure out what permissions my code needs

My instance uses the Java Security Manager. How do I figure out what permissions my code needs? It seems to run okay in development.

Because the Java Security Manager is unforgiving about policy violations, it makes developing code a chore. You have to deal with determining if the reason your application failed was a security violation or due to a problem with your code. Then, if the problem is a security violation, you have to wait for the policy to be updated to allow the operation. This kind of start-stop development would be counter productive and frustrating for developers. We have developed a profiling security manager that runs on our development machine. It follows two basic rules:

  1. If the real security manager would allow the operation, then allow the operation.
  2. If the real security manager would forbid the operation, then log the permissions needed and allow the operation.

This allows developers to work on their code without worrying about the security policies initially. Then, once you have the code working, you’ll need to profile it by clearing a cache that the security manager maintains (to prevent too many repeated messages), and fully exercise your code, exploring all code paths you possibly can. Once completed, the resulting log can be used by Web Services to update the security policy on development, qa, and production to allow the needed operations. While it should be possible to migrate your code to qa from there and not have any security policy issues, it would be wise to profile it again to ensure that no additional permissions were missed.

Once the code goes to qa, the real security manager is in charge and any security exceptions will result in your application being halted. Code that runs cleanly (no security exceptions) under qa will run cleanly on production as well because the security policies will be identical. While profiling a new application may involve a fair amount of effort, profiling of updates to applications will be made easier by the fact that most of the permissions needed will already have been allowed and only new permissions will need to be identified.

Logging

How to configure and use logging in my application

First, do not use “system.out()”. This sends the output to Tomcat’s stdout file descriptor which then gets intermingled with other output from Tomcat. This will not only make it harder for you to find your logging output, but it will also cause the file that captures this output to grow unnecessarily. Besides, by using a logging package, you can embed verbose logging into your application to help you during development and debugging, and then select the level of output you actually want for production without changing your code.

You should configure your logging to be placed in a file in CATALINA_BASE/logs/applogs. The Java Security Manager has been configured to allow this. If you attempt to put them elsewhere, it will likely result in security exceptions.

JULI Logging

If you are using JULI logging, you will need to place a logging.properties file in either your application’s WEB-INF directory or in $CATALINA_BASE/lib. We recommend placing a default logging configuration file in the lib directory so that all applications have a basic logging facility available, then placing an application-specific configuration in the application’s WEB-INF to override these defaults where desired. Here is an example logging.properties file:

handlers = org.apache.juli.FileHandler

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

org.apache.juli.FileHandler.level = FINE
org.apache.juli.FileHandler.directory = ${catalina.base}/logs/applogs
org.apache.juli.FileHandler.prefix = logDemo1.

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/myApp].level = INFO

Please do not include a handler for the console (org.apache.juli.ConsoleHandler) as this will cause logging information to once again go to Tomcat’s stdout file descriptor. This logging configuration will create a file called myApp.2008-04-15.log (with the current date, of course) in the log/applogs directory. The level of logging that actually makes it to the log can be set to one of:

  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST

You can also use the facility specific properties (the last commented line) to make changes to the logging for specific applications in a shared configuration environment. See http://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html for details on JULI logging.

Log4J Logging

If you are using Log4J logging, you will need to place a log4j.properties file in either your application’s WEB-INF directory or in $CATALINA_BASE/lib. We recommend placing a default logging configuration file in the shared directory so that all applications have a basic logging facility available, then placing an application-specific configuration in the application’s WEB-INF to override these defaults where desired. Here is an example log4j.properties file:

log4j.rootLogger=ERROR, R

# ***** R is set to be a RollingFileAppender.
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.base}/logs/applogs/myApp.log

# ***** Max file size is set to 100KB
log4j.appender.R.MaxFileSize=100KB

# ***** Keep one backup file
log4j.appender.R.MaxBackupIndex=1

# ***** R uses PatternLayout.
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d [%c] %p - %m%n

This will create a file called myApp.log in the log/applogs directory that will be automatically rolled to a new log file when it reaches 100K with one backup copy. Lines in the file will look like:

2008-04-08 12:21:41,298 [MyClass] FATAL – This is my fatal message.

See https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html for details about the various pattern values you can use to format your log to your liking.

Change the word “ERROR” on the first line to one of:

  • FATAL
  • ERROR
  • WARN
  • INFO
  • DEBUG
  • TRACE
  • ALL

to control how much logging actually gets to your log file.