Sunday, September 18, 2011

How to use pre-compiled JSPs in a webapp with tomcat 7


Written by Hasini

Problem:
Recently I had the following requirement:

I had a webapp that has some jsp files which directly call some methods in some libraries. But those libraries are in a sandbox environment secured by Java Security Manager. Therefore only the calls that come from classes that are signed by a particular key, are allowed to be executed.

My webapp was not working until I guarantee the sandbox environment that the method calls are coming from a signed source.

Solution:
The solution for the above problem is consisted with following steps:
1. Pre-compile jsp files.
2. Package the pre compiled jsp files into a jar file.
3. Sign the jar file using the appropriate key.
4. Package the signed jar file in the WEB-INF/lib folder of the webapp
5. Remove all the jsp files from the webapp.

Walk through:
jspc-maven-plugin comes to the rescue in this occasion.

I will walk you through how to pre-compile jsp files of the example webapp of WSO2 AppServer by integrating pre-compiling step into the maven pom.xml.

Following is the complete pom.xml file with modifications to include the steps of pre-compiling and packaging the jsp files.


org.wso2.appserver
wso2appserver-samples-parent
4.1.1
../../pom.xml


4.0.0

example
war
WSO2 AS - Example webapp



org.wso2.carbon
org.wso2.carbon.tomcat
${carbon.platform.version}


org.apache.axis2.wso2
axis2-client
${axis2.osgi.version}


org.wso2.carbon
org.wso2.carbon.authenticator.proxy
${carbon.platform.version}


org.wso2.carbon
org.wso2.carbon.authenticator.stub
${carbon.platform.version}


org.wso2.carbon
org.wso2.carbon.core.common
${carbon.platform.version}


org.wso2.carbon
org.wso2.carbon.core



org.apache.axis2.wso2
axis2






org.codehaus.mojo
build-helper-maven-plugin


add-source
generate-sources

add-source



target/generated-code/src







org.codehaus.mojo.jspc
jspc-maven-plugin



compile




${pom.basedir}/src/main/resources/WEB-INF/web.xml
1.5
1.5

${pom.basedir}/src/main/resources

**/*.jsp







org.codehaus.mojo.jspc
jspc-compiler-tomcat6
2.0-alpha-3



org.apache.tomcat
jasper


org.apache.tomcat
jasper-el


org.apache.tomcat
jasper-jdt


org.apache.tomcat
servlet-api


org.apache.tomcat
jsp-api


org.apache.tomcat
el-api


org.apache.tomcat
annotations-api





org.apache.tomcat
tomcat-jasper
7.0.12



org.eclipse.jdt.core.compiler
ecj
3.5.1





org.apache.maven.plugins
maven-compiler-plugin

1.5
1.5




org.apache.maven.plugins
maven-war-plugin
2.1-beta-1

example

WEB-INF/classes/**,
WEB-INF/*,
WEB-INF/jsp/*,
WEB-INF/jsp2/*,
WEB-INF/lib/jstl.jar,
WEB-INF/lib/standard.jar,
WEB-INF/lib/jsp.jar,
**/axis2-client*.jar,
**/org.wso2.carbon.authenticator.proxy*.jar,
**/org.wso2.carbon.authenticator.stub*.jar,
**/org.wso2.carbon.core.common*.jar,
**/*.java,
**/tags/**,
**/servlets/**,
**/carbon/**,
**/*.class,
**/*.html,
jsp/images/*




src/main/resources


${pom.basedir}/target/jspweb.xml






Following is what is done... please follow with the line numbers:

1. line 73 introduces jspc-maven-plugin to the pom.xml file.
This will compile jsp files to servlets and then into .class files which include the byte code. These can be found under "target/jsp-source" once the maven build succeeds.

2. Note the 'Configuration' element from line 83 to 93:
    - inputwebxml: specify where the original web.xml file of the webapp resides. jspc-maven-plugin will detect that and update the servlet mappings according to the compiled jsp files and create a new file called "jspweb.xml" in the target folder, which you need to package with the webapp instead of the original web.xml.
    - sources: specify where the jsp files resides in your webapp .

3. Then comes the trick: there is no jspc-maven-compiler plugin for tomcat 7 yet. So we need to use tomcat 6 version of it by removing the incompatibilities. This is what is done from line 97 to line 147.

4. As in line 190, you need to specify the new web.xml created by this plugin, to be included in the .war file of the webapp.

5. Now the step 1 mentioned in the above 'solution' section is achieved and the files obtained by pre-compiling jsp files are available in 'target/jsp-source' folder.

Now, in order to complete steps from 2-4 in the above 'solution', you may need to write a ant build.xml file or can integrate those steps into the pom.xml file itself. I did it through a ant build.xml file.

You can use jarsigner tool that comes with JDK installation  to sign the jar file containing the compiled jsps, as described here.

Once you include the compiled jsps in a jar file in the webapp, you need to remove the original jsp files from the webapp or avoid packaging them in the .war file because if they are included, those will be compiled and used by the servlet container instead of the already pre-compiled ones.

In my case, I had to remove the jsp files packaged inside web-inf/classes/carbon
and web-inf/classes/jsp/carbon of the webapp.

Hope this helps...

See original post

5 comments:

nuwan on September 18, 2011 at 9:26 AM said...

Glad you got stuff working :) good stuff

Hasini on September 19, 2011 at 11:52 AM said...

Yes, got it working. Thanks Nuwan... :)

Janelyzhang on October 31, 2011 at 6:18 PM said...

This is what I have been searching in many websites and I finally found it here. Amazing article. I am so impressed. Could never think of such a thing is possible with it...I think you have a great knowledge especially while dealings with such subjects.
Houton Home Security

Nikos Maravitsas on September 24, 2012 at 12:49 AM said...

Hi Feed ,

Great blog! Is there an email address I can contact you in private?

sajid arzoo on November 19, 2012 at 11:19 PM said...

Thanks for taking this opportunity to discuss this, I appreciate with this and if you have some more information please share it with me.
http://www.genesishealthinstitute.com

Post a Comment

 

Copyright 2009 All Rights Reserved Revolution Two Church theme modified by Milinda Pathirage