EclipseにおけるGWTサンプルの設定を再現するbuild.gradle

2018年8月18日

Eclipseのウィザードを使用して、GWTサンプルを作成した場合のGWTの設定状態を再現するbuild.gradleを作成してみる。

これが必要な理由

GradleのEclipseプラグインのcleanEclipse,eclipseタスクを実行すると、gradleのdependenciesの内容をもとにして勝手にビルドパスを設定などしてくれる。具体的には、dependenciesに記述されたライブラリを勝手にダウンロードし、.projectおよび.classpathの値を設定してくれるのである。

Eclipseの統合開発環境において、もっともやってほしいことを自動的にやってくれる。これを手作業でいちいち行うのは非常に面倒だからだ。

しかし、その代わりに、Eclipseの統合環境にて手作業で行った設定などは一切無視してしまう。特に、GWT使用の指定等を.project、.classpathする必要があるのだが、これらbはきれいさっぱり削除されてしまう。

ということは、dependenciesの内容をgradleが.classpathに自動設定する一方で、GWTの設定等はこちらで追加してやらねばならない。

環境とサンプルの作成方法

以下の環境だ。

  • Eclipse Oxygen 4.7.3a
  • GWT Eclipse Plugin 3.0.0.201710131939
  • GWT 2.8.2

GWTサンプルの作成方法

以下のように単純に作成する。

以下のプロジェクトが作成される。

追加する依存ライブラリ

追加する依存としては単純なものを選択する。

dependencies {    
  compile group: 'javax.inject', name: 'javax.inject', version: '1'
}

.classpathと.projectの内容

GradleのEclipseプラグインによって再現したいのは以下のファイルである。

.classpath

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="bin/main" path="src">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
    <classpathentry kind="lib" path="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar" sourcepath="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/a00123f261762a7c5e0ec916a2c7c8298d29c400/javax.inject-1-sources.jar">
        <attributes>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="com.gwtplugins.gwt.eclipse.core.GWT_CONTAINER"/>
    <classpathentry kind="output" path="bin/default"/>
</classpath>

.project

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>sample</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.wst.common.project.facet.core.builder</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
        <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
    </natures>
</projectDescription>

ビルドパスは以下の状態になっている。

これを再現するbuild.gradle

完全ではないし、他のやり方もあるかもしれないが、現在のところこれを再現するbuild.gradleは以下になる。

apply plugin: 'java'
apply plugin: 'eclipse'

repositories {
  jcenter()
}

sourceSets {
  main {
    java {
      srcDir 'src'
    }
    resources {
      srcDir 'src'
    }
  }
}

dependencies {    
  compile group: 'javax.inject', name: 'javax.inject', version: '1'
}

import org.gradle.plugins.ide.eclipse.model.*;

eclipse {
  project {
    natures 'com.gwtplugins.gwt.eclipse.core.gwtNature'
    natures 'org.eclipse.wst.common.project.facet.core.nature'
    buildCommand 'org.eclipse.wst.common.project.facet.core.builder'
    buildCommand 'com.gwtplugins.gdt.eclipse.core.webAppProjectValidator'
    buildCommand 'com.gwtplugins.gwt.eclipse.core.gwtProjectValidator'
  }  
  classpath {    
    file {    
      whenMerged { cp->
        List libs = new ArrayList();
        cp.entries.each {
          if (it instanceof Library) libs.add(it);
        }        
        cp.entries.clear();
        cp.entries.add(new SourceFolder('src', null));
        cp.entries.add(new SourceFolder('test', 'test-classes'));
        cp.entries.add(new Container('com.gwtplugins.gwt.eclipse.core.GWT_CONTAINER'));
        cp.entries.add(new Container('org.eclipse.jdt.launching.JRE_CONTAINER'));
        cp.entries.add(new Output('war/WEB-INF/classes'))        
        cp.entries.addAll(libs);
      }     
    }
  }  
}

再現結果

再現結果としては以下だ。

.project

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>sample</name>
    <comment></comment>
    <projects/>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
        <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
    </natures>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.wst.common.project.facet.core.builder</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name>
            <arguments/>
        </buildCommand>
    </buildSpec>
    <linkedResources/>
    <filteredResources/>
</projectDescription>

.classpath

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry output="test-classes" kind="src" path="test"/>
    <classpathentry kind="con" path="com.gwtplugins.gwt.eclipse.core.GWT_CONTAINER"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry path="war/WEB-INF/classes" kind="output"/>
    <classpathentry sourcepath="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/a00123f261762a7c5e0ec916a2c7c8298d29c400/javax.inject-1-sources.jar" kind="lib" path="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar">
        <attributes>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
</classpath>

gradleのGWTプラグインで簡単に行う方法

苦労して上記を行ってみたのだが、jiakuan版Gradle-GWTプラグインマニュアルを使えば自動的に行ってくれることがわかった。このプラグインをeclipseプラグインと共に使用すると、eclipseプラグインに、上記の処理の機能を追加してくれる。

しかし、このプラグインだけでは完全に同じ状態にはならない。若干の修正が必要になる。

例えば、以下のbuild.gradleを記述する。

※warプラグインは使わない。これを使用するとWTP関連のタスクが実行されてしまい、意図したものには全くならなくなる

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'gwt'

repositories {
  jcenter()
}
buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'org.wisepersist:gwt-gradle-plugin:1.0.6'
  }
}

sourceSets {
  main {
    java {
      srcDir 'src'
    }    
    resources {
      srcDir 'src'
    }    
  }
}

dependencies {    
 compile group: 'javax.inject', name: 'javax.inject', version: '1'
}

eclipse {
  project {
    // 追加のnature,buildCommand
    natures 'org.eclipse.wst.common.project.facet.core.nature'
    buildCommand 'org.eclipse.wst.common.project.facet.core.builder'
    buildCommand 'com.gwtplugins.gdt.eclipse.core.webAppProjectValidator'
  }
  classpath {
    // デフォルトの出力先
    defaultOutputDir = file('war/WEB-INF/classes')
    file {
      whenMerged { cp->
        // 出力指定をつぶしておかないと、'war/WEB-INF/classes'に出力してくれない
        cp.entries.findAll{ it.kind == 'src' }.each{
          it.output = null
        }
      }
    }
  }
}

これで、「cleanEclipse eclipse」を行ってみると、以下のファイルが生成される。

.project

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>sample</name>
    <comment></comment>
    <projects/>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
        <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
    </natures>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.wst.common.project.facet.core.builder</name>
            <arguments/>
        </buildCommand>
        <buildCommand>
            <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name>
            <arguments/>
        </buildCommand>
    </buildSpec>
    <linkedResources/>
    <filteredResources/>
</projectDescription>

.classpath

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry path="war/WEB-INF/classes" kind="output"/>
    <classpathentry kind="src" path="src">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
    <classpathentry kind="con" path="com.gwtplugins.gwt.eclipse.core.GWT_CONTAINER"/>
    <classpathentry sourcepath="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/a00123f261762a7c5e0ec916a2c7c8298d29c400/javax.inject-1-sources.jar" kind="lib" path="C:/Users/admin/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar">
        <attributes>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
</classpath>