如何在启动时使Tomcat预编译JSP?

Dan*_*ich 14 java jsp tomcat java-ee

我正在使用Apache Tomcat 6.0和Jetty 6.我们主要使用Jetty进行测试(它非常适合在JUnit测试中运行嵌入式)和Tomcat用于生产.

默认情况下,Tomcat会在用户请求时动态编译JSP.但这会导致第一次打击的性能下降.它还突出了Tomcat的JSP编译器中的奇怪错误.

Tomcat文档提供了在构建时使用Ant预编译JSP的建议(和Maven插件也可)......但由此产生的WAR包含Tomcat的具体的东西如PageContextImpl.proprietaryEvaluate,所以我们不能在码头使用.

是否有一些标志或设置我们可以在某处使用强制Tomcat在WAR初始化时预编译所有JSP?我们准备在启动时等待一段时间.

提前:我知道有一种方法预编译正是一个通过明确识别web.xml中/的servlet /时加载的启动标签为一个JSP JSP.但对于几十甚至几百个难以管理的JSP.

ari*_*iso 5

http://www.devshed.com/c/a/BrainDump/Tomcat-Capacity-Planning/


    project name="pre-compile-jsps" default="compile-jsp-servlets">

  <!-- Private properties. -- >
  <property name="webapp.dir" value="${basedir}/webapp-dir"/>
  <property name="tomcat.home" value="/opt/tomcat"/>
  <property name="jspc.pkg.prefix" value="com.mycompany"/>
  <property name="jspc.dir.prefix" value="com/mycompany"/> 

  <!-- Compilation properties. -->
  <property name="debug" value="on"/> 
  <property name="debuglevel" value="lines,vars,source"/>
  <property name="deprecation" value="on"/>
  <property name="encoding" value="ISO-8859-1"/>
  <property name="optimize" value="off"/>
  <property name="build.compiler" value="modern"/>
  <property name="source.version" value="1.5"/> 

  <!-- Initialize Paths. -->
  <path id="jspc.classpath">
    <fileset dir="${tomcat.home}/bin">
      <include name="*.jar"/>
    </fileset>
    <fileset dir="${tomcat.home}/server/lib">
      <include name="*.jar"/>
    </fileset>
    <fileset dir="${tomcat.home}/common/i18n">
      <include name="*.jar"/>
    </fileset>
    <fileset dir="${tomcat.home}/common/lib">
      <include name="*.jar"/>
    </fileset>
    <fileset dir="${webapp.dir}/WEB-INF">
      <include name="lib/*.jar"/>
    </fileset>
    <pathelement location="${webapp.dir}/WEB-INF/classes"/>
    <pathelement location="${ant.home}/lib/ant.jar"/>
    <pathelement location="${java.home}/../lib/tools.jar"/>
  </path>
  <property name="jspc.classpath" refid="jspc.classpath"/> 

  <!--========================================================== -->
  <!-- Generates Java source and a web.xml file from JSP files.                     -->
  <!-- ==========================================================
-->
  <target name="generate-jsp-java-src"> 
    <mkdir dir="${webapp.dir}/WEB-INF/jspc-src/${jspc.dir.prefix}"/>
    <taskdef classname="org.apache.jasper.JspC" name="jasper2">
      <classpath>
        <path refid="jspc.classpath"/>
      </classpath>
    </taskdef>
    <touch file="${webapp.dir}/WEB-INF/jspc-web.xml"/>
    <jasper2 uriroot="${webapp.dir}"
             package="${jspc.pkg.prefix}" 
          webXmlFragment="${webapp.dir}/WEB-INF/jspc-web.xml" 
             outputDir="${webapp.dir}/WEB-INF/jspc-src/${jspc.dir.prefix}"
             verbose="1"/>
  </target> 

  <!-- ========================================================== -->
  <!-- Compiles (generates Java class files from) the JSP servlet -->
  <!-- source code that was generated by the JspC task.            -->
  <!-- ========================================================== -->
  <target name="compile-jsp-servlets" depends="generate-jsp-java-src">
    <mkdir dir="${webapp.dir}/WEB-INF/classes"/>
    <javac srcdir="${webapp.dir}/WEB-INF/jspc-src"
           destdir="${webapp.dir}/WEB-INF/classes"
           includes="**/*.java"
           debug="${debug}"
           debuglevel="${debuglevel}"
           deprecation="${deprecation}"
           encoding="${encoding}"
           optimize="${optimize}"
           source="${source.version}">
      <classpath>
        <path refid="jspc.classpath"/>
      </classpath>
    </javac>
  </target> 

  <!-- ========================================================= -->
  <!-- Cleans any pre-compiled JSP source, classes, jspc-web.xml -->
  <!-- ========================================================= -->
  <target name="clean">
    <delete dir="${webapp.dir}/WEB-INF/jspc-src"/>
    <delete dir="${webapp.dir}/WEB-INF/classes/${jspc.dir.prefix}"/>
    <delete file="${webapp.dir}/WEB-INF/jspc-web.xml"/>
  </target>

</project
Run Code Online (Sandbox Code Playgroud)

这个构建文件将找到您的所有 webapp 的 JSP 文件,将它们编译成 servlet 类,并为这些 JSP servlet 类生成 servlet 映射。它生成的 servlet 映射 ping 必须进入您的 web 应用程序的 WEB-INF/web.xml 文件,但是很难编写一个 Ant 构建文件,该文件知道如何以可重复的方式将 servlet 映射插入到您的 web.xml 文件中。构建文件运行的时间。相反,我们使用了一个 XML 实体包含,这样每次构建文件运行时生成的 servlet 映射都会进入一个新文件,并且可以通过 XML 实体包含机制将该 servlet 映射文件插入到您的 web.xml 文件中。要使用它,您的 web 应用程序的 WEB-INF/web.xml 必须在文件顶部有一个特殊的实体声明,以及对 web 内容中的实体的引用。xml 文件,您希望在其中包含 servlet 映射文件。以下是经过这些修改后的空 servlet 2.5 webapp 的 web.xml 文件的外观:

<!DOCTYPE jspc-webxml [
    <!ENTITY jspc-webxml SYSTEM "jspc-web.xml">
  ]> 

  <web-app xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http://www.w3.org/2001/ XMLSchema-instance 
      xsi:schemaLocation="http:// java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/ 
  javaee/web-app_2_5.xsd"
      version="2.5"> 

    <!-- We include the JspC-generated mappings here. -->
    &jspc-webxml; 

    <!-- Non-generated web.xml content goes here. --> 

  </web-app> 
Run Code Online (Sandbox Code Playgroud)

确保您的 webapp 的 web.xml 文件在文件顶部始终具有内联 DTD(DOCTYPE 标记),并在其下方具有 servlet 2.5 web-app 模式声明。然后,无论您想在 web.xml 文件中插入生成的 servlet 映射的任何位置,都将实体引用 &jspc-webxml; . 请记住,实体引用以与号 ( & ) 开头,然后是实体的名称,并以分号 ( ; ) 结尾。

要使用构建文件,只需编辑它并将顶部的所有属性设置为与您的设置匹配的值,然后像这样运行它:

$ ant -f 预编译-jsps.xml