We have the usual web.xml for our web application which includes some jsp and jsp tag files. I want to switch to using pre-compiled jsp's. I have the pre-compilation happening in the build ok, and it generates the web.xml fragment and now I want to merge the fragment into the main web.xml.
Is there an include type directive for web.xml that will let me include the fragment.
Ideally I will leave things as is for DEV- as its useful to change jsp's on the fly and see the changes immediately but then for UAT/PROD, the jsp's will be pre-compiled and thus work faster.
Doh - there is an option on the jasper2 task to auto-merge the fragment into the main web.xml - addWebXmlMappings
<jasper2
validateXml="false"
uriroot="${web.dir}"
addWebXmlMappings="true"
webXmlFragment="${web.dir}/WEB-INF/classes/jasper_generated_web.xml"
outputDir="${web.dir}/WEB-INF/jsp-src" />
I wonder how good the merge is...
Annoyingly you need to generate the fragment still, even though its not needed after this task.
I use the Tomcat jasper ANT tasks in my project, which precompile the JSPs into servlets and add the new servlet mappings to the original web.xml. In the DEV builds, just skip this step and deploy the JSPs without pre-compile and modification of the web.xml.
<?xml version="1.0"?>
<project name="jspc" basedir="." default="all">
<import file="${build.appserver.home}/bin/catalina-tasks.xml"/>
<target name="all" depends="jspc,compile"></target>
<target name="jspc">
<jasper
validateXml="false"
uriroot="${build.war.dir}"
webXmlFragment="${build.war.dir}/WEB-INF/generated_web.xml"
addWebXmlMappings="true"
outputDir="${build.src.dir}" />
</target>
<target name="compile">
<javac destdir="${build.dir}/classes"
srcdir="${build.src.dir}"
optimize="on"
debug="off"
failonerror="true"
source="1.5"
target="1.5"
excludes="**/*.smap">
<classpath>
<fileset dir="${build.war.dir}/WEB-INF/classes">
<include name="*.class" />
</fileset>
<fileset dir="${build.war.lib.dir}">
<include name="*.jar" />
</fileset>
<fileset dir="${build.appserver.home}/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${build.appserver.home}/bin">
<include name="*.jar"/>
</fileset>
</classpath>
<include name="**" />
<exclude name="tags/**"/>
</javac>
</target>
<target name="clean">
<delete>
<fileset dir="${build.src.dir}"/>
<fileset dir="${build.dir}/classes/org/apache/jsp"/>
</delete>
</target>
</project>
If you already have the JSP compilation working and just want to merge the web.xml files, a simple XSLT could be written to add selected elements(such as the servlet mappings) from the newly generated web,xml into your original.
Because the generated fragment is not a valid XML file ( it's a fragment after all ), it is not possible to use XSLT directly. On the other hand you don't have to. Here is a simple trick that will give you exactly what you need.
In your web.xml file insert XML comment <!-- @JSPS_MAP@ -->
between <servlet>
and <servlet-mapping>
elements, e.g.
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>my.servlets.MyServlet</servlet-class>
<servlet>
<!-- @JSPS_MAP@ -->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/my-servlet</url-pattern>
</servlet-mapping>
Then use a token filter to replace @JSPS_MAP@
tag with generated content.
<loadfile
property="generated.web.xml.fragment"
srcFile="${generated.fragment.file}"
/>
<copy file="${orig-web-content.dir}/WEB-INF/web.xml"
toFile="${generated-web-content.dir}/WEB-INF/web.xml"
>
<filterset>
<filter token="JSPS_MAP"
value=" --> ${generated.web.xml.fragment} <!-- "
/>
</filterset>
</copy>
This approach has an advantage that the original web.xml file is completely valid (a tag is hidden in the comment), but gives you total control of where and when the generated fragment will be inserted.
So for DEV build, just copy ${orig-web-content.dir}/WEB-INF/web.xml
to ${generated-web-content.dir}/WEB-INF/web.xml
without filtering.
There is the jasper2 ant task others have noted. I thought I'd mention a couple of other options I've found.
One is cactus' webxmlmerge ant task, which uses org.codehaus.cargo.module.webapp.WebXmlMerger
Another would be to use JAXB to manipulate the web.xml; Sebastien Dionne's dtd-schemas-generator demo does this. Not sure what the license is though.
fwiw having considered these options i think I'm going to use the ant XSLT task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With