如何在启动时使 Tomcat 预编译 JSP? [英] How can I make Tomcat pre-compile JSPs on startup?

查看:44
本文介绍了如何在启动时使 Tomcat 预编译 JSP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在我工作的地方同时使用 Apache Tomcat 6.0 和 Jetty 6.我们主要使用 Jetty 进行测试(它非常适合在 JUnit 测试中嵌入运行)和 Tomcat 进行生产.

We're using both Apache Tomcat 6.0 and Jetty 6 where I work. We mostly use Jetty for testing (it's great for running embedded in JUnit tests) and Tomcat for production.

默认情况下,Tomcat 会根据用户的请求即时编译 JSP.但这会导致第一次命中的性能下降.它还强调了 Tomcat 的 JSP 编译器中的奇怪的错误.

By default, Tomcat compiles JSPs on-the-fly as users request them. But this results in degraded performance for the first hit. It also highlights bizarre bugs in Tomcat's JSP compiler.

Tomcat 文档 为预编译 JSP 提供了建议在构建时使用 Ant(也可以使用 Maven 插件)...但生成的 WAR 包含特定于 Tomcat 的内容,例如PageContextImpl.proprietaryEvaluate,所以我们不能在Jetty中使用它.

The Tomcat documentation gives recommendations for pre-compiling JSPs at build time using Ant (and a Maven plugin is also available)... but the resulting WAR contains Tomcat-specific stuff e.g. PageContextImpl.proprietaryEvaluate, so we can't use it in Jetty.

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

Is there some flag or setting we can use somewhere to force Tomcat to precompile all JSPs as soon as the WAR is initialized? We're prepared to wait a little longer on startup for this.

事先:我知道有一种方法可以通过在 web.xml 中为一个 JSP 显式标识一个/servlet/load-on-startup 标记来精确地预编译 一个 JSP.但是对于数十个甚至数百个变得无法管理的 JSP.

In advance: I know there's a way to pre-compile exactly one JSP by explicitly identifying a /servlet/load-on-startup tag in web.xml for one JSP. But for dozens or even hundreds of JSPs that becomes unmanageable.

推荐答案

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

这个构建文件将找到您的所有 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 文件的外观:

This build file will find all of your webapp’s JSP files, compile them into servlet classes, and generate servlet mappings for those JSP servlet classes. The servlet map pings it generates must go into your webapp’s WEB-INF/web.xml file, but it would be difficult to write an Ant build file that knows how to insert the servlet mappings into your web.xml file in a repeatable way every time the build file runs. Instead, we used an XML entity include so that the generated servlet mappings go into a new file every time the build file runs and that servlet mappings file can be inserted into your web.xml file via the XML entity include mechanism. To use it, your webapp’s WEB- INF/web.xml must have a special entity declaration at the top of the file, plus a reference to the entity in the content of the web.xml file where you want the servlet mappings file to be included. Here is how an empty servlet 2.5 webapp’s web.xml file looks with these modifications:

<!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> 

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

Make sure your webapp’s web.xml file has the inline DTD (the DOCTYPE tag) all the way at the top of the file and the servlet 2.5 web-app schema declaration below that. Then, wherever you want to insert the generated servlet mappings in your web.xml file, put the entity reference &jspc-webxml; . Remember, the entity reference begins with an ampersand ( & ), then has the name of the entity, and ends with a semicolon ( ; ).

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

To use the build file, just edit it and set all of the properties at the top to values that match your setup, and then run it like this:

$ ant -f 预编译-jsps.xml

$ ant -f pre-compile-jsps.xml

这篇关于如何在启动时使 Tomcat 预编译 JSP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆