2013-07-16 25 views
14

Tôi đang đóng gói một ứng dụng Web Archive (.WAR) để nó có thể được bắt đầu qua java -jar webapp.war trong một vỏ bằng cách tung ra một bản sao nhúng của Jetty 9 sử dụng mã này trong một lớp học chính:Làm thế nào để bạn có được Jetty 9 được nhúng để giải quyết thành công URI JSTL?

int port = Integer.parseInt(System.getProperty("port", "80")); // I know this has implications :) 
String contextPath = System.getProperty("contextPath", ""); 
Server server = new Server(port); 
ProtectionDomain domain = Deployer.class.getProtectionDomain(); 
URL location = domain.getCodeSource().getLocation(); 
WebAppContext webapp = new WebAppContext(); 
webapp.setContextPath("/" + contextPath); 
webapp.setWar(location.toExternalForm()); 
server.setHandler(webapp); 
server.start(); 
server.join(); 

Tuy nhiên, tôi đang chạy vào lỗi này khi JSP đầu tiên chứa một tuyên bố JSTL taglib được biên soạn:

org.apache.jasper.JasperException: /WEB-INF/html/user/login.jsp(2,62) PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application 
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:92) 
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:378) 
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:172) 
at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:431) 
at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:240) 
at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:502) 
at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:582) 
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1652) 
at org.apache.jasper.compiler.Parser.parse(Parser.java:185) 
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:244) 
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:145) 
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:212) 
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451) 
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:625) 
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) 
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492) 
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) 
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698) 
etc... 

cặp đôi dòng đầu tiên của mà JSP như sau:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 

Tôi đã nhìn xung quanh khá một chút (điều này dường như không phải là một vấn đề mới) và đã thử các giải pháp sau:

  • Slimming xuống phụ thuộc của tôi và tìm kiếm xung đột (hiện tại tôi chỉ phụ thuộc trên jetty-server, jetty-webapp, và jetty-jsp, tất cả các phiên bản 9.0.4.v20130625)
  • Xác định một <taglib> lập bản đồ rõ ràng trong file web.xml của webapp trỏ đến JSTL trực tiếp (có ý tưởng này từ việc đọc spec JSP)
  • Sửa đổi classpath máy chủ như trên this answer
  • Lợi dụng phương pháp WebAppContext như addServerClasssetParentLoaderPriority

Theo Jetty's documentation, sử dụng JSTL chỉ nên làm việc, nhưng tôi nghĩ rằng bối cảnh nhúng có thể được thay đổi cách JSTL được nạp và làm cho nó thất bại.

Sẽ đánh giá cao bất kỳ ý tưởng hoặc đề xuất nào. Thiết lập này sẽ thay thế một thiết lập cũ hơn đã làm điều tương tự thành công trên Windows nhưng không hoạt động trên Linux do sự bao gồm của một phụ thuộc cũ được đưa vào this bug. Thật không may, tôi đã không thể tìm thấy sự thay thế nhanh chóng cho sự phụ thuộc đó (groupId org.mortbay.jetty artifactId jsp-2.1-glassfish phiên bản 2.1.v20100127) không giới thiệu theo dõi ngăn xếp JSTL URI được đề cập ở trên.

CẬP NHẬT: Tôi đã tìm thấy giải pháp tối ưu. Việc hạ cấp xuống Jetty 7 được lấy cảm hứng từ this thread hiện đã giúp tôi thiết lập và chạy. Đây là một tin tuyệt vời, nhưng nó không khuyến khích nếu sau này tôi yêu cầu bất kỳ chức năng nào dành riêng cho Jetty 8 hoặc Jetty 9 mà tôi phải loại bỏ cơ sở hạ tầng triển khai này. Bất kỳ thông tin chi tiết nào về vấn đề taglib JSTL trong Jetty 9 sẽ vẫn được đánh giá cao.

Trả lời

1

Đáng buồn thay, không ai trong số các câu trả lời cho đến nay đã làm việc cho tôi. Nhưng cuối cùng tôi đã tìm ra giải pháp cho vấn đề của mình. Điều này nghe có vẻ giống như một hack, và nó chắc chắn cảm thấy như một. Nhưng nếu tôi thiết lập mọi thứ giống như tôi đã mô tả trong câu hỏi của mình, đến mức mà JSTL không giải quyết được, thì tôi có thể thực hiện một bước để mọi thứ hoạt động, gần giống như ma thuật.

Bước cringe-inducing đó đang thay đổi phần mở rộng trên tệp .war thành .jar. Một khi tôi làm điều đó, JSTL giải quyết tốt, và mọi thứ hoạt động.

Vì vậy, ngay bây giờ tôi tạo ra một .war mà bạn có thể dính vào một thùng chứa servlet hoặc bạn có thể đổi tên thành .jar và chạy độc lập. Và nó hoạt động trên cả Unix và Windows, trong khi cách tôi làm điều này trước đây sẽ không hoạt động trên Unix do có lỗi trong thư viện jsp-2.1-glassfish được James Cook đề cập.

Các bit có liên quan từ pom của tôi:

<properties> 
    <jetty.version>9.0.5.v20130815</jetty.version> 
    <war.class>com.domain.package.DeployWebapp</war.class> 
    <war.class.path>com/domain/package</war.class.path> 
</properties>  

<dependency> 
    <groupId>org.eclipse.jetty</groupId> 
    <artifactId>jetty-server</artifactId> 
    <version>${jetty.version}</version> 
    <scope>provided</scope> 
</dependency> 

<dependency> 
    <groupId>org.eclipse.jetty</groupId> 
    <artifactId>jetty-webapp</artifactId> 
    <version>${jetty.version}</version> 
    <scope>provided</scope> 
</dependency> 

<dependency> 
    <groupId>org.eclipse.jetty</groupId> 
    <artifactId>jetty-jsp</artifactId> 
    <version>${jetty.version}</version> 
    <scope>provided</scope> 
</dependency> 

<plugin> 
    <artifactId>maven-antrun-plugin</artifactId> 
    <version>1.7</version> 
    <executions> 
     <execution> 
      <id>main-class-placement</id> 
      <phase>prepare-package</phase> 
      <configuration> 
       <tasks> 
        <move todir="${project.build.directory}/${project.artifactId}-${project.version}/${war.class.path}"> 
        <fileset dir="${project.build.directory}/classes/${war.class.path}"> 
         <include name="DeployWebapp.class" /> 
        </fileset> 
       </move> 
         </tasks> 
       </configuration> 
       <goals> 
        <goal>run</goal> 
       </goals> 
      </execution> 
    </executions> 
</plugin> 

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <version>2.3</version> 
    <executions> 
     <execution> 
      <id>jetty-classpath</id> 
      <phase>prepare-package</phase> 
      <goals> 
       <goal>unpack-dependencies</goal> 
      </goals> 
      <configuration> 
       <includeGroupIds>org.eclipse.jetty,javax.servlet,javax.el,org.glassfish.web,org.eclipse.jetty.orbit,org.ow2.asm,javax.annotation</includeGroupIds> 
       <outputDirectory> 
        ${project.build.directory}/${project.artifactId}-${project.version} 
       </outputDirectory> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.4</version> 
    <configuration> 
     <attachClasses>true</attachClasses> 
     <archiveClasses>true</archiveClasses> 
     <archive> 
      <manifest> 
       <mainClass>${war.class}</mainClass> 
      </manifest> 
     </archive> 
     <packagingExcludes>META-INF/*.SF</packagingExcludes> 
     <packagingExcludes>META-INF/*.DSA</packagingExcludes> 
     <packagingExcludes>META-INF/*.RSA</packagingExcludes> 
    </configuration> 
</plugin> 
1

Tôi vừa tạo jsp đơn giản với taglib ta khi bạn sử dụng. Sau đó, tạo ứng dụng máy chủ và nó hoạt động. Vì vậy, tôi nghĩ rằng nó không phải là một taglib gây ra vấn đề.

public static void main(String[] args) throws Exception { 
    Server server = new Server(8680); 
    HandlerCollection handlers = new HandlerCollection(); 
    server.setHandler(handlers); 
    ContextHandlerCollection chc = new ContextHandlerCollection(); 
    handlers.addHandler(chc); 
    WebAppContext webapp = new WebAppContext(); 
    webapp.getInitParams().put("org.eclipse.jetty.servlet.Default.useFileMappedBuffer",  
    "false"); 
    webapp.setContextPath("/WebAppMng01"); 
    //URL url = ManagedServer.class.getResource("/WebAppMng01/build/web"); 
    URL url = ManagedServer.class.getResource("/WebAppMng01/dist/WebAppMng01.war"); 
    if (url != null) { 
     webapp.setWar(url.toExternalForm()); 
     chc.addHandler(webapp); 
    } 
    server.start(); 
    server.join(); 
} 
3

Tôi đã gặp vấn đề tương tự khi bắt đầu Jetty từ bài kiểm tra Surefire; vấn đề là Jetty 9 không xem xét các tệp kê khai của bất kỳ tệp jar nào ngoại trừ trong WEB-INF, không tương thích với cách tôi viết bài kiểm tra của mình.

Để khắc phục sự cố, tôi đã viết một chút mã để tìm tệp jar từ tệp kê khai và đặt chúng vào một trình tải URL trung cấp mới.

Đây là những gì chức năng chức năng cài đặt thử nghiệm của tôi đã kết thúc tìm kiếm muốn có được nó để làm việc với Jetty 9:

@Before @SuppressWarnings("unchecked") 
public void setUp() throws Exception { 

    WebAppContext ctx = new WebAppContext("src/main/webapp", "/"); 

    Server server = new Server(9000); 

    ctx.setServer(server); 
    server.setHandler(ctx); 

    ctx.preConfigure(); 

    ctx.addOverrideDescriptor("src/main/webapp/WEB-INF/tests-web.xml");  

    // Replace classloader with a new classloader with all URLs in manifests 
    // from the parent loader bubbled up so Jasper looks at them. 
    ClassLoader contextClassLoader = ctx.getClassLoader(); 
    ClassLoader parentLoader = contextClassLoader.getParent(); 
    if (contextClassLoader instanceof WebAppClassLoader && 
     parentLoader instanceof URLClassLoader) { 
     LinkedList<URL> allURLs = 
      new LinkedList<URL>(Arrays.asList(((URLClassLoader)parentLoader).getURLs())); 
     for (URL url : ((LinkedList<URL>)allURLs.clone())) { 
     try { 
      URLConnection conn = new URL("jar:" + url.toString() + "!/").openConnection(); 
      if (!(conn instanceof JarURLConnection)) 
      continue; 
      JarURLConnection jconn = (JarURLConnection)conn; 
      Manifest jarManifest = jconn.getManifest(); 
      String[] classPath = ((String)jarManifest.getMainAttributes().getValue("Class-Path")).split(" "); 

      for (String cpurl : classPath) 
      allURLs.add(new URL(url, cpurl)); 
     } catch (IOException e) {} catch (NullPointerException e) {} 
     } 

     ctx.setClassLoader(
      new WebAppClassLoader(
       new URLClassLoader(allURLs.toArray(new URL[]{}), parentLoader), 
       ((WebAppClassLoader)contextClassLoader).getContext())); 
    } 

    server.start(); 
} 

mẫu mã của tôi được đặt trong phạm vi công cộng - bạn có thể sử dụng nó trong mã của riêng bạn (phân bổ được đánh giá cao nhưng không bắt buộc).

+0

Giải pháp này làm việc cho Jetty 9.0 nhưng không phải 9.1 –

+0

Ngoài ra, không gây khó khăn cho Jetty 8.1 –

3

Sau khi sử dụng giải pháp a1kmm và kết thúc với NullPointers, tôi nhận thấy rằng tôi không đặt Trình nạp lớp trên WebAppContext. Sử dụng dòng sau, tôi không còn cần thiết lập quét lớp/tệp kê khai tùy chỉnh.

webAppContext.setClassLoader(new WebAppClassLoader(getClass().getClassLoader(), webAppContext)); 
2

Tôi đã gặp sự cố chính xác này. Và tôi đã giải quyết nó theo cách khác thường nhất.

Tôi đang sử dụng Maven làm công cụ xây dựng, nhưng đây là cách tôi xây dựng WAR tự thực hiện của mình.

<profile> 
     <id>Jetty_9</id> 
     <properties> 
      <jetty9.version>9.0.4.v20130625</jetty9.version> 
     </properties> 
     <dependencies> 
      <dependency> 
       <groupId>ch.qos.logback</groupId> 
       <artifactId>logback-classic</artifactId> 
       <version>${logback.version}</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>ch.qos.logback</groupId> 
       <artifactId>logback-access</artifactId> 
       <version>${logback.version}</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>ch.qos.logback</groupId> 
       <artifactId>logback-core</artifactId> 
       <version>${logback.version}</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>org.slf4j</groupId> 
       <artifactId>slf4j-api</artifactId> 
       <version>${slf4j.version}</version> 
       <scope>provided</scope> 
      </dependency> 

      <dependency> 
       <groupId>org.eclipse.jetty.orbit</groupId> 
       <artifactId>javax.servlet</artifactId> 
       <version>3.0.0.v201112011016</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>org.eclipse.jetty</groupId> 
       <artifactId>jetty-webapp</artifactId> 
       <version>${jetty9.version}</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>org.eclipse.jetty</groupId> 
       <artifactId>jetty-plus</artifactId> 
       <version>${jetty9.version}</version> 
       <scope>provided</scope> 
      </dependency> 
      <dependency> 
       <groupId>org.eclipse.jetty</groupId> 
       <artifactId>jetty-jsp</artifactId> 
       <version>${jetty9.version}</version> 
      </dependency>    
     </dependencies> 
     <build> 
      <plugins> 
       <plugin> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <version>2.3.2</version> 
        <configuration> 
         <source>${compileSource}</source> 
         <target>${compileSource}</target> 
        </configuration> 
       </plugin> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-antrun-plugin</artifactId> 
        <version>1.7</version> 
        <executions> 
         <execution> 
          <id>main-class-placement</id> 
          <phase>prepare-package</phase> 
          <configuration> 
           <target> 
            <move todir="${project.build.directory}/${project.build.finalName}/"> 
             <fileset dir="${project.build.directory}/classes/"> 
              <include name="Main.class"/> 
             </fileset> 
            </move> 
           </target> 
          </configuration> 
          <goals> 
           <goal>run</goal> 
          </goals> 
         </execution> 
        </executions> 
       </plugin> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-dependency-plugin</artifactId> 
        <version>2.6</version> 
        <executions> 
         <execution> 
          <id>jetty-classpath</id> 
          <phase>prepare-package</phase> 
          <goals> 
           <goal>unpack-dependencies</goal> 
          </goals> 
          <configuration> 
           <includeGroupIds> 
            org.eclipse.jetty,org.slf4j,ch.qos 
           </includeGroupIds>          
           <includeScope>provided</includeScope> 
           <excludes>META-INF/*.SF,META-INF/*.RSA,about.html, about_files/**, readme.txt, 
            plugin.properties, jetty-dir.css 
           </excludes> 
           <outputDirectory> 
            ${project.build.directory}/${project.build.finalName} 
           </outputDirectory> 
          </configuration> 
         </execution> 
        </executions> 
       </plugin> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-war-plugin</artifactId> 
        <version>2.3</version> 
        <configuration> 
         <archive> 
          <manifest> 
           <mainClass>Main</mainClass> 
          </manifest> 
         </archive> 
        </configuration> 
        <executions> 
         <execution> 
          <id>default-war</id> 
          <phase>package</phase> 
          <goals> 
           <goal>war</goal> 
          </goals> 
         </execution> 
        </executions> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 

Nhưng giống như bản thân tôi đã nhận được lỗi đó. Sau khi Googling cái chết ra khỏi nó sau 2 ngày Tôi thấy điều này - http://internna.blogspot.co.uk/2011/08/step-by-step-executable-war-files.html

Bằng cách chuyển ra khỏi sự phụ thuộc cầu cảng-jsp cho một này:

<dependency> 
      <groupId>org.mortbay.jetty</groupId> 
      <artifactId>jsp-2.1-glassfish</artifactId> 
      <version>2.1.v20100127</version> 
</dependency> 

Mọi chuyện bắt đầu một cách kỳ diệu làm việc!

Tại thời điểm này, tôi không thể giải thích tại sao nó hoạt động. Nhưng tôi rất muốn tìm hiểu

+0

Tôi chỉ cần thêm jsp-2.1-glassfish để depencencies của tôi và nó hoạt động? – Alexey

+0

Xin chào! Tôi rất muốn giúp bạn, nhưng câu trả lời này đã hơn 2 năm nay, bộ nhớ hơi mờ. Tôi nghĩ rằng tất cả đã chuyển từ đó. –

7

Vì vậy, đây là một giải pháp khác. Tôi đã đấu tranh với vấn đề rất giống nhau chỉ có tôi có một tập tin chiến tranh riêng biệt và một lớp học nhúng đơn giản mà tạo ra một máy chủ Jetty cho tôi và bắt đầu nó lên chỉ để có thể bất kỳ tập tin chiến tranh. Đây là cách làm việc này.

  1. Tệp chiến tranh không có thư viện tld nào trong WEB-INF/lib và hoàn toàn tách biệt với bộ nạp miniapplication.

    phụ thuộc
  2. Việc áp dụng Loader lớp chính mà bắt đầu các máy chủ và chỉ nó cho bất kỳ tập tin chiến tranh đã sau (maven):

    <!-- Jetty webapp --> 
        <dependency> 
         <groupId>org.eclipse.jetty</groupId> 
         <artifactId>jetty-webapp</artifactId> 
         <version>${jettyVersion}</version> 
        </dependency> 
    
        <!-- With JSP support --> 
        <dependency> 
         <groupId>org.eclipse.jetty</groupId> 
         <artifactId>jetty-jsp</artifactId> 
         <version>${jettyVersion}</version> 
        </dependency> 
    

  3. Lớp bốc bản thân trông như :

    Server server = new Server(cncPort); 
    
    WebAppContext webApp = new WebAppContext(); 
    
    webApp.setContextPath(applicationContext); 
    webApp.setWar(jettyHome + "/" + warFile); 
    server.setHandler(webApp); 
    
    try { 
        server.start(); 
        server.join(); 
    } catch (Exception ex) { 
        System.out.println("Failed to start server."); 
        ex.printStackTrace(); 
    } 
    
  4. Các gói phần mềm dẫn đến trường hợp của tôi trông như sau:

    + EmbedderApp 
    | 
    +-- lib 
        - EmbeddedApp.jar <-- JAR with the embedder class 
        - com.sun.el-2.2.0.v201303151357.jar 
        - javax.el-2.2.0.v201303151357.jar 
        - javax.servlet-3.0.0.v201112011016.jar 
        - javax.servlet.jsp-2.2.0.v201112011158.jar 
        - javax.servlet.jsp.jstl-1.2.0.v201105211821.jar 
        - jetty-http-9.0.6.v20130930.jar 
        - jetty-io-9.0.6.v20130930.jar 
        - jetty-jsp-9.0.6.v20130930.jar 
        - jetty-security-9.0.6.v20130930.jar 
        - jetty-server-9.0.6.v20130930.jar 
        - jetty-servlet-9.0.6.v20130930.jar 
        - jetty-util-9.0.6.v20130930.jar 
        - jetty-webapp-9.0.6.v20130930.jar 
        - jetty-xml-9.0.6.v20130930.jar 
        - org.apache.jasper.glassfish-2.2.2.v201112011158.jar 
        - org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar 
        - org.eclipse.jdt.core-3.8.2.v20130121.jar 
    
  5. dependecies của tôi đã chỉ đơn giản là thêm vào thông qua Plugin lắp ráp như

    <dependencySet> 
        <outputDirectory>lib</outputDirectory> 
        <scope>runtime</scope> 
    </dependencySet> 
    
  6. Tôi có một vỏ bắt đầu kịch bản tung ra lớp nhúng và ở đây có những gì đã cho tôi lứa tuổi để tìm ra.

    Tôi đã sử dụng tệp kê khai có đường dẫn lớp được nhúng trong bình và đặt CLASSPATH=<PATH_TO_APP>\lib\EmbeddedApp.jar giả định việc đặt lại phụ thuộc là một phần của đường dẫn lớp thông qua tệp kê khai. Và tôi đã gettign cùng một lỗi URI unresolvable.

    Khi tôi đã thêm, thay đổi biến số CLASSPATH trong tập lệnh của tôi để chứa tất cả các lọ rõ ràng nó bắt đầu hoạt động.

    for jar in ${APP_ROOT}/lib/*.jar; do CLASSPATH=$jar:${CLASSPATH}; done 
    

Hy vọng điều này có thể tiết kiệm thời gian ai đó :-)

+0

Thổi phồng classpath cũng làm việc cho tôi - cảm ơn rất nhiều! Tôi chuẩn bị từ bỏ chuyện này. –

+0

Hehe, tôi cảm thấy đau đớn của bạn, đã cho tôi lứa tuổi để tìm ra –

0

Dường như nhúng cầu cảng 9 không thích tự động sử dụng bất kỳ mục đường dẫn lớp từ chính file jar thực thi của bạn. Điều này bao gồm các thư viện taglib. Việc thêm các mục đường dẫn lớp trực tiếp vào webappclassloader dường như không hoạt động. Vì bất cứ lý do gì, các mục của đường dẫn lớp phải được thêm vào một phụ huynh của trình nạp webappclassloader.

Giải pháp đơn giản không làm việc cho tôi:

webAppContext.setClassLoader(new WebAppClassLoader(getClass().getClassLoader(), webAppContext)); 

Nhưng quét các biểu hiện bằng tay đã làm. Tôi đã viết lại ví dụ quét ở trên chỉ là tôi có thể thấy những gì đang xảy ra, và thử những thứ khác nhau mà tôi sẽ bao gồm ở đây.

//========== create WebAppClassloader with a new parent classloader with all URLs in manifests=================== 
    //search for any secondary class path entries 
    Vector<URL> secondayClassPathURLVector = new Vector<>(); 
    ClassLoader parentClassLoader = this.getClass().getClassLoader(); 
    if(parentClassLoader instanceof URLClassLoader) 
    { 
     URL[] existingURLs = ((URLClassLoader)parentClassLoader).getURLs(); 
     for (URL parentURL : existingURLs) 
     { 
      //if it doesn't end in .jar, then it's probably not going to have Manifest with a Class-Path entry 
      if(parentURL.toString().endsWith(".jar")) 
      { 
       JarURLConnection jarURLConnection = (JarURLConnection) new URL("jar:" + parentURL.toString() + "!/").openConnection(); 
       Manifest jarManifest = jarURLConnection.getManifest(); 
       String classPath = jarManifest.getMainAttributes().getValue("Class-Path"); 
       if(classPath != null) 
       { 
        //Iterate through all of the class path entries and create URLs out of them             
        for (String part : classPath.split(" ")) 
        { 
         //add our full path to the jar file to our classpath list 
         secondayClassPathURLVector.add(new URL(parentURL,part));      
        } 
       } 
      }     
     } 
    } 
    //use our class path entries to create a parent for the webappclassloader that knows how to use or referenced class paths 
    URLClassLoader internalClassPathUrlClassLoader = new URLClassLoader(secondayClassPathURLVector.toArray(new URL[secondayClassPathURLVector.size()]), parentClassLoader); 
    //create a new webapp class loader as a child of our internalClassPathUrlClassLoader. For whatever reason Jetty needs to have a WebAppClassLoader be it's main class loader, 
    //while all of our classpath entries need to be added to the parent class loader 
    WebAppClassLoader webAppClassLoader = new WebAppClassLoader(internalClassPathUrlClassLoader,context); 
    context.setClassLoader(webAppClassLoader); 

này nên thay thế ví dụ nhúng-cầu cảng-jsp mà chỉ không làm việc cho bất cứ lý do, nhưng nên, như bất kỳ mục classpath tự động nên bao gồm trong classpath. Tuy nhiên, JSP yêu cầu trình nạp lớp hệ thống NON. Vì vậy, tôi chỉ có thể giả định rằng JSP dừng quét đường dẫn lớp một khi nó đạt đến trình nạp lớp hệ thống classpath. Đó là lý do tại sao chúng ta phải thay thế nó một cách hiệu quả.

0
WebAppContext context = new WebAppContext();  
final URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); 
if (url != null) { 
    context.getMetaData().addWebInfJar(JarResource.newResource(url)); 
} 

Thêm bình chất béo làm bình WEB-INF, để MetaInfConfiguration tìm tệp * .tld.

tham khảo:

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