So it's a nice opportunity to use it writing units to test servlets, rest api etc..
But until 7.0.25 it was only possible to do it with using a barcoding port which can cause some issues on ci servers where you are not sure ports are not used by something else running.
I have personally sended a RFC to ITEF to have port allocation for only my personal use on my birthday year or zip code port but strangely this RFC was never approved :-).
Now you can use the java ServerSocket port 0 feature to use any free port available on the machine.
It has been fixed with the issue 52028.
So now you can write a unit test as it (here a test with a REST service provided by Apache CXF).
@Before
public void startTomcat()
throws Exception
{
tomcat = new Tomcat();
tomcat.setBaseDir( System.getProperty( "java.io.tmpdir" ) );
tomcat.setPort( 0 );
Context context = tomcat.addContext( "", System.getProperty( "java.io.tmpdir" ) );
A context param in your web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring-context.xml</param-value>
</context-param>
In the code
ApplicationParameter applicationParameter = new ApplicationParameter();
applicationParameter.setName( "contextConfigLocation" );
applicationParameter.setValue( "classpath*:META-INF/spring-context.xml" );
context.addApplicationParameter( applicationParameter );
A listener class in your web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
In the code
context.addApplicationListener( ContextLoaderListener.class.getName() );
CXF servlet declaration in your web.xml:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/restServices/*</url-pattern>
</servlet-mapping>
In the code:
tomcat.addServlet( context, "cxf", new CXFServlet() );
context.addServletMapping( "/restServices/*", "cxf" );
tomcat.start();
port = tomcat.getConnector().getLocalPort();
System.out.println("Tomcat started on port:"+port);
}
So now you can test/consume you REST services on localhost with the port.
Don't miss to shutdown the tomcat instance on tearDown or @After
@After
public void stopTomcat()
throws Exception
{
tomcat.stop();
}
If you use Maven you need the following dependencies:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
As samples talks more than long docs ("Code talks, bullshit walks" :-) ).
The tomcat maven archetype has been improved with a sample. (see previous post)
Have Fun!