2009-01-31 25 views
14

Chúng tôi đang sử dụng cả Apache Tomcat 6.0 và Jetty 6 nơi tôi làm việc. Chúng tôi chủ yếu sử dụng Jetty để thử nghiệm (thật tuyệt vời khi chạy nhúng trong các bài kiểm tra JUnit) và Tomcat để sản xuất.Làm cách nào để tôi có thể thực hiện JSP khi biên dịch Tomcat khi khởi động?

Theo mặc định, Tomcat biên dịch JSP nhanh chóng khi người dùng yêu cầu. Nhưng điều này dẫn đến hiệu suất bị suy giảm cho lần truy cập đầu tiên. Nó cũng làm nổi bật bizarre bugs trong trình biên dịch JSP của Tomcat.

Tomcat documentation cung cấp các đề xuất cho việc biên dịch trước JSP tại thời gian xây dựng bằng cách sử dụng Ant (và một plugin Maven cũng có sẵn) ... nhưng WAR kết quả chứa nội dung cụ thể của Tomcat. PageContextImpl.proprietaryĐánh giá, vì vậy chúng tôi không thể sử dụng nó trong Jetty.

Có một số cờ hoặc cài đặt chúng tôi có thể sử dụng ở đâu đó để buộc Tomcat biên dịch trước tất cả các JSP ngay khi WAR được khởi tạo không? Chúng tôi đã sẵn sàng chờ đợi lâu hơn một chút khi khởi động cho việc này.

Trước: Tôi biết có cách để biên dịch trước chính xác một JSP bằng cách xác định rõ ràng thẻ/servlet/load-on-startup trong tệp web.xml cho một JSP. Nhưng đối với hàng chục hoặc thậm chí hàng trăm JSP trở nên không thể quản lý được.

+0

liên kết đến lỗi bizzarre là sai. Tôi đoán https đã được nhập mà không có dấu hai chấm, gây nhầm lẫn cho nó ... – Stephen

+0

tôi sẽ sử dụng hai bản dựng hoặc hai kết quả đầu ra - một cho cầu cảng và một cho tomcat, theo cách đó không cần phải chờ đợi cho tomcat biên dịch tất cả jsps mỗi khi bạn khởi động lại nó – tgkprog

+1

Đây là một chàng trai muốn làm điều tương tự như bạn: biên dịch trước các JSP, Tomcat hoặc Jetty, không có Ant. Có thể [this] (http://www.j2eegeek.com/blog/2004/05/03/a-different-twist-on-pre-compiling-jsps/) cũng sẽ giúp bạn. Tôi đã không thử nó bản thân mình. – duffymo

Trả lời

4

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 

xây dựng tập tin này sẽ tìm thấy tất cả các tập tin JSP của webapp của bạn, biên dịch chúng thành các lớp servlet, và tạo ra các ánh xạ servlet cho những lớp servlet JSP. Bản đồ servlet ping mà nó tạo ra phải đi vào tệp WEB-INF/web.xml của webapp của bạn, nhưng sẽ rất khó để viết một tệp xây dựng Ant để biết cách chèn ánh xạ servlet vào tệp web.xml của bạn theo cách lặp lại mọi thời gian tệp xây dựng chạy. Thay vào đó, chúng ta đã sử dụng một thực thể XML để các ánh xạ servlet được tạo ra đi vào một tệp mới mỗi khi tệp xây dựng chạy và tệp ánh xạ servlet có thể được chèn vào tệp web.xml của bạn thông qua cơ chế bao gồm thực thể XML. Để sử dụng nó, WEB-INF/web.xml của webapp phải có khai báo thực thể đặc biệt ở đầu tệp, cộng với tham chiếu đến thực thể trong nội dung của tệp web.xml nơi bạn muốn tệp ánh xạ servlet được bao gồm. Sau đây là cách tập tin web.xml một trống servlet 2.5 của ứng dụng web trông với những sửa đổi:

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

Đảm bảo rằng tệp web.xml của webapp của bạn có inline DTD (thẻ DOCTYPE) tất cả các con đường ở phía trên cùng của tập tin và khai báo lược đồ ứng dụng web servlet 2.5 bên dưới. Sau đó, bất cứ nơi nào bạn muốn chèn ánh xạ servlet được tạo ra trong tệp web.xml của bạn, hãy đặt tham chiếu thực thể & jspc-webxml; . Hãy nhớ, tham chiếu thực thể bắt đầu bằng dấu và (&), sau đó có tên của thực thể và kết thúc bằng dấu chấm phẩy (;).

Để sử dụng các tập tin xây dựng, chỉ cần chỉnh sửa nó và thiết lập tất cả các thuộc tính ở phía trên để các giá trị phù hợp với thiết lập của bạn, và sau đó chạy nó như thế này:

$ ant -f trước biên dịch JSP. xml

1

Nếu bạn đi với giải pháp được đề cập bởi duffymo trỏ tới blog của Vinny Carpenter, tôi có mẹo. Có một khu vực khiến container của tôi bị treo vô thời hạn trong khi liên hệ với localhost (đặc biệt trong phương thức private connect()). Sử dụng bản hack sau đây là cách giải quyết của tôi:

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); 
     } 
    } 

Đặt thời gian chờ và bỏ qua SocketTimeoutException hoạt động (mặc dù không phải là giải pháp tốt nhất).Ngoài ra, bằng cách sử dụng thủ tục này có nghĩa là bạn sẽ cần phải chỉ định các JSP trong web.xml. Điều này là đủ cho nhu cầu của tôi.

Các vấn đề liên quan