Background
Recently we’ve just integrated a new Dev, Cert, Production environment in which we use:
- Java
- Spring
- Maven
- Eclipse
Using Jetty for development and Tomcat for deployment. In hindsight that statement is a dead giveaway that problems are forthcoming. Since usually it’s a good idea to use the same kind of environment for Dev, Cert and Prod.
Previous Jetty Pluggin Configuration:
Here is the plugin configuration we used for a Jetty (SSL only) configuration inside of our pom.xml/project/build/plugins:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<contextPath>/</contextPath>
<connectors>
<connector implementation="org.mortbay.jetty.security.SslSocketConnector">
<port>8002</port>
<maxIdleTime>60000</maxIdleTime>
<keystore>${project.build.directory}/secure.server/WEB-INF/classes/jetty-ssl.keystore</keystore>
<password>jetty6</password>
<keyPassword>jetty6</keyPassword>
</connector>
</connectors>
</configuration>
</plugin>
Goal – Overridden Resources
We develop in as modular fashion as possible so some projects provide “Default configurations” that are expected to be overriden by consuming projects. Things such as properties files and spring configurations.
Example:
Project A has settings.properties in the resulting jar classes directory and
Project B also has an override version of settings.properties in it’s resulting classes directory.
This is an integral part of our deployment process allowing us to keep cert and prod passwords out of the main project where developers will see.
Symptoms
We found that during development sometimes our override settings would be ignored and the “default configuration” would be used. To be clear:
Project A\classes has:
\settings.properties
\some classes and packages
Project B\classes has:
\settings.properties
\some other classes and packages
When we tried to access settings.properties in the classpath spring at runtime, sometimes the Project A version was used and sometimes the Project B version was used.
Example spring Include:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:settings.properties" />
</bean>
<bean id="testStringValue" class="java.lang.String">
<constructor-arg index="0" value="${test.string.value}" />
</bean>
Example properties file:
test.string.value=String Value 1
Found Issue
After lots of troubleshooting, we ruled out both Spring and Maven as the culprit. Using test classes in Maven to run the SAME test code worked perfectly (used Project B version), while for some reason using “mvn jetty:run” to have the same code invoked FAILED as stated above.
We therefore found that Jetty was actually the issue, likely boiling down to one of these things:
- the out of the box configuration
- a shortcoming in Jetty
- or the Maven Jetty pluggin
Resolution
We switched to tomcat development/testing environment by using “mvn tomcat:run” to test and this configuration instead: (Cofigured to be SSL only)
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<path>/</path>
<httpsPort>8443</httpsPort>
<port>0</port>
<keystoreFile>${project.build.directory}/secure.server/WEB-INF/classes/jetty-ssl.keystore</keystoreFile>
<keystorePass>jetty6</keystorePass>
</configuration>
</plugin>