GWT + delombok でantタスクからGWTコンパイルする

2015.4.14

このブログの内容を行う前の注意

動機

lombokでjavaファイルのボイラーコードを減らしたかったが、lombokでAST変換してからGWTコンパイルすると、以前にコンパイルが通ったjavaファイルでエラーが出るという問題が出たので、delombokを利用するようにした。

環境

antのビルドタスクの作成

  • 記事末尾のxmlファイル2つをプロジェクトのトップディレクトリに置くこと
  • パスなどを適宜修正すること

delombokするファイルについての注意

  • delombokしたいファイルの末尾にはBaseをつけること(*Base.java)。delombokターゲット実行時に、ファイル名・クラス名からBaseを除外したjavaファイルが作成される(*.java)。

ex. ModelDataBase.java(ModelDataBaseクラスを含む)
 -> ModelData.java(ModelDataクラスを含む)

  • ファイルを修正したいときは、いったん *Base.java を編集してから再度delombokターゲットを実行すること。

 (junit実行時などはこれがすごく手間)

  • 他のクラスから利用するときは、*Baseクラスではなく、delombokで生成したクラスのほうを使用すること。

テスト(JUNIT)実行手順

  1. *Base.java の修正
  2. delombokターゲット実行
  3. プロジェクトのリフレッシュ
  4. JUNIT実行

GWT Super Dev Modeでのデバッグ手順

(すでにGWT Super Dev Modeでローカルサーバ実行中の前提で)

  1. *Base.java の修正
  2. gwtcターゲット実行
  3. プロジェクトのリフレッシュ
  4. HTMLページを再読み込み


build-gwtc.xml  (GWT Project からデバッグとテストの内容を除外したもの)

<?xml version="1.0" encoding="utf-8" ?>
<project name="gwt-compile" default="build" basedir=".">
	<import file="build-delombok.xml" />
	
	<!-- コンパイルしたいgwtモジュール 複数指定するときはスペース区切り -->
	<property name="gwt.module" value="com.example.project.Model com.example.project.Client" />
	
	<!-- gwt SDKのあるディレクトリを指定 -->
	<property name="gwt.sdk" location="C:\MyPrograms\eclipse_4.4\plugins\com.google.gwt.eclipse.sdkbundle_2.6.0\gwt-2.6.0" />
	<!-- javaファイルのコンパイルに必要なファイルは lib か war/WEB-INF/lib に入れておくこと -->
	<path id="project.class.path">
		<pathelement location="war/WEB-INF/classes" />
		<pathelement location="${gwt.sdk}/gwt-user.jar" />
		<fileset dir="${gwt.sdk}" includes="gwt-dev*.jar" />
		<!-- Add any additional non-server libs (such as JUnit) -->
		<fileset dir="war/WEB-INF/lib" includes="**/*.jar" />
		<fileset dir="lib" includes="**/*.jar" />
	</path>
	<!-- コンパイルしたいソースファイルの存在するディレクトリ -->
	<path id="source.path">
		<pathelement location=".apt_generated" />
		<pathelement location="src" />
	</path>


	<target name="delombok and gwtc" depends="delombok,gwtc" description="delombok before GWT compile" />
		
	<!-- 1.delombok 2.javac 3.gwtc -->
	<target name="gwtc" depends="javac" description="GWT compile to JavaScript">
		<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
			<classpath>
				<path refid="source.path" />
				<path refid="project.class.path" />
			</classpath>
			<!-- add jvmarg -Xss16M or similar if you see a StackOverflowError -->
			<jvmarg value="-Xmx256M" />
			<!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
			<arg line="${gwt.module}" />
		</java>
	</target>

	<target name="libs" description="Copy libs to WEB-INF/lib">
		<mkdir dir="war/WEB-INF/lib" />
		<copy todir="war/WEB-INF/lib" file="${gwt.sdk}/gwt-servlet.jar" />
		<!-- Add any additional server libs that need to be copied -->
	</target>

	<target name="javac" depends="libs">
		<mkdir dir="war/WEB-INF/classes" />
		<javac includes="**" encoding="utf-8" destdir="war/WEB-INF/classes" source="1.5" target="1.5" nowarn="true" debug="true" debuglevel="lines,vars,source">
			<classpath refid="project.class.path" />
			<src refid="source.path" />
		</javac>
		<copy todir="war/WEB-INF/classes">
			<fileset dir="src" excludes="**/*.java" />
		</copy>
	</target>

	<target name="build" depends="gwtc" description="Build this project" />

	<target name="war" depends="build" description="Create a war file">
		<zip destfile="Foo.war" basedir="war" />
	</target>

	<target name="clean" description="Cleans this project">
		<delete dir="war/WEB-INF/classes" failonerror="false" />
		<delete dir="war/foo" failonerror="false" />
	</target>

</project>

build-delombok.xml

<?xml version="1.0" encoding="utf-8" ?>
<project name="delombok" default="delombok" basedir=".">

	<!-- delombokする前のファイルの一時フォルダ -->
	<property name="dir.delombok.pickup" value=".delombok_generated/source" />
	<!-- delombokした後のファイルの一時フォルダ -->
	<property name="dir.delombok.generated" value=".delombok_generated/dist" />
	<!-- delombokするjavaクラスの接尾辞 -->
	<property name="delombok.template.suffix" value="Base" />

	<target name="delombok" description="">
		<fileset dir="src" id="delombok-src">
			<include name="**/*${delombok.template.suffix}.java" />
			<!--    <exclude name="exclude"/> -->
		</fileset>
		<taskdef classname="lombok.delombok.ant.Tasks$Delombok" classpath="lib/lombok.jar" name="delombok" />

		<delete dir="${dir.delombok.pickup}" />
		<mkdir dir="${dir.delombok.pickup}" />
		<delete dir="${dir.delombok.generated}" />
		<mkdir dir="${dir.delombok.generated}" />
		<_copy-delombok-source />
		<delombok verbose="true" encoding="UTF-8" to="${dir.delombok.generated}" from="${dir.delombok.pickup}">
			<format value="suppressWarnings:skip" />
		</delombok>
		<_copy-delombok-dist />
<!--		<eclipse.refreshLocal /> -->
	</target>

	<!-- delombokされたファイルをsrcにコピー -->
	<macrodef name="_copy-delombok-dist">
		<sequential>
			<echo message="delombokされたファイルをsrcにコピー" />


			<replaceregexp byline="true" flags="g">
				<regexp pattern="(\w+)${delombok.template.suffix}" />
				<substitution expression="\1" />
				<fileset dir="${dir.delombok.generated}" id="_delombok-dist">
					<include name="**/*${delombok.template.suffix}.java" />
				</fileset>
			</replaceregexp>

			<!-- delombokした後のjavaファイルのサブパッケージ 
			<property name="delombok.package.generated" value="generated" /> 
			<replaceregexp byline="true" flags="g">
				<regexp pattern="^package\s(.+);$" />
				<substitution expression="package \1.${delombok.package.generated};" />
				<fileset dir="${dir.delombok.generated}" id="_delombok-dist">
					<include name="**/*${delombok.template.suffix}.java" />
				</fileset>
			</replaceregexp>
			-->

			<copy todir="src" overwrite="true">
				<fileset dir="${dir.delombok.generated}" id="_delombok-dist">
					<include name="**/*${delombok.template.suffix}.java" />
				</fileset>
				<mapper type="glob" from="*${delombok.template.suffix}.java" to="*.java" />
				<!--				<mapper type="regexp" from="^(.+)/([^/]+)${delombok.template.suffix}.java" to="\1/${delombok.package.generated}/\2.java" /> -->
			</copy>
			<pathconvert property="convert-path" refid="_delombok-dist" />
			<echo message="${convert-path}" />
		</sequential>
	</macrodef>


	<!-- delombokするファイルをsrcからコピー -->
	<macrodef name="_copy-delombok-source">
		<sequential>
			<echo message="delombokするファイルをsrcにコピー" />
			<copy todir="${dir.delombok.pickup}" overwrite="true">
				<fileset dir="src" id="_delombok-source">
					<include name="**/*${delombok.template.suffix}.java" />
					<!--    <exclude name="exclude"/> -->
				</fileset>
			</copy>
			<pathconvert property="convert-path" refid="_delombok-source" />
			<echo message="${convert-path}" />
		</sequential>
	</macrodef>

</project>

その他

gwt+scalaなんてのもあるみたいだけど手はださなかった


参考:
delombok
GWT Project