Friday, 3 June 2011

Setting up our spring integration apps to run under jboss:

I found setting up my spring app with jboss 5 and maven tricky. You'll need to produce a war file in maven to deploy to the jboss server. Take the following steps:
 Ensure you have
<packaging>war</packaging>
near the top of you pom
 Then add the following plugin:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>

 Add the following directory structure to your existing maven project:

src/main --
|-- webapp
|
|----- WEB-INF
| |-- web.xml
| |-- lib
| |--- <libraries will eventually automatically be added here by the war plugin>
|----- jsp
|--- <you can put a jsp page here so you can verify your app is up once you deploy>

 Now add the web.xml file described in the structure above with contents similar to this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
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">
<display-name>app</display-name>

<!-- Configure the location of the Spring application context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/app.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Configure Log4j to get Configuration From Central Area -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>file:${log4j.calculation.filePath}</param-value>
</context-param>

<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>

<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>1000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener> -->

<!-- Status page accessed at http://hostname:port/CGO-calculation
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

 For the logging you cannot refer to a classpath resouce (at least I couldn't ... anyone who cracks this let me know).
 Also I couldn't get jboss to call a main class or pass arguments arguments to my app, so you'll have to:
 Use the maven variable sub stitution to have your app pull in its environment specific config files. e.g. put a variable like ${dbadaptor.release.env} in your config file and then when you build from maven do something like this ... mvn clean install -Ddbadaptor.release.env=dev. For this to work you'll need to say in your pom which sets of files are eligable for substitution like this using the tag when declaring resources:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>

 Allow jboss to instantiate your spring context directly. This is in the web.xml above in this piece:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/databaseAdaptor.xml</param-value>
</context-param>
 Jboss ships with its own xerces xml parsers. If you package your war with the xerces and xml apis you'll get an error when you try to deploy to jboss. Exclude the libraries from the war build in your pom like this with the scope tag in the dependency (it won't affect your local running, although it may affect a one-jar that you produce (if you ever need to)):

<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.6.2</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.0.b2</version>
<scope>provided</scope>
</dependency>
 Jboss also ships with its own log4j jars and prevents you from accessing your own in the war lib directory. Not only this, if you include the logging jars in your war lib directory your own classpath will resolve to these jars even though at a later time jboss will prevent them from being accessed, so you need to exclude these from your war also (again using the scope tag):

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
<scope>provided</scope>

<exclusions>
<exclusion>
<groupId>apache-log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>

<exclusion>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
</exclusion>

<exclusion>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
</exclusion>

<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>

</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>

 Using standalone MBeans servers like mx4j will cause issues with jboss so your better off just using the jboss jmx service and get rid of the former from your spring context
 Once you run your maven build (mvn clean install), a *.war file will appear in your ./target directory. Copy this to your jboss server deploy directory (/server/default/deploy) and when you start jboss it should pick it up (this last step will be slightly different when we move from local application server to the jfarms ... once we get the jfarms we can update here)

No comments:

Post a Comment