ビルドツールにGradle、IDEにNetBeans、APサーバにGlassFishを使って Web アプリを開発

しようと思ったら、しょっぱなで躓いた。

NetBeans には Gradle プロジェクトを取り込むためのプラグインが存在する。
これを使えば、 Gradle のプロジェクトを取り込むことができる。

しかし、そのままプロジェクトを実行すると `gradle run` というふうにタスクが実行されてしまう。
実際は GlassFish にデプロイして Web アプリケーションとして実行したいわけで、この挙動だと困る。

調べたけど、スマートな方法が見つからず、 Gradle に GlassFish と連携するためのタスクを追加することで対応した。

#普通に Gradle のプロジェクトを作る
```text:フォルダ構成
sample/
|-build.gradle
`-src/main/
  |-java/sample/
  |  |-MyApplication.java
  |  `-HelloResource.java
  `-webapp/
```

```groovy:build.gradle
apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
    compile 'javax:javaee-api:7.0'
}

war {
    baseName = 'sample'
}
```

```java:MyApplication.java
package sample;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("api")
public class MyApplication extends Application {
}
```

```java:HelloResource.java
package sample;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("hello")
public class HelloResource {
    
    @GET
    public String hello() {
        return "Hello World!!";
    }
}
```

#NetBeans に Gradle のプラグインをインストールする。
- [ツール] → [プラグイン] を選択。
- [使用可能なプラグイン]タブを開く。
- 右上の [検索] に `gradle` と入力。
- [Gradle Support] と [Gradle JavaEE Support] が現れるので、両方にチェックを入れて [インストール] をクリック。
- あとは画面の指示に従ってインストールを完了させる。

#NetBeans に、先ほど作った Gradle プロジェクトをインポートする
- [ファイル] → [プロジェクトを開く] を選択。
- [ファイル名] に Gradle プロジェクトへのパスを入力して [プロジェクトを開く] をクリック。

![gradle.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/e666ffc6-0ec5-354f-deb6-508fd7ac3095.jpeg)

#GlassFish と連携するためのタスクを定義する
```groovy:build.gradle
apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
    compile 'javax:javaee-api:7.0'
}

war {
    baseName = 'sample'
}

ext {
    glassFishHome = '<GlassFish をインストールしたフォルダへのパス>'
    asadmin = glassFishHome + (isWindows() ? '/bin/asadmin.bat'
                                           : '/bin/asadmin')
    domain = 'domain1'
}

def isWindows() {
    return System.properties['os.name'].toLowerCase().contains('windows')
}

task startServer(type: Exec) {
    commandLine asadmin, 'start-domain', '--debug=true', domain
}

task stopServer(type: Exec) {
    commandLine asadmin, 'stop-domain', domain
}

task deploy(type: Exec, dependsOn: 'war') {
    commandLine asadmin, 'deploy', '--force=true', war.archivePath
}
```

- `asadmin` コマンドを使って、サーバーの起動・停止・デプロイができるようにタスクを定義している。
- `start-domain` のときに `--debug=true` を指定して、リモートデバッグできるようにしている。

#タスクを実行する
```bash:
# GlassFish を起動する
$ gradle startServer

# GlassFish にアプリをデプロイする
$ gradle deploy

# 試しに API を叩いてみる
$ curl http://localhost:8080/sample/api/hello
Hello World!!

# GlassFish を停止する
$ gradle stopServer
```

#NetBeans でデバッグする
- [デバッグ] → [デバッガのアタッチ] を選択する。
- [デバッガ] に [Javaデバッガ（JPDA）] が、 [コネクタ] に [SocketAttach] が選択されていることを確認。
- [ホスト] に `localhost` と入力、 [ポート] に `9009` と入力※。
- [OK] をクリック。

![gradle.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/cc2561dc-8f59-ff2a-ca1a-ca5d68f8844c.jpeg)

GlassFish に接続し、以後は普通にデバッグできるようになる。

※リモートデバッグのポート番号は、ドメインのログファイル（`<ドメイン>/logs/server.log`）に出力されている。

```text:server.log
[2015-03-04T00:16:58.888+0900] [] [INFO] [NCLS-GFLAUNCHER-00005] [javax.enterprise.launcher] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1425395818888] [levelValue: 800] [[
  JVM invocation command line:
C:\Program Files\Java\jdk8\bin\java.exe
-cp
F:/ProgramFiles/GlassFish/glassfish4/glassfish/modules/glassfish.jar
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9009 ★←これ
-XX:+UnlockDiagnosticVMOptions
（以下略）
```

#参考
- [Gradle task for deploying to Glassfish | sufficiently secure](https://sufficientlysecure.org/index.php/2013/08/03/gradle-task-for-deploying-to-glassfish/)
- [Exec - Gradle DSL Version 2.3](http://gradle.org/docs/current/dsl/org.gradle.api.tasks.Exec.html)