EclipseのGradleプラグイン使ってるときにprovidedCompileで指定しているjarもWEB-INF/libに配備されて困ったときの話


#ことのはじまり
問題が発生したのは、 Jersey MVC の JSP を GlassFish 4.0 で試そうとしたときのこと。

CDI を有効にしてデプロイしたら、 CDI 関連のエラーが発生した。

色々試していたところ、 `build.gradle` の `dependencies` に `providedCompile` で指定していた `jersey-mvc-jsp` をコメントアウトしたら、エラーは発生しなくなった。

いや、 `providedCompile` なのに何で影響あるんすか。。。

調べたところ、どうも Eclipse の Gradle プラグインでインポートした Web アプリプロジェクトは、`build.gradle` の `dependencies` で指定した jar を軒並み `WEB-INF/lib` の下に叩きこむようになってるっぽい。

下は、Eclipse の Maven プラグインで生成した Web アプリプロジェクトの設定と比較した様子。

__Maven の場合__

![mavenの場合.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/10eac07f-b57e-d69f-86c2-6f64b4b879d0.jpeg)

__Gradle の場合__

![gradleの場合.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/04b37cf7-d29c-7f2f-3bf5-2f70ffc9e6b8.jpeg)

Maven プラグインで作った方は `provided` で設定した jar に「公開/エクスポート構造から除外」という設定が入っているが、 Gradle プラグインで作った方にはない。

どうも Gradle プラグインの動きがおかしいっぽい？

#原因と対応策
ググったところ、以下のやりとりを見つける。

[providedCompile in war · Issue #5 · spring-projects/eclipse-integration-gradle · GitHub](https://github.com/spring-projects/eclipse-integration-gradle/issues/5)

__質問__
>[dubacher]
>When publishing the web-project onto the configured server in eclipse the dependencies marked with providedCompile are included in the produced war as well.
>
>Is there a workaround available?
>
>【訳】
>サーバーに Web プロジェクトを公開したら、 providedCompile で設定している依存関係も war に突っ込まれるんだけど、何か解決策あります(´･ω･`)？

__回答__
>[kdvolder]
>The gradle tooling api doesn't tell us which dependencies are 'provided' so we can't treat them specially in the container.
>
>However, I think this case has come up before and a workaround has been implemented.
>
>Just open the Gradle >> WTP preferences page. Add some regexp's there to match the jars you don't want to deploy.
>
>【訳】
>gradle tooling API は、どれが 'provided' の依存関係なのかを教えてくれないから、コンテナ内で特別扱いすることができないんだ。
>
>でも、以前同じ質問があって、解決策も出てたと思うよ。
>
>設定にある [Gralde] の [WTP] を開いて、 __デプロイしたくない jar を正規表現でマッチするように追加してね！__ (`･ω･´)b

mjsk?!

![wtp設定画面.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d8142f25-2548-5497-b92e-de6244071fe2.jpeg)

マジでした。

これ、ワークスペース全体の設定なんすけど...

#Gradle の Eclipse プラグインで WTP のプロジェクトを生成する
おとなしく、 Gradle の Eclipse プラグインを使って WTP プロジェクトを生成することにしました。

##build.gradle に WTP 用の設定を記述する
```groovy:build.gradle
apply plugin: 'war'
apply plugin: 'eclipse-wtp'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.2.1'
    
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    
    testCompile 'junit:junit:4.11', {
        transitive = false
    }
    testCompile 'org.hamcrest:hamcrest-all:1.3'
}

eclipse {
    project {
        name = 'gradle-wtp-sample'
    }
    
    wtp {
        facet {
            facet name: 'jst.java', version: '1.7'
            facet name: 'jst.web', version: '3.0'
        }
        
        component {
            deployName = 'Gradle WTP Sample'
            contextPath  = 'gws'
        }
    }
}
```

後半の `eclipse {` 以降が Eclipse 化するときの設定。

何も設定せずに Eclipse 化すると、 `jst.web` のバージョンが `2.4` と、めがっさ古くなるので `3.0` を明示している。

###生成されるファイルとか
```xml:.settings/org.eclipse.wst.common.project.facet.core.xml
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
	<installed facet="jst.java" version="1.7"/>
	<installed facet="jst.web" version="3.0"/>
</faceted-project>
```

```xml:.settings/org.eclipse.wst.common.component
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="2.0">
	<wb-module deploy-name="Gradle WTP Sample">
		<property name="context-root" value="gws"/>
		<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
		<wb-resource deploy-path="/" source-path="src/main/webapp"/>
		<dependent-module deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/<GRADLE_USER_HOME へのパス>/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.2.1/66f13681add50ca9e4546ffabafaaac7645db3cf/commons-lang3-3.2.1.jar">
			<dependency-type>uses</dependency-type>
		</dependent-module>
	</wb-module>
</project-modules>
```

ちゃんと、 `compile` で指定した依存関係だけが設定されている。

##Eclipse にインポートするときの手順
###Eclipse プロジェクト化する
```text:
>gradle eclipse
```

各人の環境で上記コマンドを実行してもらい、 Eclipse プロジェクト化する。

###Eclipse にインポートする
後は普通に、「既存プロジェクト」として Eclipse にインポートする。

#参考
- [providedCompile in war · Issue #5 · spring-projects/eclipse-integration-gradle · GitHub](https://github.com/spring-projects/eclipse-integration-gradle/issues/5)
- [GradleでEclipseの設定ファイルを生成するときにクラスパス変数GRADLE_REPOを使う - 豆無日記](http://nobeans.hatenablog.com/entry/20110914/1315975552)
- [GradleとEclipseを使う場合のTipsをいくつか紹介 - wadahiroの日記](http://wadahiro.hatenablog.com/entry/20120321/1332287707)
- [EclipseWtpFacet - Gradle DSL](http://gradle.monochromeroad.com/docs/dsl/org.gradle.plugins.ide.eclipse.model.EclipseWtpFacet.html)
- [EclipseClasspath - Gradle DSL](http://gradle.monochromeroad.com/docs/dsl/org.gradle.plugins.ide.eclipse.model.EclipseClasspath.html)
- [EclipseWtpComponent - Gradle DSL](http://gradle.monochromeroad.com/docs/dsl/org.gradle.plugins.ide.eclipse.model.EclipseWtpComponent.html)