Maven, sbt, cmake, make 等と同様に、ビルドツールとして有名な Gradle の基本的な使い方を、特に Java をビルド対象としてまとめます。2017/05/08 現在、Android における標準のビルドツールです。
参考ドキュメント
- 環境構築
- サンプルデモ
- ユーザーガイド
インストール
事前に JDK または JRE 1.7 以上をインストールしておく必要があります。
macOS / Linux
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
Windows
- こちらから最新バージョンの binary-only をダウンロードして、例えば
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
Java に限らない新規 Gradle プロジェクトの作成
ディレクトリおよびラッパーの作成
以下のコマンドで新規プロジェクトのディレクトリを作成します。
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'
シンプルな copy タスクを設定
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
Java に限らない既存 Gradle プロジェクトのビルド
以下のコマンドで実行可能なタスクを確認して実行します。
./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/gradle
These 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/install
While 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/
Java 新規 Gradle プロジェクトの作成
Java ライブラリの作成
参考ドキュメント: 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
Java アプリケーションの作成
参考ドキュメント: 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
Java Web アプリケーションの作成
参考ドキュメント: 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 の追加
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
にリダイレクトしています。
HTML ファイルの追加
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 の動作を確認できます。
Eclipse 設定
Using the Gradle build system in the Eclipse IDE - Tutorial を参考に Buildship プラグインを導入します。Gradle Tasks ビューから各種タスクが実行可能になります。
関連記事
- Spring Security フォームログインのサンプルコードSpring フレームワークによる Web アプリケーション開発で、ログイン処理を実装する際は Spring Security が便利です。ここでは特に Spring Boot で Web アプリケーションを開発する場合を対象とし、フォームによる ID/Password ログインを行うためのサンプルコードをまとめます。 公式ドキュメント [Spring Security チュートリアル](http...
- Java配列の宣言方法 (C/C++との違い)Javaの配列 Javaの配列宣言方法はC/C++と似ているようで若干異なる。 初期化しない場合 C/C++の int array[10]; はJavaでは int array[] = new int[10]; となる。同様にC/C++の int array[3][3]; はJavaでは int array[][] = new int[3][3]; となる。 初期化
- PlantUML による UML 図の描き方PlantUML はテキスト形式で表現されたシーケンス図やクラス図といった UML (Unified Modeling Language) 図の情報から画像を生成するためのツールです。簡単な使い方をまとめます。 インストール方法の選択 Atom や Eclipse のプラグインをインストールしてエディタから利用する方法、JAR をダウンロードして Java コマンドで実行する方法、Redmine ...
- Akka HTTP サンプルコード (Scala)Akka アクターを用いて実装された汎用 HTTP フレームワークです。Spray の後継です。コアモジュールである akka-http-core は 2016/2/17 に experimental が外れました。akka-http などのいくつかのサブモジュールは 2016/3/1 現在 experimental のままですが、基本的な
- Kestrel の使用例Kestrel は Message Queue (MQ) の実装のひとつです。一般に MQ はアプリケーション間やプロセス間、スレッド間で非同期に通信するために用いられます。メッセージの送信側は MQ に書き込めば受信側の応答を待たずに次の処理に非同期に進むことができます。Kestrel はわずか 2500 行程の Scala で実装されており JVM で動作します。MQ 自体はメモリ上に存在する...