簡體   English   中英

如何在啟動時使Tomcat預編譯JSP?

[英]How can I make Tomcat pre-compile JSPs on startup?

我正在使用Apache Tomcat 6.0和Jetty 6。 我們主要使用Jetty進行測試(它非常適合在JUnit測試中運行嵌入式)和Tomcat用於生產。

默認情況下,Tomcat會在用戶請求時動態編譯JSP。 但這會導致第一次打擊的性能下降。 它還突出了Tomcat的JSP編譯器中的奇怪錯誤

Tomcat文檔提供了在構建時使用Ant預編譯JSP的建議(並且還提供了Maven插件)...但是生成的WAR包含特定於Tomcat的東西,例如PageContextImpl.proprietaryEvaluate,因此我們不能在Jetty中使用它。

是否有一些標志或設置我們可以在某處使用強制Tomcat在WAR初始化時預編譯所有JSP? 我們准備在啟動時等待一段時間。

在推進:通過明確識別web.xml中/的servlet /時加載的啟動標簽為一個JSP我知道有一種方法預編譯正是一個 JSP。 但對於幾十甚至幾百個難以管理的JSP。

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 map ping必須進入你的webapp的WEB-INF / web.xml文件,但是編寫一個知道如何以可重復的方式將servlet映射插入web.xml文件的Ant構建文件是很困難的。構建文件運行的時間。 相反,我們使用XML實體包含,以便每次構建文件運行時生成的servlet映射都會進入新文件,並且可以通過XML實體包含機制將servlet映射文件插入到web.xml文件中。 要使用它,您的webapp的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> 

確保webapp的web.xml文件在文件頂部和下面的servlet 2.5 web-app模式聲明中一直有內聯DTD(DOCTYPE標記)。 然后,無論您希望在web.xml文件中插入生成的servlet映射,請將實體引用&jspc-webxml; 請記住,實體引用以和號(&)開頭,然后具有實體的名稱,並以分號(;)結尾。

要使用構建文件,只需編輯它並將頂部的所有屬性設置為與您的設置匹配的值,然后像下面這樣運行:

$ ant -f pre-compile-jsps.xml

如果你選擇duffymo提到的解決方案指向Vinny Carpenter的博客,我有一個提示。 有一個區域導致我的容器在聯系localhost時無限期掛起(特別是在private connect()方法中)。 使用以下hack是我的解決方法:

    private void connect(final String urlString) {

        HttpURLConnection conn;
        try {
            final URL url = new URL(urlString);
            conn = (HttpURLConnection)url.openConnection();
            conn.setConnectTimeout(5000);
            //time it out quickly - otherwise hangs forever
            //seems to be an issue hitting localhost
            //will still precompile the page
            conn.setReadTimeout(100);
            conn.setAllowUserInteraction(true);
            conn.getInputStream();
            conn.disconnect();
        }
        catch (SocketTimeoutException e) {
            log.debug(e);
        }
        catch (IOException ioe) {
            log.error(ioe);
        }
    }

設置超時並忽略SocketTimeoutException(雖然不可能是最好的解決方案)。 此外,使用此過程意味着您需要在web.xml中指定JSP。 這足以滿足我的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM