【问题标题】:Self-contained war file with Tomcat embedded?嵌入Tomcat的独立战争文件?
【发布时间】:2011-10-26 13:48:53
【问题描述】:

有没有人成功地使用 Tomcat 7 Embedded 制作了一个独立的 .war 文件?使用 Maven。

我的意思是“自包含”war 文件也可以在命令行中用作:

java -jar application.war

它应该选择 META-INF/MANIFEST.MF 的主类并使用提供的嵌入式 Tomcat 7 运行应用程序。

我设法让它这样运行,但我似乎无法将它打包成一个 .war 文件来做同样的事情。

有人有某种文档的链接吗?

TIA !!!

一月

从 pom.xml 添加一个提取:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
      <failOnMissingWebXml>false</failOnMissingWebXml>
      <archive>
        <manifest>
          <mainClass>EmbeddedMain</mainClass>
          <addClasspath>true</addClasspath>
          <classpathPrefix>WEB-INF/lib/</classpathPrefix>
        </manifest>
      </archive>
      <webResources>
        <resource>
          <directory>target/classes</directory>
        </resource>
      </webResources>
    </configuration>
  </plugin>

其中“EmbeddedMain”是包含 main() 方法的类。尽管一切似乎都在它的位置,我仍然得到:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/catalina/LifecycleListener
Caused by: java.lang.ClassNotFoundException: org.apache.catalina.LifecycleListener
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: EmbeddedMain. Program will exit.

MANIFEST.MF 似乎没问题:WEB-INF/lib/tomcat-embed-core-7.0.22.jar 包含缺少的类。

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: jan
Build-Jdk: 1.6.0_29
Main-Class: EmbeddedMain
Class-Path: WEB-INF/lib/spring-web-3.0.6.RELEASE.jar WEB-INF/lib/aopal
 liance-1.0.jar WEB-INF/lib/spring-beans-3.0.6.RELEASE.jar WEB-INF/lib
 /spring-core-3.0.6.RELEASE.jar WEB-INF/lib/jwt-3.1.11.jar WEB-INF/lib
 /commons-fileupload-1.2.1.jar WEB-INF/lib/commons-io-1.4.jar WEB-INF/
 lib/next-persistence-0.0.3.jar WEB-INF/lib/hibernate-entitymanager-3.
 6.7.Final.jar WEB-INF/lib/hibernate-core-3.6.7.Final.jar WEB-INF/lib/
 antlr-2.7.6.jar WEB-INF/lib/dom4j-1.6.1.jar WEB-INF/lib/hibernate-com
 mons-annotations-3.2.0.Final.jar WEB-INF/lib/jta-1.1.jar WEB-INF/lib/
 cglib-2.2.jar WEB-INF/lib/javassist-3.12.0.GA.jar WEB-INF/lib/hiberna
 te-jpa-2.0-api-1.0.1.Final.jar WEB-INF/lib/kryo-1.04.jar WEB-INF/lib/
 asm-3.2.jar WEB-INF/lib/reflectasm-1.01.jar WEB-INF/lib/minlog-1.2.ja
 r WEB-INF/lib/annotations-1.3.9.jar WEB-INF/lib/tomcat-embed-core-7.0
 .22.jar WEB-INF/lib/tomcat-embed-jasper-7.0.22.jar WEB-INF/lib/tomcat
 -embed-logging-juli-7.0.22.jar WEB-INF/lib/derby-10.8.1.2.jar WEB-INF
 /lib/spring-context-3.0.6.RELEASE.jar WEB-INF/lib/spring-aop-3.0.6.RE
 LEASE.jar WEB-INF/lib/spring-expression-3.0.6.RELEASE.jar WEB-INF/lib
 /spring-asm-3.0.6.RELEASE.jar WEB-INF/lib/spring-orm-3.0.6.RELEASE.ja
 r WEB-INF/lib/spring-jdbc-3.0.6.RELEASE.jar WEB-INF/lib/spring-tx-3.0
 .6.RELEASE.jar WEB-INF/lib/commons-lang-2.5.jar WEB-INF/lib/slf4j-api
 -1.6.3.jar WEB-INF/lib/slf4j-log4j12-1.6.3.jar WEB-INF/lib/log4j-1.2.
 14.jar WEB-INF/lib/jcl-over-slf4j-1.6.3.jar WEB-INF/lib/commons-loggi
 ng-1.1.jar WEB-INF/lib/commons-collections-3.2.jar

【问题讨论】:

  • 我认为一般来说,如果您想提供嵌入式 Web 服务器/Web 服务,那么 jetty 是最简单的方法 (jetty.codehaus.org/jetty)
  • 我同意。但是其中一个库不能处理 Jetty 7 和 8。这就是我尝试嵌入 Tomcat 的原因。哪个直接起作用。 (在今天之前不知道它存在。)
  • 是否可能不支持 jars 内的 jars?
  • 是的,我相信您需要解压缩依赖项 jar 并将所有生成的文件重新打包到您的交付 jar 中。有一些工具可以帮助解决这个问题:stackoverflow.com/questions/183292/…
  • 我只是可以让它工作:通过使用 Assembly 插件展开它,给它一个主类并将来自各种 Spring jar 的所有“spring.handlers”合并到一个“spring.handlers”文件中.我会看看这两个插件中的一个是否可以做到这一点。

标签: java tomcat maven


【解决方案1】:

我尝试了各种库,但没有一个可以完全满足我的要求。你有那些聪明的类加载技巧来保持war文件不变。你已经得到了那些将所有 jar 分解成单独的文件并将它们全部塞进一个可执行 jar 的那些。

在我发现的第一类中,Winstone 是我能找到的最好的。只需添加插件,重建并运行。事实上,有些东西将战争部署到嵌入式 Web 容器中。不幸的是,它的功能不足以运行复杂的 Web 应用程序。

我排除了第二类的解决方案,因为在解压缩包含相同路径的文件的 jar 时会发生文件冲突。通常是 META-INF/.... 更准确地说是与 Spring 相关的元数据。必须将其合并到一个文件中。否则应用程序根本无法启动。

我选择了第三种解决方案:让可执行 jar 包含 war 文件。当它运行时,它会将war文件提取到一个临时目录中,并使用刚刚提取的war文件运行嵌入式Web容器(在我的例子中是Tomcat)。另外在正确的 url 上打开浏览器。

它很容易实现,任何人都可以开始。虽然我更愿意保留 jar 文件,但这可以避免由于类加载或爆炸的 jar 文件冲突而导致的任何并发症。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2017-03-07
    • 2019-09-30
    • 2022-06-10
    • 2012-11-27
    • 1970-01-01
    相关资源
    最近更新 更多