2
Executable War
Calvin Xiao edited this page 2013-11-14 19:06:57 -08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

##Overview 看ThoughtWorks的技术雷达里面提到了Micro-Service和Embedded Jetty。大家越来越喜欢用一个嵌入式Jetty加一个嵌入式的H2不用依赖任何Container就可以启动一个应用了。

这种嵌入式Embedded有两种风格:

一种是提供一个Zip包里面有一个bin目录放着jsw(Java Service Wrapper),一个lib目录放着Jetty的jar一个webapp目录放着真正的应用一个conf目录放着jetty和jsw的配置文件。用户解开zip包后进入bin目录就可以简单的start/stop应用。像ActiveMQ, Solr, Nexus, Sonar等都是这个风格。

另一种更简洁把jetty的jar包解开成class放入war包里再放一个Main class进去用户用java -jar xxxx.war 就可以启动应用像Jenkins,Selenium的Server等都是这种风格。

在SpringSide的showcae项目里演示了后一种风格同样原理也可以自行制作第一种风格的包。

##打包 在showcase里使用如下就会在target目录生成一个showcase.war和一个showcase-xxx.standalone.war.

mvn package -Pstandalone
  1. 观察一下showcase的pom.xml依赖的Jetty包定义成provided既可以用来编译Main.java又不会打包到WEB-INF/lib中. 然后定义了一个runtime级别的jstl.1.2.jar因为Jetty用的那个Jasper的编译器只懂得从WEB-INF/lib下的jar里的META-INF中找tld而不能从war的/META-INF中找。

  2. 然后是pom.xml里的standalone profile可以看到是使用assembly插件实现showcase-4.xx.standalone.war的打包。

  3. 再观察assembly-standalone.xml
    首先把org.eclipse.jetty*:* 及其依赖的包全部解开class来 然后打包war包里注意要exclude掉META-INF里的内容否则那些*.RDA之类的文件会报jar包签名错之类的错
    然后把原来war包里的内容同样copy到war包里。
    最后从classes中将一个Main.class也copy到war包中。

  4. 再回到pom.xml里assembly插件还会修改war包里的META-INF/Manifest.mf设置main class为刚才那个Main class。

最后再看一下Main.class的实现

  System.setProperty("org.apache.jasper.compiler.disablejsr199", "true");

设置环境变量可确定使用Eclipse的JDT而不是JDK的compiler来编译JSP。Jetty7.5后默认使用JDK Compiler但我的机器上老是报NoJDK郁闷死。

ProtectionDomain protectionDomain = Main.class.getProtectionDomain();
URL location = protectionDomain.getCodeSource().getLocation();
String warFile = location.toExternalForm();

神奇的语句可以通过Main.class找到war包的路径。

String currentDir = new File(location.getPath()).getParent();
File workDir = new File(currentDir, "work");
context.setTempDirectory(workDir);

设置work dir,war包将解压到该目录jsp编译后的文件也将放入其中。

##运行

用java -jar xxx.war -Dport=8082 可以简单的在8082端口(默认为8080)运行应用如果要设置其他JVM参数

java-Xms2048m -Xmx2048m -XX:MaxPermSize=128m -jar xxx.war -Dport=8082

Tomcat

Tomcat的Maven Plugin自带打运行包的功能耶。使用如下命令可以在target目录生成一个showcase-xxx-standalone-tomcat.jar不过暂时有H2 Driver找不到的问题

mvn package -Pstandalone-tomcat