如何部署 Java 应用
Flynn 需要使用 JAVA 或 Gradle 构建包, 利用 Maven 或者 Gradle 来完成 JAVA 应用的自动构建和部署。
Flynn 使用 OpenJDK 来运行 JAVA 应用。
应用检测
Flynn 使用下面的规则检测 JAVA 应用:
- 在应用的根目录下的
pom.xml
文件,表明此 JAVA 应用使用 Maven 构建工具。 - 在应用的根目录下的
gradlew
,build.gradle
,或settings.gradle
文件,表明此 JAVA 应用使用 Gradle 构建工具。
环境依赖
Maven
当使用 Maven 的时候,将所依赖的软件包加入pom.xml
文件的<dependencies>
配置项里。
例如,下面的pom.xml
配置文件说明编译环境需要log4j
的支持:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>io.flynn.example</groupId>
<artifactId>flynn-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>flynn-example</name>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
当包含此配置文件的应用部署到 Flynn 时,系统会自动执行如下的 Maven 命令:
mvn -B -DskipTests=true clean install
上述命令会下载编译依赖的软件包,并将编译结果输出到target
目录。
Flynn 默认使用最新版本的 Maven。如果想使用特定版本的 Maven,需要在根目录下创建system.properties
文件,在此文件指定 Maven 的版本:
maven.version=3.2.3
使用 Maven 时,关于环境依赖的更多信息,可以参见 Maven 环境依赖文档。
Gradle
使用 Gradle 时,需要使用它的 Java 插件 ,按插件要求的格式在根目录下的build.gradle
文件里配置所依赖的软件包。
Flynn 在编译和部署应用的过程中,会运行一系列预定义的stage
任务。
例如,下面是一个build.gradle
文件,里面声明了编译期间依赖log4j
,并且定义了一个stage
任务,完成编译清理工作:
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile group: "log4j", name: "log4j", version: "1.2.17"
}
task stage (dependsOn: ["clean", "jar"])
当包含上述配置文件的应用部署到 Flynn 时,系统自动执行下面的命令:
./gradlew stage
会下载所依赖的软件,执行编译,并将编译结果放在build
目录中。
注意:建议在应用里包含gradlew
脚本,这个脚本能检测使用的 Gradle 版本。如果系统中没有,Flynn 会自动安装。但此版本是不确定的。参见 Gradle Wrapper 页面获取更多信息
使用 Gradle 时,关于环境依赖的更多信息,可以参见 Gradle 环境依赖文档。
JAVA 运行环境
运行 JAVA 应用时,Flynn 默认使用 OpenJDK 8。OpenJDK 6 和 7 也是可用的。可以修改根目录下的system.properties
文件,修改其中的java.runtime.version
来更换版本:
! OpenJDK 6
java.runtime.version=1.6
! OpenJDK 7
java.runtime.version=1.7
应用类型
可以在应用根目录下的 Procfile
里声明应用的类型,声明的格式是:TYPE: COMMAND
。
web
一般情况下 WEB 类型的应用会包含 HTTP 路由,通信端口(port
)等环境变量,会为应用启动一个 HTTP 服务器。
内嵌 Jetty
内嵌 Jetty 服务器的应用会使用环境变量中定义的端口(port
)来启动应用,例如:
import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.server.Server;
public class MyServlet extends HttpServlet
{
// handler definitions
public static void main(String[] args) throws Exception
{
Server server = new Server(Integer.valueOf(System.getenv("PORT")));
// code to set handlers and start the server
}
}
想了解更多关于 Jetty 嵌入的信息,请参见嵌入 Jetty 页面。
假如一个应用使用 Gradle 构建工具,通过 Gradle 应用插件创建了名为example
的应用,应用的类型在 Procfile
里按如下格式定义:
web: build/install/example/bin/example
外部 Jetty + WAR 包
打包成 WAR 格式的 JAVA 应用需要使用外部的 Servlet 容器来运行。
也可以让 Marven Dependency 插件 自动拷贝一个 jetty-runner
JAR 文件的副本到target/dependency
目录,这需要在pom.xml
里增加如下配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>copy</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>7.5.4.v20111024</version>
<destFileName>jetty-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
将应用打包成 WAR 格式,存储到 target
目录,在 Procfile
文件里定义应用类型:
web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war