公司同事的项目整合jetty实现自启动配置碰到困难,因此,花了点时间上网查了资料,进行了试验,解决了网上资料中的一些坑,成功的将一个原有的工程改造成jetty自启动工程。现录如下。
原有的工程本身就是ssm+maven工程,因此,引入的工程包通过pom方式进行引入。ssm的配置方式不在本文阐述范围,略。
1.改造pom.xml,加入字符编码配置,否则代码中有中文,后期用maven进行打包的时候会报错。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> </properties>
2.在pom.xml中加入jetty依赖。
<properties> <jetty.version>9.0.2.v20130417</jetty.version> </properties> <dependencies> <!-- jetty --> <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> </dependency> <!-- jsp解析采用这个页面会报错,因此采用jsp-2.1-glassfish <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-jsp</artifactId> <version>${jetty.version}</version> </dependency> --> <!-- https://mvnrepository.com/artifact/org.mortbay.jetty/jsp-2.1-glassfish --> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jsp-2.1-glassfish</artifactId> <version>9.1.02.B04.p0</version> </dependency> </dependencies>
这里的坑就是jsp包,采用jetty-jsp,在win下启动的时候打开jsp页面会报
PWC6345: There is an error in invoking javac. A full JDK (not just JRE) is required
但是本地的JAVA_HOME设置,PATH设置都是正确的,最后换了glassfish的包问题才得到解决。
3.启动类编写
package com.musa.base; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.webapp.WebAppContext; import java.io.File; import java.net.URL; import java.security.ProtectionDomain; public class Launcher { public static final int DEFAULT_PORT = 8080; public static final String DEFAULT_CONTEXT_PATH = "/jetty-demo"; private static final String DEFAULT_APP_CONTEXT_PATH = "src/main/webapp"; public static void main(String[] args) { runJettyServer(DEFAULT_PORT, DEFAULT_CONTEXT_PATH); } public static void runJettyServer(int port, String contextPath) { Server server = createJettyServer(port, contextPath); try { server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); } finally { try { server.stop(); } catch (Exception e) { e.printStackTrace(); } } } public static Server createJettyServer(int port, String contextPath) { Server server = new Server(port); server.setStopAtShutdown(true); ProtectionDomain protectionDomain = Launcher.class.getProtectionDomain(); URL location = protectionDomain.getCodeSource().getLocation(); String warFile = location.toExternalForm(); WebAppContext context = new WebAppContext(warFile, contextPath); context.setServer(server); // 设置work dir,war包将解压到该目录,jsp编译后的文件也将放入其中。 String currentDir = new File(location.getPath()).getParent(); File workDir = new File(currentDir, "work"); context.setTempDirectory(workDir); server.setHandler(context); return server; } public static Server createDevServer(int port, String contextPath) { Server server = new Server(); server.setStopAtShutdown(true); ServerConnector connector = new ServerConnector(server); // 设置服务端口 connector.setPort(port); connector.setReuseAddress(false); server.setConnectors(new Connector[] {connector}); // 设置web资源根路径以及访问web的根路径 WebAppContext webAppCtx = new WebAppContext(DEFAULT_APP_CONTEXT_PATH, contextPath); webAppCtx.setDescriptor(DEFAULT_APP_CONTEXT_PATH + "/WEB-INF/web.xml"); webAppCtx.setResourceBase(DEFAULT_APP_CONTEXT_PATH); webAppCtx.setClassLoader(Thread.currentThread().getContextClassLoader()); server.setHandler(webAppCtx); return server; } }
4.配置maven打包插件
<build> <finalName>jetty-demo</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <target>1.7</target> <source>1.7</source> <encoding>UTF-8</encoding> </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> <tasks> <copy todir="${project.build.directory}/${project.artifactId}/"> <fileset dir="${project.build.directory}/classes/"> <include name="**/*/Launcher.class" /> </fileset> </copy> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.musa.base.Launcher</mainClass> </transformer> </transformers> <artifactSet> <includes> <include>org.eclipse.jetty:*</include> <include>*:javax.servlet*</include> <include>org.glassfish:javax.el*</include> </includes> </artifactSet> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.0</version> <configuration> <descriptors> <!--描述文件路径 --> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
这里的关键是配置maven-assembly-plugin这个插件,configuration应放置到plugin下,如果放到execution里,打包时会一直报找不到配置文件的错误。
其中maven-shade-plugin插件用于将特定的第三方依赖追加到将要编译打包的jar里面(or war),使得该jar成为可运行的jar(or war)。
<mainClass>指向main函数所在的类,在该项目中为Launcher类。<artifactSet>的<includes>里面指定需要整合到jar里面的第三方依赖库。
另外,由于项目为web项目,打成war包的时候Launcher类所在的目录为/WEB-INF/class下,我们需要将它移动到war包根目录,因此我们使用maven-antrun-plugin插件来完成这个需求
5.打包
打包是通过maven-assembly-plugin实现,插件通过读取配置文件进行打包操作。配置文件assembly.xml配置如下。
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd"> <id>standalone</id> <formats> <format>zip</format> </formats> <dependencySets> </dependencySets> <files> <file> <source>target/${project.artifactId}.war</source> <outputDirectory></outputDirectory> </file> </files> <fileSets> <fileSet> <directory>srcmainassemblyin</directory> <outputDirectory>in</outputDirectory> <includes> <include>start.sh</include> </includes> <fileMode>0755</fileMode> <lineEnding>unix</lineEnding> </fileSet> <fileSet> <directory>srcmainassemblyin</directory> <outputDirectory>in</outputDirectory> <includes> <include>start.bat</include> </includes> </fileSet> </fileSets> </assembly>
6.maven打包并运行。
到这这步,进入工程根目录,调出cmd,执行mvn clean package,打包后会在本地形成jetty-demo.war和jetty-demo-standalone.zip,其实只需要jetty-demo.war就行了。
在jetty-demo.war所在目录执行java -jar jetty-demo.war,程序走起~