如何部署 Java 应用

Flynn 需要使用 JAVAGradle 构建包, 利用 Maven 或者 Gradle 来完成 JAVA 应用的自动构建和部署。

Flynn 使用 OpenJDK 来运行 JAVA 应用。

应用检测

Flynn 使用下面的规则检测 JAVA 应用:

  • 在应用的根目录下的 pom.xml 文件,表明此 JAVA 应用使用 Maven 构建工具。
  • 在应用的根目录下的gradlewbuild.gradle,或settings.gradle文件,表明此 JAVA 应用使用 Gradle 构建工具。

环境依赖

Maven

当使用 Maven 的时候,将所依赖的软件包加入pom.xml文件的<dependencies>配置项里。

例如,下面的pom.xml配置文件说明编译环境需要log4j的支持:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>io.flynn.example</groupId>
  5. <artifactId>flynn-example</artifactId>
  6. <version>1.0-SNAPSHOT</version>
  7. <packaging>jar</packaging>
  8. <name>flynn-example</name>
  9. <dependencies>
  10. <dependency>
  11. <groupId>log4j</groupId>
  12. <artifactId>log4j</artifactId>
  13. <version>1.2.17</version>
  14. <scope>compile</scope>
  15. </dependency>
  16. </dependencies>
  17. </project>

当包含此配置文件的应用部署到 Flynn 时,系统会自动执行如下的 Maven 命令:

  1. mvn -B -DskipTests=true clean install

上述命令会下载编译依赖的软件包,并将编译结果输出到target目录。

Flynn 默认使用最新版本的 Maven。如果想使用特定版本的 Maven,需要在根目录下创建system.properties文件,在此文件指定 Maven 的版本:

  1. maven.version=3.2.3

使用 Maven 时,关于环境依赖的更多信息,可以参见 Maven 环境依赖文档。

Gradle

使用 Gradle 时,需要使用它的 Java 插件 ,按插件要求的格式在根目录下的build.gradle文件里配置所依赖的软件包。

Flynn 在编译和部署应用的过程中,会运行一系列预定义的stage任务。

例如,下面是一个build.gradle文件,里面声明了编译期间依赖log4j,并且定义了一个stage任务,完成编译清理工作:

  1. apply plugin: "java"
  2. repositories {
  3. mavenCentral()
  4. }
  5. dependencies {
  6. compile group: "log4j", name: "log4j", version: "1.2.17"
  7. }
  8. task stage (dependsOn: ["clean", "jar"])

当包含上述配置文件的应用部署到 Flynn 时,系统自动执行下面的命令:

  1. ./gradlew stage

会下载所依赖的软件,执行编译,并将编译结果放在build目录中。

注意:建议在应用里包含gradlew脚本,这个脚本能检测使用的 Gradle 版本。如果系统中没有,Flynn 会自动安装。但此版本是不确定的。参见 Gradle Wrapper 页面获取更多信息

使用 Gradle 时,关于环境依赖的更多信息,可以参见 Gradle 环境依赖文档。

JAVA 运行环境

运行 JAVA 应用时,Flynn 默认使用 OpenJDK 8。OpenJDK 6 和 7 也是可用的。可以修改根目录下的system.properties文件,修改其中的java.runtime.version来更换版本:

  1. ! OpenJDK 6
  2. java.runtime.version=1.6
  3. ! OpenJDK 7
  4. java.runtime.version=1.7

应用类型

可以在应用根目录下的 Procfile 里声明应用的类型,声明的格式是:TYPE: COMMAND

web

一般情况下 WEB 类型的应用会包含 HTTP 路由,通信端口(port)等环境变量,会为应用启动一个 HTTP 服务器。

内嵌 Jetty

内嵌 Jetty 服务器的应用会使用环境变量中定义的端口(port)来启动应用,例如:

  1. import javax.servlet.http.HttpServlet;
  2. import org.eclipse.jetty.server.Server;
  3. public class MyServlet extends HttpServlet
  4. {
  5. // handler definitions
  6. public static void main(String[] args) throws Exception
  7. {
  8. Server server = new Server(Integer.valueOf(System.getenv("PORT")));
  9. // code to set handlers and start the server
  10. }
  11. }

想了解更多关于 Jetty 嵌入的信息,请参见嵌入 Jetty 页面

假如一个应用使用 Gradle 构建工具,通过 Gradle 应用插件创建了名为example的应用,应用的类型在 Procfile 里按如下格式定义:

  1. web: build/install/example/bin/example

外部 Jetty + WAR 包

打包成 WAR 格式的 JAVA 应用需要使用外部的 Servlet 容器来运行。

也可以让 Marven Dependency 插件 自动拷贝一个 jetty-runner JAR 文件的副本到target/dependency 目录,这需要在pom.xml里增加如下配置:

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.apache.maven.plugins</groupId>
  5. <artifactId>maven-dependency-plugin</artifactId>
  6. <version>2.3</version>
  7. <executions>
  8. <execution>
  9. <phase>package</phase>
  10. <goals><goal>copy</goal></goals>
  11. <configuration>
  12. <artifactItems>
  13. <artifactItem>
  14. <groupId>org.mortbay.jetty</groupId>
  15. <artifactId>jetty-runner</artifactId>
  16. <version>7.5.4.v20111024</version>
  17. <destFileName>jetty-runner.jar</destFileName>
  18. </artifactItem>
  19. </artifactItems>
  20. </configuration>
  21. </execution>
  22. </executions>
  23. </plugin>
  24. </plugins>
  25. </build>

将应用打包成 WAR 格式,存储到 target 目录,在 Procfile 文件里定义应用类型:

  1. web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war

原文: http://doc.oschina.net/flynn?t=54097