GradleのincludeFlatって結局、deprecatedじゃないってことで良いのね?

f:id:ts0818:20220319204745j:plain

nazology.net

「透明マント」や「透明シールド」はフィクションの世界で頻繁に登場します。

人や物を透明化する「ステルスシールド」を開発! - ナゾロジー

それらの実現を夢見て、これまでにも「透明シールドのようなもの」はいくつか開発されてきました。

人や物を透明化する「ステルスシールド」を開発! - ナゾロジー

しかし、それらはどれも技術的に完成度が低く、一時的に話題を集めただけだったようです。

人や物を透明化する「ステルスシールド」を開発! - ナゾロジー

そして最近、イギリスのスタートアップ企業「Invisiblity Shield Co」は、”透明シールドもどき”のイメージを払拭するような、完成度の高いステルスシールドを発表しました。

人や物を透明化する「ステルスシールド」を開発! - ナゾロジー

⇧ 透明と聞くと、

『お前もボディを透明にしてやろうか!(「冷たい熱帯魚[監督:園子温]」)』

という台詞を思い出してしまいますね。


冷たい熱帯魚 [Blu-ray]

俳優の演技力が凄まじいです。

冒頭から脱線しましたが、今回はJava関連です。レッツトライ~。

deprecatedにするって言ってたような...

なかなかカオスな感じなのですが、

docs.gradle.org

Gradle 7.1 deprecated project layouts where subprojects were located outside of the project root. However, based on community feedback we decided to roll back in Gradle 7.4 and removed the deprecation. As a consequence, the Settings.includeFlat() method is deprecated in Gradle 7.1, 7.2, and 7.3 only.

https://docs.gradle.org/current/userguide/upgrading_version_7.html

⇧ コミュニティの声を反映して、deprecatedを撤回となってるのだけど、そもそもとして、何でdeprecatedにしようとしたのかがいまいち判然としないんですよね...

フラットな構造のMulti Projectは、application.propertiesで別プロジェクトのapplication.propertiesを読み込めない...

何て言うか、Spring Frameworkがイケてないのかが分からんのだけど、フラットな構造のMulti Projectだと、別プロジェクトのapplication.propertiesを読み込むことはできないっぽい...というか、一番需要がありそうなとこだと思うのだけど、何故かドキュメントでも触れられていないというね...

そもそもとして、

spring.pleiades.io

spring.config.name および spring.config.location は、どのファイルをロードする必要があるかを判断するために非常に早い段階で使用されるため、環境プロパティ(通常は OS 環境変数システムプロパティ、またはコマンドライン引数)として定義する必要があります。

https://spring.pleiades.io/spring-boot/docs/2.1.3.RELEASE/reference/html/boot-features-external-config.html

⇧ OS依存してしまってる時点で、Javaが謳ってる「Write once, run anywhere」とは相容れないと言った感じでしょうか。

docs.spring.io

Windowsでは、ドライブプレフィックスが絶対に付いている場合は、ファイルURLに追加の「/」が必要です(たとえばfile:///${user.home}/config-repo)。

https://docs.spring.io/spring-cloud-config/docs/3.0.0/reference/html/

⇧ う~ん、どうにもイケてない...

なんか、multi projectにするメリットって、共通で使いたいものを分けておくってことに尽きるとは思うんですが、それを読み込む方法が無いっていうのが残念過ぎるという...

結局2重管理になってしまうのが哀しい...

フラットな構造でmulti project作ってみた

というわけで、Eclipseで「Spring Boot」なプロジェクトを2つ作ります。

f:id:ts0818:20220319194313p:plain

⇧「api」「dao」ってプロジェクトを作成。

まずは、「dao」のほうから。

利用するデータベースやデータベースのポート番号などデータベース接続情報は、ご自身の環境に合わせてください。

■/dao/settings.gradle

rootProject.name = 'dao'   

■/dao/build.gradle

plugins {
	id 'org.springframework.boot' version '2.6.4'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'org.postgresql:postgresql'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

■/dao/src/main/resources/application.properties

spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:postgresql://localhost:5434/test?currentSchema=public
spring.datasource.url=jdbc:postgresql://localhost:5434/test
spring.jpa.properties.hibernate.default_schema=public
spring.datasource.username=postgres
spring.datasource.password=postgres 

■/dao/src/main/java/com/example/demo/model/entity/User.java

package com.example.demo.model.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name="user")
public class User {

	@Id
	@Column(name="id")
	private Long id;

	@Column(name="name")
	private String name;
}   

■/dao/src/main/java/com/example/demo/repository/UserRepository.java

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;

import com.example.demo.model.entity.User;

public interface UserRepository extends JpaRepository<User, Long>, CrudRepository<User, Long> {

}  

■/dao/src/main/java/com/example/demo/DaoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DaoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DaoApplication.class, args);
	}

}    

続きまして、「api」プロジェクトのほう。

■/api/settings.gradle

rootProject.name = 'api'
includeFlat 'dao'    

■/api/build.gradle

plugins {
	id 'org.springframework.boot' version '2.6.4'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	"implementation"(project(":dao"))
}

tasks.named('test') {
	useJUnitPlatform()
}

■/api/src/main/resources/application.properties

server.port=8080

#spring.config.import=file:/dao/src/main/resources/application.properties
#spring.config.additional-location=classpath:/dao/src/main/resources/application.properties

spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:postgresql://localhost:5434/test?currentSchema=public
spring.datasource.url=jdbc:postgresql://localhost:5434/test
spring.jpa.properties.hibernate.default_schema=public
spring.datasource.username=postgres
spring.datasource.password=postgres    

■/api/src/main/java/com/example/demo/service/user/UserService.java

package com.example.demo.service.user;

import java.util.List;

import com.example.demo.model.entity.User;

public interface UserService {
	public List<User> findAllUser ();
}   

■/api/src/main/java/com/example/demo/service/user/UserServiceImpl.java

package com.example.demo.service.user;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.model.entity.User;
import com.example.demo.repository.UserRepository;

@Service
public class UserServiceImpl implements UserService {
	@Autowired
    private UserRepository userRepository;

	@Override
	public List<User> findAllUser () {
	  List<User> userList = this.userRepository.findAll();
	  return userList;
	}
}    

■/api/src/main/java/com/example/demo/controller/UserController.java

package com.example.demo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.model.entity.User;
import com.example.demo.service.user.UserService;

@RestController
@RequestMapping(value="/user")
public class UserController {

	@Autowired
	private UserService userService;

	@GetMapping
	public String hello() {
		return "Hello World";
	}

	@GetMapping(value="/all")
	public List<user> getAllUser () {
		return this.userService.findAllUser();
	}
}   

■/api/src/main/java/com/example/demo/ApiApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApiApplication {

	public static void main(String[] args) {
		SpringApplication.run(ApiApplication.class, args);
	}
}    

で保存。

テーブルは、PostgreSQLのpublicスキーマにtestって名前のデータベースを作って、userテーブルを作ってデータを入れておきます。

カラムが2つだけのシンプルな構成です。idが主キーです。

f:id:ts0818:20220319200146p:plain

f:id:ts0818:20220319200220p:plain

f:id:ts0818:20220319200112p:plain

で、Eclipseで「apiプロジェクト」を選択し起動。

f:id:ts0818:20220319200355p:plain

f:id:ts0818:20220319200434p:plain

f:id:ts0818:20220319200509p:plain

アプリケーションサーバーのTomcatが起動したらば、ブラウザで「http://localhost:8080/user/all」にアクセス。

f:id:ts0818:20220319200659p:plain

「daoプロジェクト」の処理を利用してデータベースから取得できました。
「daoプロジェクト」単体で動かすこともできるので、「daoプロジェクト」のほうで単体テストなど確認もできるかと。

毎度モヤモヤ感が半端ない...

今回はこのへんで。