5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SpringBoot+Doma2+Gradleで環境構築したら色々ハマった件

Posted at

環境

今回のメイン

  • Windows10 (※Windows Server 2016 Datacenter)
  • eclipse 4.8 Photon (pleiades-2021-03-java-win-64bit-jre_20210328)
  • Java11 (OpenJDK11U-jdk_x64_windows_hotspot_11.0.10_9)
  • Gradle 7.0.2
  • Gradle-Wrapper (=gradlew)
  • SpringBoot 2.5.0
  • Doma2 2.46.1
  • Doma-CodeGen 1.4.0
  • ↑2021.06.05 時点の最新バージョンで実施

AWS Workspaces を使っているため、その実態はWindowsServerでありUIとしてWindows10となっている

メインの他に必要or使用した環境

  • PostgreSQL 13.3-2 (自身の環境に合わせて変更してください)

環境構築方法を知りたい方は構築手順
ハマった内容を確認したい方はハマった点

構築手順

本筋でないところは割愛

  • Postgresのインストール&設定
  • eclipseのインストール

SpringBootプロジェクトを作成する

  • Spring Initializr で作成し、ダウンロードする
    • Project: Gradle Project
    • Language: Java
    • Project Metadata
      • java: 11
      • それ以外は任意
    • ADD Dependencies...
      • Spring Web
      • PostgreSQL Driver
      • Lombok
      • ↑は必要最低限の構成

Gradle-Wrapperの構築

  • ダウンロードしたプロジェクト内のGradle-Wrapperを更新する

    • /path/to/project/gradle/wrapper/gradle-wrapper.properties を編集する
    gradle-wrapper.properties
    
    distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
    
    • プロジェクトディレクトリに移動し、更新コマンドを実行する
    > cd /path/to/project
    > gradlew wrapper
    
    • これによりgradle-wrapper.jargradlewなどのコマンドファイルも更新される

Gradleビルドの設定

`build.gradle`を編集する
build.gradle

    import org.seasar.doma.gradle.codegen.desc.NamingType

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            // Doma-CodeGenの実行時に必要となる設定
            classpath 'org.postgresql:postgresql:42.2.20'
        }
    }

    plugins {
        id 'org.springframework.boot' version '2.5.0'
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id 'java'
        // Doma-Boilerplate プロジェクトの設定を参考にする
        id 'com.diffplug.eclipse.apt' version "3.29.1"
        id 'org.seasar.doma.compile' version '1.1.1-beta1'

        // @see https://github.com/domaframework/doma-codegen-plugin
        // @see https://plugins.gradle.org/plugin/org.seasar.doma.codegen
        id 'org.seasar.doma.codegen' version '1.4.0'
    }

    // ヒミツ
    group = '***.*****.*******'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '11'
    targetCompatibility = '11'

    configurations {
        domaGenRuntime
    }

    test {
        useJUnitPlatform()
    }

    compileJava {
        options.encoding = 'UTF-8'
    }

    compileTestJava {
        options.encoding = 'UTF-8'
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-security'
        implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'

        // https://mvnrepository.com/artifact/org.postgresql/postgresql
        runtimeOnly 'org.postgresql:postgresql'

        // Lombok
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'

        // https://mvnrepository.com/artifact/org.seasar.doma.boot/doma-spring-boot-starter
        implementation group: 'org.seasar.doma.boot', name: 'doma-spring-boot-starter', version: '1.5.0'

        // https://mvnrepository.com/artifact/org.seasar.doma/doma-core
        implementation group: 'org.seasar.doma', name: 'doma-core', version: '2.46.1'

        // https://mvnrepository.com/artifact/org.seasar.doma/doma-processor
        compileOnly group: 'org.seasar.doma', name: 'doma-processor', version: '2.46.1'
        annotationProcessor group: 'org.seasar.doma', name: 'doma-processor', version: '2.46.1'

        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testImplementation 'org.springframework.security:spring-security-test'
    }

    // 筆者の環境ではDoma-CodeGenで使用するDatasource情報をプロパティファイルに外出ししてます
    // user definitions.
    /**
     * Reads properties from the specified .properties file.
     */
    def loadProperties(filename) {
        def props = new Properties()
        file(filename).withInputStream {
            props.load(it)
        }
        return props
    }

    def loadDatasourceProps() {
        return loadProperties("$rootDir/domaCodeGen/property/datasource.properties")
    }

    // doma-codegen-plugin
    domaCodeGen {
        // load datasource info.
        def dsProps = loadDatasourceProps()
        def _url = dsProps.getProperty("origin.url")
        def _user = dsProps.getProperty("origin.username")
        def _password = dsProps.getProperty("origin.password")

        // make an arbitrary named block
        dev {
            url = _url
            user = _user
            password = _password

            // custom template files
            templateDir = file("$projectDir/domaCodeGen/template")
            // configuration for generated entity source files
            entity {
                overwrite = true
                packageName = "***.*****.*******.entity"  // 自身の環境に合わせてください
                namingType = NamingType.SNAKE_LOWER_CASE
                showColumnName = false
                useAccessor = false
                useMappedSuperclass = false
            }
            // configuration for generated DAO source files
            dao {
                overwrite = true
                packageName = "***.*****.*******.dao"  // 自身の環境に合わせてください
            }
            sql {
                overwrite = true
            }
        }
    }


eclipseプロジェクトに変更し、eclipseにインポートする

  • 以下のコマンドを実行すると、eclipseに必要なファイルが生成される(例: .project, .classpathなど)

    > cd /path/to/project
    > gradlew eclipse
    
  • (重要!):thinking: 一般プロジェクトとしてインポートする

    • ファイル > インポート > 一般 > 既存プロジェクトをワークスペースへ

ビルド実行

  • インポート時にeclipseが自動的にインポートすると思いますが念のため
    • プロジェクト > クリーン
    • (重要!):thinking: eclipseが実行するGradle環境の設定
      • ウィンドウ > 設定 > Gradle > Gradle ディストリビューション
        • Gradle ラッパーにチェックを付ける
    • Gradleビルド
      • 実行 > 実行構成 > Gradle タスク
        • 作業ディレクトリ: ${workspace_loc:/プロジェクト名}
        • タスク: build
    • Doma-CodeGenでDao+Entityソースファイルを生成する
      • 実行 > 実行構成 > Gradle タスク
        • 作業ディレクトリ: ${workspace_loc:/プロジェクト名}
        • タスク: domaCodeGenDevAll

ハマった点

  • Doma2とGradle-Plugin(BuildShip)との関係
  • Doma-CodeGenのカスタマイズ

Doma2とGradle-Plugin(BuildShip)との関係

Doma2についての基礎知識

  • Doma2ではJavaのPluggable Annotation Processing APIという仕組みを利用している
  • これによりコンパイル時にソースの自動生成や検証を行ってくれる
    • ソースの自動生成: XxxDaoImp.javaなど
    • 検証: Daoで定義したメソッドに対応するSQLファイルの存在チェックなど
  • Doma2では自動生成ファイルを .apt_generated に格納する
  • 当然、ビルドパスに .apt_generated が存在しないと実行(orコンパイル)できない
    • Doma2ではdoma-compile-pluginにより自動的にビルドパスの設定を行ってくれる
    • 本件では gradlew eclipse を実行したタイミング
  • また、Doma2ではDaoとsqlのパッケージ構成が同一である必要がある
  • サンプルプロジェクトが充実しており、以下のbuild.gradleを参考にした
    • Spring+Doma2の構成だとココ
    • シンプルなDomaプロジェクトはココ

BuildShipについて

  • 知っていることはeclipse公式のGradle-Pluginということだけ
  • 今回はハマったから使わないからね!!!

ハマったポイント

  • Gradle refresh でビルドパスが上書きされる!
    • 実際、.classpathファイルのタイムスタンプが更新されている
    • しかも、.apt_generated の出力先がdefaultに勝手に変更されてしまう!
    • なので、aptの検証時にDaoとSQLファイルの整合性チェックでコンパイルエラーになる
  • 試したこと
    • 公式でのQ&A
      • 回答の通り、dependencies { files(".apt_generated") } など試してもうまくいかなかった
    • ビルドパスの設定でソースフォルダごとに出力フォルダの指定を可能にするのチェックを外せば出力フォルダを統一できるが、テストソースが作れなくなるので却下。
    • 結局。BuildShipを使用することを断念。

BuildShipを使用しない方法

  • eclipseのSpringスタータープロジェクトによるプロジェクト作成はしない
    • ↑強制的にBuildShipが利用される
    • 作成されたプロジェクトからBuildShipに関係のありそうな設定を削除してもeclipseでビルドができなくなるだけ
      • .project<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
      • .settings/org.eclipse.buildship.core.prefsファイル全体など
  • Spring Initializrでプロジェクト作成する
  • gradlew eclipseしてeclipseプロジェクトに変換する
  • eclipseに「一般プロジェクト」としてインポートする

Doma-CodeGenのカスタマイズ

Doma-CodeGenとは?

  • Doma-Genの後継プロジェクトか?⇒GitHub
  • 以前からDomaのソース生成といえばDoma-Genであったがdeprecatedになっている!
  • 記事が長くなったので、Doma-CodeGenでの試行錯誤やその動機を次回に回します。
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?