Maven, sbt, cmake, make 等と同様に、ビルドツールとして有名な Gradle の基本的な使い方を、特に Java をビルド対象としてまとめます。2017/05/08 現在、Android における標準のビルドツールです。
参考ドキュメント
事前に JDK または JRE 1.7 以上をインストールしておく必要があります。
Homebrew または、rbenv 等の影響を受けた SDKMAN! を利用してインストールできます。SDKMAN! の旧称は gvm です。
Homebrew (macOS のみ)
brew install gradle
gradle -v
SDKMAN!
curl -s "https://get.sdkman.io" | bash ←`.bashrc`, `.bash_profile`, `.zshrc` 等に設定が追記
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk version ←`which sdk` では見つかりません
sdk list gradle
sdk install gradle 3.5
sdk current
gradle -v
C:\Gradle\gradle-3.5
に解凍します。GRADLE_HOME
に、解凍したフォルダ C:\Gradle\gradle-3.5
を設定します。PATH
に、解凍したフォルダ内の bin フォルダ C:\Gradle\gradle-3.5\bin
を追記します。インストールされたことを確認します。
gradle -v
こちらのページに記載のとおり、JAVA_OPTS
等による JVM 設定や、build.gradle
における System.setProperty
設定でプロキシ設定が可能です。その他にも gradle.properties
をプロジェクトルートまたは GRADLE_HOME
に設置することで設定可能です。うまくいかない場合は ~/.gradle/
に設置します。
gradle.properties
systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080
systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost
systemProp.https.proxyHost=www.somehost.org
systemProp.https.proxyPort=8080
systemProp.https.nonProxyHosts=*.nonproxyrepos.com|localhost
以下のコマンドで新規プロジェクトのディレクトリを作成します。
mkdir basic-demo
cd basic-demo
touch build.gradle
以下のコマンドで実行可能なタスク一覧が確認できます。
gradle tasks
以下のコマンドで Gradle ラッパーを作成できることが分かります。
gradle wrapper
実行すると以下のようになります。
.
|-- .gradle/
|-- build.gradle
|-- gradle ←生成された
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew ←生成された
`-- gradlew.bat ←生成された
Gradle ラッパーは別の環境で本プロジェクトをビルドする際に利用する gradle コマンド相当のスクリプトです。本環境と同じバージョンの gradle が存在しなければ自動でインストールされます。同じバージョンを使用することで、別の環境でビルドできないといった状況を回避できます。
./gradlew tasks
例えば、上記のコマンドを実行すると、初回実行時は以下のディレクトリに同じバージョンの gradle がインストールされます。
$ ls $HOME/.gradle/wrapper/dists
gradle-3.3-all gradle-3.5-bin
その他 jar ファイルなどは $HOME/.gradle/caches
にダウンロードされます。
設定項目の一覧は以下のコマンドで確認できます。
gradle properties
設定は build.gradle
に記載します。再度 gradle properties
を実行すると値が設定されたことを確認できます。
build.gradle
description = 'A trivial Gradle build'
version = '1.0'
mkdir src
echo 'Hello, World!' > src/myfile.txt
build.gradle
description = 'A trivial Gradle build'
version = '1.0'
task copy(type: Copy) {
from 'src'
into 'dest'
}
以下のコマンドで確認できるタスク一覧に copy
タスクが追加されたことを確認します。
gradle tasks --all
copy
タスクを実行すると dest ディレクトリが作成されて src が dest にコピーされます。
gradle copy
base
プラグインを使ってみるGradle では様々なプラグインが利用可能です。base
プラグインを利用するとプロジェクト一式を zip に固めるタスクを追加できます。
build.gradle
plugins {
id 'base'
}
description = 'A trivial Gradle build'
version = '1.0'
task copy(type: Copy) {
from 'src'
into 'dest'
}
task zip(type: Zip) {
from 'src'
}
以下のコマンドを実行すると zip ファイルが生成されることを確認できます。
gradle tasks --all
gradle zip
ls build/distributions/basic-demo-1.0.zip
以下のコマンドで build
ディレクトリを削除できます。
gradle clean
plugins {}
は build.gradle
の最上部に記述する必要があります。そうでない場合は以下のエラーが発生します。
only buildscript {} and other plugins {} script blocks are allowed before plugins {} blocks, no other statements are allowed
以下のコマンドで実行可能なタスクを確認して実行します。
./gradlew tasks --all ←Windows の場合は './' は不要
gradle
コマンドではなく gradle ラッパースクリプトを使用する、ということに注意します。前述のとおり、gradle ラッパーはビルドする際に利用する gradle コマンド相当のスクリプトです。プロジェクト作成に利用した環境と同じバージョンの gradle が存在しなければ自動でインストールされます。同じバージョンを使用することで、別の環境でビルドできないといった状況を回避できます。
公式ドキュメント内の様々な箇所で gradlew の使用が推奨されています。
You should use the wrapper to build the gradle project. Generally, you should use the wrapper for any wrapper-enabled project because it guarantees building with the Gradle version that the build was intended to use.
https://github.com/gradle/gradleThese wrapper scripts will locate and use the correct version of Gradle if it is already installed on your system, and will otherwise download and install the correct version of Gradle on your behalf.
https://gradle.org/installWhile Gradle versions are very good about supporting backward compatibility, using a wrapper ensures that the user is working with a version of Gradle that the project creator supports, and is therefore considered a good practice.
https://guides.gradle.org/creating-new-gradle-builds/
参考ドキュメント: Building Java Libraries
Gradle の init タスクで Java ライブラリの雛形を生成できます。
mkdir building-java-libraries
cd building-java-libraries
gradle init --type java-library
自動生成されたファイル
.
|-- build.gradle
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
|-- settings.gradle
`-- src
|-- main
| `-- java
| `-- Library.java
`-- test
`-- java
`-- LibraryTest.java
settings.gradle
は複数プロジェクトが存在する場合に利用する設定ファイルです。ビルド時に include
すべきプロジェクトを指定します。
/*
* This settings file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* In a single project build this file can be empty or even removed.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
*/
/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/
rootProject.name = 'building-java-libraries'
build.gradle は以下のようになっています。
/*
* This build file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* user guide available at https://docs.gradle.org/3.5/userguide/java_library_plugin.html
*/
// Apply the java-library plugin to add support for Java Library
apply plugin: 'java-library'
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:21.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
Java ライブラリは他の Java プログラムから利用されるため、API を公開していると考えます。dependencies
における api
では、本ライブラリを利用するために事前に import しておく必要のある Java ライブラリを指定します。implementation
では、本ライブラリをビルドするために必要ではある一方で、ビルド結果を他の Java プログラムから利用するときに import しておく必要はない Java ライブラリを指定します。後者には、Google Guava のように、Java の記法を拡張するようなライブラリが該当します。testImplementation
はテストに関する implementation
です。テストコードを含めたビルド時に必要となる Java ライブラリです。
Library.java
のパッケージ名は無指定となって雛形が生成されます。
/*
* This Java source file was generated by the Gradle 'init' task.
*/
public class Library {
public boolean someLibraryMethod() {
return true;
}
}
LibraryTest.java
/*
* This Java source file was generated by the Gradle 'init' task.
*/
import org.junit.Test;
import static org.junit.Assert.*;
public class LibraryTest {
@Test public void testSomeLibraryMethod() {
Library classUnderTest = new Library();
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
}
}
例えば、以下のコマンドで gradle ラッパースクリプトを利用してビルドします。
./gradlew build
ビルド前にはテストが実行されます。実行結果は HTML で出力されます。
ls build/reports/tests/test/index.html
ビルド結果の成果物は以下の jar ファイルです。
ls build/libs/building-java-libraries.jar
build.gradle に以下の設定を追記することで MANIFEST.MF の設定を変更できます。
jar {
manifest {
attributes('Implementation-Title': project.name,
'Implementation-Version': project.version)
}
}
こちらのページで使い方をまとめた jar コマンドを利用して内容を確認すると以下のようになっています。
$ jar tf build/libs/building-java-libraries.jar
META-INF/
META-INF/MANIFEST.MF
Library.class
$ jar xvf build/libs/building-java-libraries.jar META-INF/MANIFEST.MF
META-INF/MANIFEST.MFが展開されました
$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: building-java-libraries
Implementation-Version: unspecified
以下のコマンドでドキュメントを生成できます。
./gradlew javadoc
ls build/docs/javadoc/index.html
参考ドキュメント: Building Java Applications
Gradle の init タスクで Java アプリケーションの雛形を生成できます。生成されるコードは java-library
の場合と build.gradle
を除いてほぼ同様です。
mkdir java-demo
cd java-demo
gradle init --type java-application
build.gradle
/*
* This build file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at https://docs.gradle.org/3.5/userguide/tutorial_java_projects.html
*/
// Apply the java plugin to add support for Java
apply plugin: 'java'
// Apply the application plugin to add support for building an application
apply plugin: 'application'
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:21.0'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
}
// Define the main class for the application
mainClassName = 'App'
ライブラリではなくアプリケーションであるため、エントリーポイントを mainClassName
で指定しています。また、ライブラリの場合と異なりアプリケーションに依存するアプリケーションは存在しないため、api
と implementation
のように分けずに compile
で記述します。
例えば、以下のように gradle ラッパースクリプトを利用してビルドします。テスト結果もレポートされます。
./gradlew build
ls build/reports/tests/test/index.html
成果物は以下のディレクトリに格納されます。
$ ls build/distributions/
java-demo.tar java-demo.zip
解凍します。
unzip build/distributions/java-demo.zip
(or tar xvf build/distributions/java-demo.tar)
実行用のスクリプトが同封されています。
$ tree java-demo/
java-demo/
|-- bin
| |-- java-demo
| `-- java-demo.bat
`-- lib
|-- guava-21.0.jar
`-- java-demo.jar
実行すると以下のようになります。
$ ./java-demo/bin/java-demo
Hello world.
java コマンドでも以下のように実行できます。
$ java -classpath ./java-demo/lib/java-demo.jar App
Hello world.
ビルドおよび実行結果の確認をまとめて実行できる run タスクが用意されています。
./gradlew run
参考ドキュメント: Building Java Web Applications
mkdir webdemo
cd webdemo
mkdir -p src/main/java ←Java ファイル
mkdir -p src/main/webapp ←その他のファイル (js,css,html,jsp,...)
mkdir -p src/test/java ←Java テストファイル
touch build.gradle
build.gradle
plugins {
id 'java'
id 'war'
id 'org.akhikhl.gretty' version '1.4.2'
}
repositories {
jcenter()
}
dependencies {
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
testCompile 'junit:junit:4.12'
}
providedCompile
は war
プラグインによって提供される設定です。ローカル環境で実行する際にビルドに含める必要があり、成果物の war ファイルを生成するときには不要なライブラリを指定します。上記例では Servlet コンテナが設定されています。同様に、testCompile
はテスト時にビルドに含める必要があり、それ以外のビルドでは不要なライブラリを指定します。
以下のコマンドで gradlew ラッパースクリプトを生成します。
gradle wrapper
Servlet 3.0 より前までは WEB-INF
ディレクトリ内の web.xml
に記載する必要がありましたが、Servlet 3.0 からはアノテーションを利用して設定できるようになりました。サンプルとして以下のような Servlet を作成します。Servlet を providedCompile
で指定した Servlet コンテナで動かして開発します。
mkdir -p src/main/java/org/gradle/demo
touch src/main/java/org/gradle/demo/HelloServlet.java
HelloServlet.java
package org.gradle.demo;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "HelloServlet", urlPatterns = {"hello"}, loadOnStartup = 1)
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().print("Hello, World!");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
if (name == null) name = "World";
request.setAttribute("user", name);
request.getRequestDispatcher("response.jsp").forward(request, response);
}
}
Servlet では引数で渡される request
から情報を get します。response
を利用して情報を返します。doGet
では request
は使用せず response
の print で情報を出力しています。doPost
では request
から取得した name
パラメータをもとに、response.jsp
にリダイレクトしています。
touch src/main/webapp/index.html
touch src/main/webapp/response.jsp
index.html
<html>
<head>
<title>Web Demo</title>
</head>
<body>
<p>Say <a href="hello">Hello</a></p>
<form method="post" action="hello">
<h2>Name:</h2>
<input type="text" id="say-hello-text-input" name="name" />
<input type="submit" id="say-hello-button" value="Say Hello" />
</form>
</body>
</html>
response.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello Page</title>
</head>
<body>
<h2>Hello, ${user}!</h2>
</body>
</html>
build.gradle
で指定した gretty
プラグインを利用すると、以下のコマンドで Jetty または Tomcat 上で動作確認が行えます。既定値は Jetty です。jetty
プラグインは古く、非推奨扱いです。
./gradlew appRun
http://localhost:8080/webdemo/ にアクセスして GET と POST の動作を確認できます。
Using the Gradle build system in the Eclipse IDE - Tutorial を参考に Buildship プラグインを導入します。Gradle Tasks ビューから各種タスクが実行可能になります。