maven打造可执行war包(超详细)

来源:互联网 发布:c语言长整型定义 编辑:程序博客网 时间:2024/06/06 03:39

在开发java Web时,有时我们会使用嵌入式jetty来运行,项目完成后,如果能够直接运行war包从而启动jetty来运行war包那就非常完美了,本文将讲解如何在项目中整合jetty 9,并构造可执行的war包(打包前和打包后都能随时启动)。

1.首先添加jetty 9的依赖(本文暂时只用到了jetty的以下依赖,读者根据自己的项目需要增加)

<dependency>    <groupId>org.eclipse.jetty</groupId><artifactId>jetty-server</artifactId><version>9.2.7.v20150116</version></dependency><dependency>    <groupId>org.eclipse.jetty</groupId>    <artifactId>jetty-webapp</artifactId>    <version>9.2.7.v20150116</version></dependency>

2.项目中使用jetty 9。

首先我封装了自己的JettyServer

public class EmbeddedServer {    //public static final Logger logger = LoggerFactory.getLogger(EmbeddedServer.class);   // private static final int DEFAULT_BUFFER_SIZE = 16192;    protected final Server server = new Server();        public EmbeddedServer(int port,String path) throws IOException{    this(port,path,false,null);    }    /**     * use war to start     * @param port     * @param isWar     * @param warPath     * @throws IOException     */    public EmbeddedServer(int port,boolean isWar,String warPath) throws IOException{    this(port,null,isWar,warPath);    }    private EmbeddedServer(int port, String path,boolean isWar,String warPath) throws IOException {        Connector connector = getConnector(port);        server.addConnector(connector);        WebAppContext application = getWebAppContext(path,isWar,warPath);        server.setHandler(application);        server.setStopAtShutdown(true);    }    protected WebAppContext getWebAppContext(String path,boolean isWar,String warPath) {    WebAppContext application;    if(isWar){    application=new WebAppContext();    application.setWar(warPath);    return application;        }else{            application = new WebAppContext(path, "/");            application.setConfigurationDiscovered(true);            application.setParentLoaderPriority(true);            application.setClassLoader(Thread.currentThread().getContextClassLoader());            return application;        }    }    protected Connector getConnector(int port) throws IOException {        HttpConfiguration http_config = new HttpConfiguration();        // this is to enable large header sizes when Kerberos is enabled with AD        //final int bufferSize = getBufferSize();        //http_config.setResponseHeaderSize(bufferSize);        //http_config.setRequestHeaderSize(bufferSize);        ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(http_config));        connector.setPort(port);        connector.setHost("0.0.0.0");        server.addConnector(connector);        return connector;    }    /*protected Integer getBufferSize() {        try {            Configuration configuration = ApplicationProperties.get();            return configuration.getInt("sysimple.jetty.request.buffer.size", DEFAULT_BUFFER_SIZE);        } catch (Exception e) {            // do nothing        }        return DEFAULT_BUFFER_SIZE;    }*/    public void start() throws Exception {        server.start();          //logger.info("********************************************************");        //logger.info("The SySimple Has Started !!!");        server.join();    }    public void stop() {        try {            server.stop();        } catch (Exception e) {            //logger.warn("Error during shutdown", e);        }    }}

接着可以使用封装好的EmbeddedServer来启动war

public class StartWeb{private static EmbeddedServer embeddedServer;public static void main(String[] args){//Start web serverint port=3000try{        if(args.length==0){            //该方式能够在开发时快速启动            embeddedServer=new EmbeddedServer(port, "src/main/webapp");            }else{                //传入war包的路径,该方法能够在打包完成后启动该war包            embeddedServer=new EmbeddedServer(port, true, args[0]);            }        embeddedServer.start();        }catch(Exception e){        System.exit(0);        }    }}

注意:打包后如果需要启动war包,需要使用如下的这种批处理命令来启动:

以批处理命令(start.bat)和server.war在同级目录下为例:(以下是start.bat的内容)

@echo offset bat_dir=%~dp0java -jar  %bat_dir%/web.war %bat_dir%/web.war

读者可以考虑在代码中得到war包的路径,这样可以在启动时省去传参。

  1. 下面是最重要的:使用Maven构建可执行war包

总的来说可执行war包是将war包的结构仿照jar包的结构进行改变,第一个是需要在manifest中标记出主方法,第二个是编译后的代码(包,而非.class)必须放在war包的最外层,最后要能够找到项目的依赖。

①标记主方法

通过maven-war-plugin在manifest中标记主方法入口

<plugin>              <groupId>org.apache.maven.plugins</groupId>              <artifactId>maven-war-plugin</artifactId>              <configuration>                <archive>                    <manifest>                        <mainClass>org.bit.linc.web.commons.StartWeb</mainClass>                    </manifest>                </archive>            </configuration>         </plugin>

②拷贝(也可以移动)web的所有的代码到war包最外层(使用maven-antrun-plugin)

<plugin>                <groupId>org.apache.maven.plugins</groupId>                  <artifactId>maven-antrun-plugin</artifactId>                  <executions>                    <execution>                          <id>main-class-placement</id>                          <phase>prepare-package</phase>                          <configuration>                              <target>                                <copy todir="${project.build.directory}/${project.artifactId}/">                                      <fileset dir="${project.build.directory}/classes/">                                          <include name="**/*.*" />                                    </fileset>                                  </copy>                            </target>                          </configuration>                          <goals>                            <goal>run</goal>                          </goals>                    </execution>                  </executions>              </plugin>

③ 标记所有依赖的位置(将代码拷贝到war最外层后,会出现依赖的类都找不到的情况,因此需要让war包能够查找到这些依赖)

将maven-war-plugin更改为如下内容:

<plugin>              <groupId>org.apache.maven.plugins</groupId>              <artifactId>maven-war-plugin</artifactId>              <configuration>                <archive>                    <manifest>                        <mainClass>org.bit.linc.web.commons.StartWeb</mainClass>                        <addClasspath>true</addClasspath>                        <classpathPrefix>WEB-INF/lib</classpathPrefix>                    </manifest>                </archive>            </configuration>         </plugin>

现在可以构建可执行war包了。

以笔者的项目为例: 构建的war包中META-INF/MANIFEST.MF会变成如下内容:

Manifest-Version: 1.0Built-By: wuboBuild-Jdk: 1.7.0_17Class-Path: WEB-INF/lib/commons-0.0.2.jar WEB-INF/lib/commons-configur ation-1.8.jar WEB-INF/lib/commons-lang-2.6.jar WEB-INF/lib/commons-lo gging-1.1.1.jar WEB-INF/lib/slf4j-api-1.7.7.jar WEB-INF/lib/slf4j-log 4j12-1.7.7.jar WEB-INF/lib/log4j-1.2.17.jar WEB-INF/lib/plugins-0.0.2 .jar WEB-INF/lib/clusters-0.0.2.jar WEB-INF/lib/monitors-0.0.2.jar WE B-INF/lib/jetty-server-9.2.7.v20150116.jar WEB-INF/lib/javax.servlet- api-3.1.0.jar WEB-INF/lib/jetty-http-9.2.7.v20150116.jar WEB-INF/lib/ jetty-util-9.2.7.v20150116.jar WEB-INF/lib/jetty-io-9.2.7.v20150116.j ar WEB-INF/lib/jetty-webapp-9.2.7.v20150116.jar WEB-INF/lib/jetty-xml -9.2.7.v20150116.jar WEB-INF/lib/jetty-servlet-9.2.7.v20150116.jar WE B-INF/lib/jetty-security-9.2.7.v20150116.jar WEB-INF/lib/gson-2.3.1.j arCreated-By: Apache Maven 3.3.9Main-Class: org.bit.linc.web.commons.StartWebArchiver-Version: Plexus Archiver

其中的Class-Path和Main-Class均已经改变。

7 0
原创粉丝点击