要说的是, 鄙人所说的方案和这篇文章 http://www.jfinal.com/share/422 没有多大关系, 只是看到这个文章之后, 分享下我这边的方案, 不是说更好的方案, 此方法是我之前自己项目中想要用 jetty 打包部署, 图方便, 这种方式, 提供一种不一样的参考.
方法和该文章所说的方式略有不同, 这里打包出来的结构并不是一个独立的 jar 包.
打包完成后的结构如下:
/-- /conf /bin /lib
conf 放置配置文件信息, bin 存放启动脚本 lib 存放 jar 包依赖 包括项目本身.
具体方式:
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <groupId>com.example</groupId> <artifactId>test</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>test</name> <description>test</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <pro-basedir>${project.basedir}</pro-basedir> <project-charset>UTF-8</project-charset> <version-java>1.8</version-java> <version-jfinal>3.1</version-jfinal> <version-jetty>9.4.6.v20170531</version-jetty> </properties> <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <version>${version-jetty}</version> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> <version>${version-jetty}</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>${version-jfinal}</version> <exclusions> <exclusion> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <resources> <resource> <directory>${basedir}/src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <testResources> <testResource> <directory>${basedir}/src/main/resources</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${version-java}</source> <target>${version-java}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> <includePom>true</includePom> </configuration> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <includes> <!-- 打jar包时,只打包class文件 --> <include>**/*.class</include> </includes> <finalName>${project.artifactId}-${project.version}</finalName> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <id>create-archive</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <tarLongFileMode>gnu</tarLongFileMode> <appendAssemblyId>false</appendAssemblyId> <attach>false</attach> <finalName>${project.name}</finalName> <appendAssemblyId>false</appendAssemblyId> <descriptors> <descriptor>src/main/assembly/pkg.xml</descriptor> </descriptors> <outputDirectory>${project.build.directory}/dist/</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <dependencies> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-filtering</artifactId> <version>1.3</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
是的, 用到了 assembly 插件, 来进行依赖包移动. 在 src/main
目录新增 assembly
且创建 pkg.xml
文件.
pkg.xml
<?xml version="1.0" encoding="UTF-8"?><assembly> <id>dist</id> <formats> <format>dir</format> <format>tar.gz</format> </formats> <baseDirectory>${project.name}</baseDirectory> <includeBaseDirectory>true</includeBaseDirectory> <fileSets> <fileSet> <directory>${project.basedir}</directory> <outputDirectory>/</outputDirectory> <includes> <include>README.md</include> </includes> </fileSet> <fileSet> <directory>${project.basedir}/src/main/resources</directory> <includes> <include>*</include> </includes> <outputDirectory>/conf</outputDirectory> <filtered>true</filtered> </fileSet> <fileSet> <directory>${project.basedir}/src/main/webapp</directory> <outputDirectory>/conf/webapp</outputDirectory> </fileSet> <fileSet> <directory>${project.basedir}/src/main/bin</directory> <includes> <include>*</include> </includes> <outputDirectory>/bin</outputDirectory> <fileMode>0755</fileMode> </fileSet> <fileSet> <directory>${project.basedir}/target</directory> <includes> <!-- dependencySets 只负责将依赖 jar 包移动到 lib, 项目本身手动移过去 --> <include>test*.jar</include> </includes> <outputDirectory>/lib</outputDirectory> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>/lib</outputDirectory> </dependencySet> </dependencySets></assembly>
这样, 整个配置就完成了, 执行 mvn package
指令进行打包, 就能得到一个 tar.gz
的包, 解压后执行 /bin
目录中预先写好的 shell 脚本启动项目.
至于启动的代码怎么写, 这个就很简单了
Boot.java
package com.example.test.core; /** * Created by iaceob on 2017/7/25. */ public class LightSowBoot { private void init() throws LightSowException { Boolean debug = PropKit.getBoolean("test.debug"); int model = ConfKit.getInt("test.model", 0); if (model == 0) throw new RuntimeException("未知的运作模式"); } private String findWebdir() { // 调试模式不自动寻找 webdir 地址, 直接在配置文件写死就好 if (PropKit.getBoolean("test.debug")) return PropKit.get("test.webdir.debug"); // 正常模式下, 通过环境变量去寻找名称是 /webapp 的地址, web.xml 文件便放在这里面 try { Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(""); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (!url.getPath().endsWith("/webapp/")) continue; File file = new File(url.getPath()); if (!file.isDirectory()) continue; return url.getPath(); } return null; } catch (IOException e) { throw new RuntimeException("Can not find webapp."); } } public void boot() { PropKit.use("cfg.properties"); try { this.init(); } catch (RuntimeException e) { log.error(e.getMessage(), e); } int port = PropKit.getInt("test.srv.port"); try { Server server = new Server(port); WebAppContext ctx = new WebAppContext(); String webdir = findWebdir(); ctx.setResourceBase(webdir); ctx.setDescriptor(String.format("%s/WEB-INF/web.xml", webdir)); ctx.setContextPath("/"); ctx.setParentLoaderPriority(true); ctx.setConfigurations(new Configuration[]{ new WebXmlConfiguration(), new WebInfConfiguration(), // new TagLibConfiguration(), new MetaInfConfiguration(), new FragmentConfiguration(), new JettyWebXmlConfiguration() }); log.info("Server listen {}", port); server.setHandler(ctx); server.start(); server.join(); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
到这里就结束了, web.xml 的内容就不用我贴了吧.
最后, 打包, 解压后的目录结构应该像这样
. |-conf | |-webapp | |-web.xml |-bin | |-boot.sh |-lib |-a.jar |-b.jar
启动脚本可以看这里 啟動 Java 程序 Shell 腳本
题外话, 关于这个使用 jetty 的启动方式, 其实还可以继续玩下去, 达到不需要写 web.xml 配置文件, 只需要在进行一次封装即可, 重写 JfinalConfig 提供一个启动方法, 继承 Config 后写 main 方法调用即可.