Enterprise Java

Run java web apps in embedded containers with Maven, Jetty and Tomcat

While developing java web applications is very practical to have quick feedback from a “real” environment. In this post I’ll explore how to run a java web application with Maven in an embedded container be it Jetty or Tomcat.  I’ll show how I have configured them for the development of podcastpedia project backing the Podcastpedia.org website.

Prerequisites

You should have Maven and  at least Java 7 installed. Ideally you could setup up the podcastpedia project yourself to see it in action.

Jetty Maven Plugin

Plugin Configuration

<!-- http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html -->
<plugin>
	<groupId>org.eclipse.jetty</groupId>
	<artifactId>jetty-maven-plugin</artifactId>
	<version>${jetty.version}</version>
	<configuration>
		<jettyConfig>${project.basedir}/src/main/resources/config/jetty9.xml</jettyConfig>
		<stopKey>STOP</stopKey>
		<stopPort>9999</stopPort>
		<scanIntervalSeconds>5</scanIntervalSeconds>
		<scanTargets>
			<scanTarget>${project.basedir}/src/main</scanTarget>
			<scanTarget>${project.basedir}/src/test</scanTarget>
		</scanTargets>
		<contextXml>${project.basedir}/src/test/resources/jetty-context.xml</contextXml>
		<webAppConfig>
			<contextPath>/</contextPath>
		</webAppConfig>
	</configuration>
	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.connector.java.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>${java.mail.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jdbc</artifactId>
			<version>${tomcat.jdbc.version}</version>
		</dependency>
	</dependencies>
</plugin>

Notes:

  • jettyConfig points to the Jetty configuration file; see next section for more explanations
  • defined folders (scanTargets) where Jetty looks for changes every 5 seconds (scanInterval)
  • defined external dependencies to connect to database and send email

Jetty.xml configuration file

Jetty xml configuration file

<?xml version="1.0" encoding="UTF-8"?>
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
	<New id="pcmdbDS" class="org.eclipse.jetty.plus.jndi.Resource">
		<Arg>jdbc/pcmDB</Arg>
		<Arg>
			<New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
				<Set name="Url">jdbc:mysql://localhost:3307/pcmDB?allowMultiQueries=true
				</Set>
				<Set name="User">pcm</Set>
				<Set name="Password">pcm_pw</Set>
			</New>
		</Arg>
	</New>
	<New id="mailSessionId" class="org.eclipse.jetty.plus.jndi.Resource">
		<Arg>mail/Session</Arg>
		<Arg>
			<New class="org.eclipse.jetty.jndi.factories.MailSessionReference">
				<Set name="user">test-dev@podcastpedia.org</Set>
				<Set name="password">test-dev</Set>
				<Set name="properties">
					<New class="java.util.Properties">
						<Put name="mail.host">mail.podcastpedia.org</Put>
						<Put name="mail.debug">true</Put>
						<Put name="mail.transport.protocol">smtp</Put>
						<Put name="mail.smtp.port">25</Put>
						<Put name="mail.smtp.auth">true</Put>
					</New>
				</Set>
			</New>
		</Arg>
	</New>
</Configure>

In the Jetty configuration file (jetty.xml) you have the following configured:

  • The Server class (or subclass if extended) and global options.
  • A ThreadPool (min and max thread).
  • Connectors (ports, timeouts, buffer sizes, protocol).
  • The handler structure (default handlers and/or a contextHandlerCollections).
  • The deployment manager that scans for and deploys webapps and contexts.
  • Login services that provide authentication checking.
  • A request log.

Apache Tomcat Maven Plugin

Apache Tomcat Maven Plugin Configuration

<!-- https://tomcat.apache.org/maven-plugin-trunk/index.html -->
<plugin>
	<groupId>org.apache.tomcat.maven</groupId>
	<artifactId>tomcat7-maven-plugin</artifactId>
	<version>2.2</version>
	<configuration>
		<!-- http port -->
		<port>8080</port>
		<!-- application path always starts with /-->
		<path>/</path>
		<!-- optional path to a context file -->
		<contextFile>context.xml</contextFile>
		<!-- optional system propoerties you want to add -->
		<systemProperties>
			<appserver.base>${project.build.directory}/appserver-base</appserver.base>
			<appserver.home>${project.build.directory}/appserver-home</appserver.home>
			<derby.system.home>${project.build.directory}/appserver-base/logs</derby.system.home>
			<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
		</systemProperties>
		<!-- if you want to use test dependencies rather than only runtime -->
		<useTestClasspath>false</useTestClasspath>
		<!-- optional if you want to add some extra directories into the classloader -->
		<additionalClasspathDirs>
			<additionalClasspathDir></additionalClasspathDir>
		</additionalClasspathDirs>
	</configuration>
	<!-- For any extra dependencies needed when running embedded Tomcat (not WAR dependencies) add them below -->
	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.connector.java.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>${java.mail.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jdbc</artifactId>
			<version>${tomcat.jdbc.version}</version>
		</dependency>
	</dependencies>
</plugin>

Notes

  • specify port where Tomcat runs
  • specify contextFile where Tomcat looks for configuration
  • defined external dependencies to connect to database and send email

Context.xml

<Context>
  <Resource
            name="jdbc/pcmDB"
            auth="Container"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            initialSize="5"
            maxActive="55"
            maxIdle="21"
            minIdle="13"
            timeBetweenEvictionRunsMillis="34000"
            minEvictableIdleTimeMillis="55000"
            validationQuery="SELECT 1"
            validationInterval="34"
            testOnBorrow="true"
            removeAbandoned="true"
            removeAbandonedTimeout="233"
            username="pcm"
            password="pcm_pw"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3307/pcmDB?allowMultiQueries=true"
   /> 

	<Resource name="mail/Session" auth="Container"
	            type="javax.mail.Session"
		        username="test-dev@podcastpedia.org"
		        password="test-dev"	            
	            mail.smtp.host="mail.podcastpedia.org"
	            mail.smtp.port="25"
	            mail.smtp.user="test-dev@podcastpedia.org"
	            mail.transport.protocol="smtp" 
	            mail.smtp.auth="true"
	/> 
</Context>

In context.xml there are defined the database and email resources.

There you go… Java webapps powered by Spring Framework running light servlet containers posing a true alternative to JAVA EE servers and all the costs that come with them.

Note:
These are simple configurations, but suffice for current development. My advice is to read the corresponding documentation for more advanced options and capabilities.

Resources

  1. Jetty Maven Plugin
  2. Apache Tomcat Maven Plugin

Adrian Matei

Adrian Matei (ama [AT] codingpedia DOT org) is the founder of Podcastpedia.org and Codingpedia.org, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Leonardo
Leonardo
8 years ago

Hello, thanks for your post.
How do I run the application?
Thanks.

Back to top button