2025年12月13日土曜日

Gradle Wrapperのプロパティファイルが見つからないエラー

12月12日

Gradle Wrapperのプロパティファイルが見つからないエラーですね。以下の手順で解決できます:

解決方法

1. Gradleが直接インストールされているか確認

bash
gradle --version

もしGradleがインストールされていれば、./gradlew の代わりに gradle コマンドを使用できます:

bash
gradle bootRun --args='--spring.profiles.active=dev'

2. Gradle Wrapperを再生成する(推奨)

Gradleがインストールされている場合:

bash
# Gradle Wrapperを生成
gradle wrapper

# その後、gradlewが使えるようになります
./gradlew bootRun --args='--spring.profiles.active=dev'

3. Gradleをインストールしていない場合

Fedoraでは以下のコマンドでインストールできます:

bash
sudo dnf install gradle

インストール後、上記の手順2を実行してください。

4. 別の方法:プロジェクトを再クローン

もし元のリポジトリにGradle Wrapperファイルが含まれていた場合、再度クローンすることで解決することがあります:

bash
cd ~
mv springboot-gradle-blog-main springboot-gradle-blog-main.bak
git clone [リポジトリURL] springboot-gradle-blog-main
cd springboot-gradle-blog-main
./gradlew bootRun --args='--spring.profiles.active=dev'

どの方法を試しますか?gradle --version の結果を教えていただければ、より具体的なアドバイスができます。

hiroppy123@fedora:~/springboot-gradle-blog-main$ sudo dnf install gradle [sudo] hiroppy123 のパスワード: リポジトリの更新を読み込み中: リポジトリを読み込みました。 Failed to resolve the transaction: 引数に一致するものはありません: gradle コマンド ラインに追加してみてください: --skip-unavailable で利用できないパッケージをスキップします hiroppy123@fedora:~/springboot-gradle-blog-main$ sudo dnf search gradle リポジトリの更新を読み込み中: リポジトリを読み込みました。 No matches found. hiroppy123@fedora:~/springboot-gradle-blog-main$ gradle --version bash: gradle: コマンドが見つかりませんでした... hiroppy123@fedora:~/springboot-gradle-blog-main$

12月12日

Fedoraの標準リポジトリにGradleがないようですね。SDKMANを使ってGradleをインストールするのが最適です。

SDKMANでGradleをインストール

1. SDKMANをインストール

bash
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

2. Gradleをインストール

bash
sdk install gradle

3. インストール確認

bash
gradle --version

4. Gradle Wrapperを生成

bash
cd ~/springboot-gradle-blog-main
gradle wrapper

5. アプリケーションを起動

bash
./gradlew bootRun --args='--spring.profiles.active=dev'

別の方法:手動でGradle Wrapperファイルを作成

もし上記がうまくいかない場合、以下のファイルを手動で作成できます:

gradle/wrapper/gradle-wrapper.properties を作成

gradle/wrapper/gradle-wrapper.jar をダウンロード

bash
curl -o gradle/wrapper/gradle-wrapper.jar https://raw.githubusercontent.com/gradle/gradle/master/gradle/wrapper/gradle-wrapper.jar

gradlew スクリプトをダウンロード

bash
curl -o gradlew https://raw.githubusercontent.com/gradle/gradle/master/gradlew 
chmod +x gradlew

その後、./gradlew bootRun --args='--spring.profiles.active=dev' を実行してください。

**SDKMANを使う方法が最も簡単で確実です。**どちらの方法を試しますか?

依存関係が怪しいので、リフレッシュする方法や、Java25を使う是非と、やり方について、雑学や業界話も交えながら解説してください。

12月12日

Gradle依存関係のリフレッシュとJavaバージョン戦略

依存関係のリフレッシュ方法

1. 基本的なリフレッシュコマンド

bash
# キャッシュをクリアして依存関係を再ダウンロード
./gradlew clean build --refresh-dependencies

# より徹底的なクリーン(ビルドキャッシュも削除)
./gradlew clean cleanBuildCache build --refresh-dependencies

# オフラインキャッシュも含めて完全リセット
rm -rf ~/.gradle/caches/
./gradlew clean build

2. 依存関係の確認コマンド

bash
# 依存関係ツリーを表示
./gradlew dependencies

# 特定の設定の依存関係のみ表示
./gradlew dependencies --configuration runtimeClasspath

# 依存関係の競合を確認
./gradlew dependencyInsight --dependency spring-boot-starter-web
```

## Java 25を使うべきか?業界の実情

### 現在の業界標準(2024-2025年)

**本番環境でよく使われているバージョン:**
- **Java 17(LTS)** - 最も人気、
Spring Boot 3系の推奨バージョン
- **Java 21(LTS)** - 新しい案件で採用増加中、
Virtual Threadsなど魅力的な機能
- **Java 11(LTS)** - レガシー案件でまだ多い

**Java 25の立ち位置:**
- 2025年3月リリース予定の**非LTS版**
- 実験的な機能を試すには良いが、本番環境では避けるべき
- 次のLTS版は**Java 26(2026年9月予定)**じゃなくて、
実は**Java 23がLTSになる可能性が高い**

### 業界の面白い話

**「LTS信仰」の実態**
```
企業「うちはLTSしか使わない!」
↓
実際には Java 8(2014年リリース)
を2024年まで使い続ける
↓
セキュリティパッチは切れてるけど
「安定してるから」という謎理論

これ、結構あるあるです😅

Spring Bootとの相性問題

yaml
Spring Boot 3.x: Java 17以上必須
Spring Boot 2.x: Java 8-21対応(でもサポート終了済み)

あなたのプロジェクトでの推奨設定

おすすめ:Java 21を使う

理由:

  1. ✅ LTS版なので長期サポートあり
  2. ✅ Spring Boot 3.xと完全互換
  3. ✅ **Virtual Threads(仮想スレッド)**が使える
  4. ✅ Record Patterns、Pattern Matchingなどモダンな機能
  5. ✅ 企業での採用が増えてきている

Java 21のインストール(SDKMAN使用)

bash
# 利用可能なJavaバージョンを確認
sdk list java

# Java 21をインストール(推奨)
sdk install java 21.0.1-tem

# プロジェクトのデフォルトに設定
sdk use java 21.0.1-tem

# 確認
java -version

Virtual Threadsの魅力(Java 21の目玉機能)

従来のスレッドモデルの問題:

java
// 従来:OSスレッドは重い(1スレッド = 約1MB)
// 10,000リクエスト = 10GB メモリ消費 😱
ExecutorService executor = Executors.newFixedThreadPool(10000);

Virtual Threadsで解決:

java
// Java 21: 仮想スレッドは軽量(1スレッド = 数KB)
// 100万スレッドでも余裕 🚀
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

Spring Bootでの有効化:

yaml
# application.yml
spring:
  threads:
    virtual:
      enabled: true  # これだけでVirtual Threads有効化!

実践的なトラブルシューティング

依存関係の競合が起きたら

bash
# 1. まず依存関係ツリーを確認
./gradlew dependencies > dependencies.txt

# 2. 競合している依存関係を特定
./gradlew dependencyInsight --dependency jackson-databind

# 3. build.gradleで明示的にバージョン指定
configurations.all {
    resolutionStrategy {
        force 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
    }
}

Gradle Daemon が暴走したら

bash
# Daemonを停止
./gradlew --stop

# プロセスを確認
ps aux | grep gradle

# 強制終了(最終手段)
killall -9 java
```

## 業界のリアルな話

**「最新版使いたい症候群」vs「枯れた技術信仰」**
```
新人エンジニア「Java 25使いましょうよ!最新ですよ!」
↓
ベテラン「Java 8で十分。動いてるものを変えるな」
↓
中堅「いや、せめてJava 17にしましょう...(妥協案)」
↓
結論:Java 11のまま何も変わらない

実際はバランスが大事で:

  • 実験・学習: 最新版を試す価値あり
  • 本番環境: LTS版(Java 17 or 21)を選択
  • レガシー保守: 無理にバージョンアップしない

まとめ:あなたのプロジェクトへの推奨

bash
# 1. Java 21をインストール
sdk install java 21.0.1-tem

# 2. build.gradleでJava 21を指定
# sourceCompatibility = '21'

# 3. 依存関係をリフレッシュ
./gradlew clean build --refresh-dependencies

# 4. アプリケーション起動
./gradlew bootRun --args='--spring.profiles.active=dev'

Java 25は見送って、Java 21を使いましょう!

何か具体的なエラーが出たら、その内容を教えてください。一緒に解決していきましょう!

hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew clean cleanBuildCache build --refresh-dependencies Downloading https://services.gradle.org/distributions/gradle-9.2.1-bin.zip ............10%.............20%.............30%.............40%.............50%.............60%.............70%.............80%.............90%.............100% [Incubating] Problems report is available at: file:///home/hiroppy123/springboot-gradle-blog-main/build/reports/problems/problems-report.html FAILURE: Build failed with an exception. * What went wrong: Task 'cleanBuildCache' not found in root project 'blog'. * Try: > Run gradlew tasks to get a list of available tasks. > For more on name expansion, please refer to https://docs.gradle.org/9.2.1/userguide/command_line_interface.html#sec:name_abbreviation in the Gradle documentation. > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to generate a Build Scan (powered by Develocity). > Get more help at https://help.gradle.org. Deprecated Gradle features were used in this build, making it incompatible with Gradle 10. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/9.2.1/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD FAILED in 28s hiroppy123@fedora:~/springboot-gradle-blog-main$

12月12日

おっと、cleanBuildCacheというタスクは存在しないようですね。Gradle 9.2.1が正常にダウンロードされたので、正しいコマンドでビルドしましょう!

正しい依存関係リフレッシュ方法

bash
# 1. シンプルなクリーンビルド(これで十分)
./gradlew clean build --refresh-dependencies

# 2. もっと徹底的にやりたい場合
rm -rf ~/.gradle/caches/modules-2/
./gradlew clean build --refresh-dependencies

# 3. 利用可能なタスクを確認(参考)
./gradlew tasks
```

## Gradle 9.2.1について(業界トーク)

**おめでとうございます!
最新のGradle 9.2.1がダウンロードされました🎉**

### Gradleバージョンの歴史と業界事情
```
Gradle 4.x (2017-2018) - 
「あの頃は良かった...」by老害エンジニア
Gradle 5.x (2019) - Kotlin DSL本格導入
Gradle 6.x (2020) - 依存関係管理の改善
Gradle 7.x (2021) - Java 16対応
Gradle 8.x (2023) - 大幅な性能向上
Gradle 9.x (2024-2025) - ← 今ココ!最新鋭
```

**実はGradle 9は結構攻めてる**
- まだ「枯れてない」バージョン
- 企業の本番環境では**Gradle 8.x**が主流
- でも学習・開発用には問題なし!

### 面白い業界あるある
```
プロジェクトA: Gradle 4.10(2018年)
↓
新人「バージョン上げましょう!」
↓
先輩「動いてるから触るな」
↓
5年後もGradle 4.10のまま...

Java バージョンの確認と設定

bash
# 現在のJavaバージョンを確認
java -version

# SDKMANでJava 21をインストール(まだなら)
sdk install java 21.0.1-tem
sdk use java 21.0.1-tem

# 再度確認
java -version

build.gradle の推奨設定

プロジェクトの build.gradle を確認・修正してください:

gradle
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

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

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)  // Java 21を使用
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    
    runtimeOnly 'org.postgresql:postgresql'
    
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

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

ビルドを実行

bash
# クリーンビルド(依存関係を再取得)
./gradlew clean build --refresh-dependencies

# ビルドが成功したら起動
./gradlew bootRun --args='--spring.profiles.active=dev'
```

## よくあるエラーと対処法

### エラー1: Java バージョン不一致
```
> Could not target platform: 'Java SE 21' 
using tool chain: 'JDK 17'

対処法:

bash
sdk install java 21.0.1-tem
sdk use java 21.0.1-tem
```

### エラー2: 依存関係が見つからない
```
> Could not resolve com.example:some-library:1.0.0

対処法:

bash
# キャッシュをクリア
rm -rf ~/.gradle/caches/
./gradlew clean build --refresh-dependencies
```

### エラー3: Gradle Daemon のメモリ不足
```
> Expiring Daemon because JVM heap space is exhausted

対処法:

bash
# gradle.properties を作成/編集 
echo "org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m" >> gradle.properties

Gradle 9.2.1 の新機能(雑学)

Configuration Cache の改善

bash
# 2回目以降のビルドが爆速に!
./gradlew build --configuration-cache

これ、実際に使うとビルド時間が30-50%短縮されることも。大規模プロジェクトだと体感できるレベルで速いです。

Build Scan の進化

bash
# ビルドのパフォーマンスを可視化
./gradlew build --scan

どこで時間がかかってるか一目瞭然。「なんでビルド遅いの?」問題の救世主。

現在の状況を確認

bash
# 1. Javaバージョン確認
java -version

# 2. Gradleバージョン確認
./gradlew --version

# 3. プロジェクトの依存関係を確認
./gradlew dependencies --configuration runtimeClasspath

これらのコマンドを実行して、結果を教えてください。特にエラーが出た場合は、その内容を共有していただければ、ピンポイントで解決策を提案できます!

**まずは ./gradlew clean build --refresh-dependencies を実行してみてください。**どうなりましたか?🚀

hiroppy123@fedora:~/springboot-gradle-blog-main$ sdk install java 21.0.1-tem Downloading: java 21.0.1-tem In progress... ######################################################################### 100.0% Repackaging Java 21.0.1-tem... Done repackaging... Installing: java 21.0.1-tem Done installi

pasted

21.0.9-tem   と    openjdk21.0.9             とエラーの件どうしたら良いですか?

12月12日

このエラーはJavaのバージョン不一致が原因です。複数のJavaがインストールされており、Gradleが異なるJavaを使っています。

問題の整理

SDKMANでインストール: Java 21.0.1-tem
システムのJava:        OpenJDK 21.0.9 (Fedoraのパッケージ)
↓
Gradleが混乱して、古いJava 8相当でコンパイルしようとしている

エラーメッセージ class, interface, enumまたはrecordがありません は、Javaコンパイラがソースファイルを正しく認識できていない典型的な症状です。

解決方法

ステップ1: JAVA_HOMEを明示的に設定

bash
# 現在のシェルでJAVA_HOMEを確認
echo $JAVA_HOME

# SDKMANのJavaに切り替え
sdk use java 21.0.1-tem

# JAVA_HOMEを確認(正しく設定されているか)
echo $JAVA_HOME

# 確認
which java
java -version

ステップ2: Gradle用にJAVA_HOMEを明示的に指定

gradle.properties ファイルを作成/編集:

bash
cat > gradle.properties << 'EOF' org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/21.0.1-tem 
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 
EOF

ステップ3: Gradle Daemonをリセット

bash
# 既存のGradle Daemonを停止
./gradlew --stop

# Gradleキャッシュをクリア
rm -rf ~/.gradle/daemon/

# 再ビルド
./gradlew clean build --refresh-dependencies

別解:テストをスキップしてビルド(暫定対応)

テストに問題がある場合、まずはテストなしでビルドしてみましょう:

bash
# テストをスキップしてビルド
./gradlew clean build -x test

# アプリケーションを起動
./gradlew bootRun --args='--spring.profiles.active=dev'
```

## 業界あるある:複数Java問題 😅
```
開発者「Java 21入れました!」
↓
システム「Fedoraに元から入ってるJava 21もあるよ」
↓
SDKMAN「僕もJava 21入れました!」
↓
Gradle「どれ使えばいいの...?(混乱)」
↓
結果:エラー祭り 🎉

これ、Javaあるあるトップ3に入ります。

なぜこうなるのか?

  1. FedoraのJava/usr/lib/jvm/ にインストール
  2. SDKMANのJava~/.sdkman/candidates/java/ にインストール
  3. JAVA_HOME未設定: Gradleが勝手にJavaを探す→間違ったバージョンを使う

推奨:SDKMANのJavaに統一

bash
# Fedoraのシステムパッケージとして入っているJavaを確認
rpm -qa | grep openjdk

# システムのJavaは残しておいて良いですが、優先順位を変更
# SDKMANのJavaを使うように.bashrcに追加
echo 'export JAVA_HOME="$HOME/.sdkman/candidates/java/current"' >> ~/.bashrc
echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bashrc

# 設定を反映
source ~/.bashrc

# 確認
java -version
which java
echo $JAVA_HOME

build.gradle の確認

build.gradle ファイルを確認して、Java Toolchainが正しく設定されているか見てみましょう:

bash
cat build.gradle

もし見せてもらえれば、より具体的な修正案を提案できます!

現実的な次のステップ

まずはこれを試してください:

bash
# 1. gradle.propertiesを作成
cat > gradle.properties << 'EOF'
org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/21.0.1-tem
org.gradle.jvmargs=-Xmx2048m
EOF

# 2. Gradle Daemonを停止
./gradlew --stop

# 3. テストなしでビルド(まず動かすことを優先)
./gradlew clean build -x test

# 4. 成功したら起動
./gradlew bootRun --args='--spring.profiles.active=dev'

これで動けば、後からテストの問題を解決できます。

**うまくいかない場合は、build.gradle の内容を見せてください!**一緒に修正しましょう 🚀

Java21.0.9-temというのもインストール出来る様ですが、21.0.1-temで大丈夫ですか?それと、パスの設定や、openjdkとの違いなどについても解説してください。

12月12日

Java 21.0.9-tem vs 21.0.1-tem とJavaディストリビューションの世界

バージョンの違い:21.0.1 vs 21.0.9

結論:21.0.9-tem の方が良い

bash
Java 21.0.1-tem: 2023年10月リリース(古い)
Java 21.0.9-tem: 2024年10月リリース(最新)
↓
セキュリティパッチとバグ修正が8回分多い!
```

### マイナーバージョンの意味
```
Java 21.0.9
     │ │ └─ パッチバージョン(セキュリティ修正、バグ修正)
     │ └─── マイナーバージョン
     └───── メジャーバージョン

パッチバージョンが上がるたび:

  • セキュリティ脆弱性の修正
  • クリティカルなバグ修正
  • パフォーマンス改善

業界の常識: 同じメジャーバージョン内では、常に最新のパッチバージョンを使うべき。

21.0.9-temにアップグレード

bash
# 最新版をインストール
sdk install java 21.0.9-tem

# デフォルトに設定
sdk default java 21.0.9-tem

# 確認
java -version
# 出力: openjdk version "21.0.9" ...

# 古いバージョンを削除(オプション)
sdk uninstall java 21.0.1-tem
```

## OpenJDK vs tem(Temurin)の違い

### Javaディストリビューションの世界 🌍

**驚愕の事実:** Javaは「オープンソース」なので、
誰でも独自のビルドを配布できる!
```
Java仕様(Oracle管理)
    ↓
OpenJDK(オープンソース実装)
    ↓
┌────────┬─────────┬──────────┐
│ Oracle │ Temurin │ Corretto │ Zulu   │
│  JDK   │ (tem)(Amazon)(Azul)└────────┴─────────┴──────────┘
```

### 主要なJavaディストリビューション

#### 1. **Oracle JDK**
```
提供元: Oracle
ライセンス: 商用利用は有償(個人・開発は無料)
特徴: オリジナル、最も「公式」
業界での立ち位置: 「高いから使わない」が主流
```

#### 2. **Eclipse Temurin (tem)** ⭐️ おすすめ
```
提供元: Eclipse Foundation(Adoptiumプロジェクト)
ライセンス: 完全無料(商用利用も)
特徴: 
  - 旧名 AdoptOpenJDK
  - 最も人気のあるディストリビューション
  - Spring Bootの公式推奨
  - 大企業でも採用多数
品質: ✅ 非常に高い
```

#### 3. **Amazon Corretto**
```
提供元: Amazon
ライセンス: 完全無料
特徴: AWS環境で最適化、長期サポート
業界での立ち位置: AWS使ってるなら候補
```

#### 4. **Azul Zulu**
```
提供元: Azul Systems
ライセンス: 無料版と商用サポート版あり
特徴: エンタープライズ向け、パフォーマンス重視
```

#### 5. **Red Hat OpenJDK**
```
提供元: Red Hat(Fedoraのパッケージ)
ライセンス: 完全無料
特徴: 
  - Fedora/RHEL標準
  - システムパッケージとして提供
  - 安定性重視
注意: バージョン管理がdnf依存で柔軟性低い

技術的な違い

java
コア部分: 全て同じOpenJDKベース
↓
違うのは:
  - ビルド設定
  - パッチの適用タイミング
  - サポート期間
  - バイナリの最適化
```

**実際の互換性:** 99.9%同じ。
アプリケーションコードはどれでも動く。

## なぜ「tem」を選ぶべきか?

### 業界での採用状況(2024-2025年)
```
1: Eclipse Temurin (tem) 45%
2: Amazon Corretto      20%
3: Red Hat OpenJDK      15%
4: Oracle JDK           10%
5: その他                10%
```

### Spring Bootとの相性

**Spring公式ドキュメント推奨順位:**
1.Eclipse Temurin
2.Amazon Corretto
3.Azul Zulu

### 面白い業界話

**Oracle JDK有償化事件」(2019年)**
```
OracleJava 8 Update 211から商用利用は有償ね!」
↓
企業「えっ!?」
↓
大移行祭り → AdoptOpenJDK(現Temurin)へ殺到
↓
結果: Temurinがデファクトスタンダードに

これ、業界に衝撃が走りました。「Javaって無料じゃなかったの?」って。

パス設定の完全ガイド

SDKMANのパス管理の仕組み

bash
# SDKMANのディレクトリ構造
~/.sdkman/
├── candidates/
│   └── java/
│       ├── 21.0.1-tem/          # 古いバージョン
│       ├── 21.0.9-tem/          # 新しいバージョン
│       └── current -> 21.0.9-tem/  # シンボリックリンク
└── bin/
    └── sdkman-init.sh

パスの優先順位

bash
# Linuxのコマンド検索順序
1. カレントディレクトリの実行ファイル (./command)
2. PATHの左側から順番に検索
   例: PATH="/usr/local/bin:/usr/bin:/bin"
       → /usr/local/binが最優先

正しいパス設定

~/.bashrc に追加(推奨設定)

bash
# ~/.bashrc を編集
nano ~/.bashrc

# 以下を追加(ファイルの最後に)
# ---------- Java/SDKMAN設定 ----------
# SDKMANの初期化(これが最重要!)
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ]] && source "$SDKMAN_DIR/bin/sdkman-init.sh"

# JAVA_HOMEを明示的に設定(SDKMANのcurrentを使用)
export JAVA_HOME="$HOME/.sdkman/candidates/java/current"
export PATH="$JAVA_HOME/bin:$PATH"
# -------------------------------------

設定の反映

bash
# 設定を読み込み直す
source ~/.bashrc

# 確認
echo $JAVA_HOME
# 出力: /home/hiroppy123/.sdkman/candidates/java/current

which java
# 出力: /home/hiroppy123/.sdkman/candidates/java/current/bin/java

java -version
# 出力: openjdk version "21.0.9" ...

パスの優先順位を確認

bash
# すべてのjavaコマンドの場所を表示
type -a java

# 正しい出力例:
# java is /home/hiroppy123/.sdkman/candidates/java/current/bin/java
# java is /usr/bin/java  ← システムのJava(使われない)

システムJava(Fedora)との共存

なぜ両方あっても問題ないのか?

bash
システムJava: /usr/bin/java
  ↓
  用途: システムツール用(DNF、Jenkinsなど)
  
SDKMANのJava: ~/.sdkman/candidates/java/current/bin/java
  ↓
  用途: 開発・アプリケーション実行用

PATHの優先順位で分ける

bash
PATH="$JAVA_HOME/bin:...:usr/bin"
      ↑最優先       ↑後回し

システムJavaを削除すべきか?

答え:削除しない方が良い

bash
理由:
1. システムツールが依存している可能性
2. パッケージ管理が複雑になる
3. 共存させても害はない(パスで制御できる)

実践:完全セットアップ

ステップ1: 最新Javaをインストール

bash
# 利用可能なJavaバージョンを確認
sdk list java | grep tem

# 最新版をインストール
sdk install java 21.0.9-tem

# デフォルトに設定
sdk default java 21.0.9-tem

ステップ2: パス設定を確認

bash
# ~/.bashrcにSDKMAN設定があるか確認
grep -n "sdkman" ~/.bashrc

# なければ追加
cat >> ~/.bashrc << 'EOF'

# SDKMAN設定
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ]] && source "$SDKMAN_DIR/bin/sdkman-init.sh"
EOF

# 反映
source ~/.bashrc

ステップ3: プロジェクト設定

bash
cd ~/springboot-gradle-blog-main

# gradle.propertiesを作成
cat > gradle.properties << 'EOF'
# Gradleが使用するJavaを明示的に指定
org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/current

# JVMメモリ設定
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m

# ビルドキャッシュを有効化(高速化)
org.gradle.caching=true

# 並列ビルド有効化
org.gradle.parallel=true
EOF

# Gradle Daemonをリセット
./gradlew --stop

# ビルド
./gradlew clean build -x test

ステップ4: 確認

bash
# Javaバージョン確認
java -version

# Gradleが使うJavaを確認
./gradlew -version

# 両方とも "21.0.9" になっていればOK!

トラブルシューティング

問題1: パスが反映されない

bash
# 原因: シェルが設定を読み込んでいない
# 解決法:
source ~/.bashrc

# または新しいターミナルを開く

問題2: GradleがシステムJavaを使う

bash
# 原因: gradle.propertiesがない
# 解決法: gradle.propertiesを作成(上記参照)

# または環境変数で一時的に指定
JAVA_HOME=~/.sdkman/candidates/java/current ./gradlew build

問題3: 複数バージョンが混在

bash
# インストール済みJavaを確認
sdk list java

# 不要なバージョンを削除
sdk uninstall java 21.0.1-tem
```

## まとめ:ベストプラクティス

### 推奨構成
```
✅ Eclipse Temurin 21.0.9(最新パッチ)
✅ SDKMANで管理
✅ gradle.propertiesで明示的に指定
✅ システムJavaは残す(共存)

次のアクション

bash
# 1. 最新Javaをインストール
sdk install java 21.0.9-tem
sdk default java 21.0.9-tem

# 2. パス確認
source ~/.bashrc
java -version

# 3. プロジェクトビルド
cd ~/springboot-gradle-blog-main
cat > gradle.properties << 'EOF'
org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/current
org.gradle.jvmargs=-Xmx2048m
EOF

./gradlew --stop
./gradlew clean build -x test

# 4. アプリ起動
./gradlew bootRun --args='--spring.profiles.active=dev'

これで完璧なJava環境が整います!🚀

何か質問や追加のトラブルがあれば教えてください!

hiroppy123@fedora:~/springboot-gradle-blog-main$ sdk install java 21.0.9-tem Downloading: java 21.0.9-tem In progress... ######################################################################### 100.0% Repackaging Java 21.0.9-tem... Done repackaging... Installing: java 21.0.9-tem Done installing! Setting java 21.0.9-tem as default. hiroppy123@fedora:~/springboot-gradle-blog-main$ sdk uninstall java 21.0.1-tem removed java 21.0.1-tem. hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew --stop ERROR: JAVA_HOME is set to an invalid directory: /home/hiroppy123/.sdkman/candidates/java/21.0.1-tem Please set the JAVA_HOME variable in your environment to match the location of your Java installation. hiroppy123@fedora:~/springboot-gradle-blog-main$ hiroppy123@fedora:~/springboot-gradle-blog-main$ cat > gradle.properties << 'EOF' # Gradleが使用するJavaを明示的に指定 org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/current # JVMメモリ設定 org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # ビルドキャッシュを有効化(高速化) org.gradle.caching=true # 並列ビルド有効化 org.gradle.parallel=true EOF hiroppy123@fedora:~/springboot-gradle-blog-main$ cat > gradle.properties << 'EOF' # Gradleが使用するJavaを明示的に指定 org.gradle.java.home=/home/hiroppy123/.sdkman/candidates/java/current # JVMメモリ設定 org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # ビルドキャッシュを有効化(高速化) org.gradle.caching=true # 並列ビルド有効化 org.gradle.parallel=true EOF hiroppy123@fedora:~/springboot-gradle-blog-main$ hiroppy123@fedora:~/springboot-gradle-blog-main$ cat > gradle.properties << 'EOF' # Gradleが使用するJavaを明示的に指定 ./gradlew --stop ./gradlew --stop ERROR: JAVA_HOME is set to an invalid directory: /home/hiroppy123/.sdkman/candidates/java/21.0.1-tem Please set the JAVA_HOME variable in your environment to match the location of your Java installation. hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew --stop hiroppy123@fedora:~/springboot-gradle-blog-main$ cat > gradle.properties << 'EOF' # Gradleが使用するJavaを明示的に指定 ./gradlew --stop hiroppy123@fedora:~/springboot-gradle-blog-main$ sdk use java 21.0.1-tem Stop! Candidate version is not installed. Tip: Run the following to install this version $ sdk install java 21.0.1-tem hiroppy123@fedora:~/springboot-gradle-blog-main$         ーーーーー      これはどうしたら良いですか?

12月12日

問題が見えました!環境変数JAVA_HOMEが古い21.0.1-temを指したままになっています。シェルセッションをリフレッシュする必要があります。

解決方法

ステップ1: 新しいターミナルを開く(最も確実)

bash
# 現在のターミナルを閉じて、新しいターミナルを開く
# または以下のコマンドを実行

ステップ2: 環境変数を再読み込み

bash
# .bashrcを再読み込み
source ~/.bashrc

# JAVA_HOMEを確認
echo $JAVA_HOME
# 正しい出力: /home/hiroppy123/.sdkman/candidates/java/current

# Javaバージョンを確認
java -version
# 正しい出力: openjdk version "21.0.9" ...

# whichコマンドでパスを確認
which java
# 正しい出力: /home/hiroppy123/.sdkman/candidates/java/current/bin/java

ステップ3: 手動でJAVA_HOMEを設定(緊急対応)

もしsource ~/.bashrcでも直らない場合:

bash
# 現在のシェルで手動設定
export JAVA_HOME="$HOME/.sdkman/candidates/java/current"
export PATH="$JAVA_HOME/bin:$PATH"

# 確認
echo $JAVA_HOME
java -version

ステップ4: Gradleを実行

bash
cd ~/springboot-gradle-blog-main

# Gradle Daemonを停止(古いJAVA_HOMEを忘れさせる)
./gradlew --stop

# ビルド実行
./gradlew clean build -x test

# 成功したら起動
./gradlew bootRun --args='--spring.profiles.active=dev'

なぜこうなったのか?業界あるあるトーク

環境変数の「記憶」問題

bash
シェル起動時:
  ↓
~/.bashrc読み込み → JAVA_HOME設定
  ↓
この時点で21.0.1-temを記憶
  ↓
途中で21.0.1-temを削除
  ↓
でもシェルは古いJAVA_HOMEを覚えたまま 😅
```

**これ、開発者あるあるトップ5に入ります!**
```
開発者「なんで動かないの?」
↓
先輩「ターミナル再起動した?」
↓
開発者「あ...(再起動)」
↓
先輩「動いた?」
↓
開発者「動きました!」
↓
これが1日に5回は起きる
```

### シェルの環境変数の寿命
```
ターミナルを開く
  ↓
環境変数が設定される
  ↓
【ここからが重要】
この環境変数は「このターミナルが閉じるまで」有効
  ↓
途中でファイルを変更したり、ソフトを削除しても
シェルは「起動時の状態」を覚えたまま

確実な解決手順(順番に試してください)

方法1: 新しいターミナルで試す(最も確実)

bash
# 1. 現在のターミナルを閉じる
# 2. 新しいターミナルを開く
# 3. 以下を実行

cd ~/springboot-gradle-blog-main
java -version  # 21.0.9になっているか確認
./gradlew --stop
./gradlew clean build -x test

方法2: 現在のターミナルで強制リフレッシュ

bash
# SDKMANの初期化スクリプトを再実行
source "$HOME/.sdkman/bin/sdkman-init.sh"

# デフォルトJavaを再設定
sdk default java 21.0.9-tem

# 確認
echo $JAVA_HOME
java -version

# Gradleを実行
cd ~/springboot-gradle-blog-main
./gradlew --stop
./gradlew clean build -x test

方法3: 完全リセット(最終手段)

bash
# すべてのGradle Daemonプロセスを強制終了
pkill -f gradle

# Gradleキャッシュを削除
rm -rf ~/.gradle/daemon/
rm -rf ~/.gradle/caches/

# 環境変数を手動設定
export JAVA_HOME="$HOME/.sdkman/candidates/java/current"
export PATH="$JAVA_HOME/bin:$PATH"

# ビルド
cd ~/springboot-gradle-blog-main
./gradlew clean build -x test

トラブルシューティング チェックリスト

✅ 確認1: currentシンボリックリンク

bash
# currentが21.0.9を指しているか確認
ls -la ~/.sdkman/candidates/java/

# 正しい出力例:
# lrwxrwxrwx  1 hiroppy123 hiroppy123   10 Dec 12 10:30 current -> 21.0.9-tem
# drwxr-xr-x  8 hiroppy123 hiroppy123 4096 Dec 12 10:25 21.0.9-tem

もしcurrentが存在しないか、間違っている場合:

bash
# 手動でシンボリックリンクを作成
cd ~/.sdkman/candidates/java/
rm -f current
ln -s 21.0.9-tem current

✅ 確認2: JAVA_HOMEの値

bash
echo $JAVA_HOME

# 期待される出力:
# /home/hiroppy123/.sdkman/candidates/java/current
# または
# /home/hiroppy123/.sdkman/candidates/java/21.0.9-tem

# 21.0.1-temが含まれていたらNG!

✅ 確認3: Javaコマンドのパス

bash
which java
# 期待される出力:
# /home/hiroppy123/.sdkman/candidates/java/current/bin/java

type -a java
# 最初に表示されるのがSDKMANのJavaであればOK

業界の知恵:環境変数デバッグのコツ

printenvコマンドで全環境変数を確認

bash
# Java関連の環境変数を一覧表示
printenv | grep -i java

# PATH全体を見やすく表示
echo $PATH | tr ':' '\n'

シェル設定ファイルの優先順位

bash
Linuxのシェル起動時の読み込み順序:
1. /etc/profile         # システム全体の設定
2. ~/.bash_profile      # ユーザー個別(ログイン時)
3. ~/.bashrc            # ユーザー個別(シェル起動時)← 通常はここ
4. ~/.bash_login        # レガシー

SDKMANは~/.bashrcに設定を追加します。

最も簡単な解決策(推奨)

bash
# ステップ1: 新しいターミナルを開く

# ステップ2: 以下を実行
cd ~/springboot-gradle-blog-main
java -version  # "21.0.9"と表示されることを確認

# ステップ3: Gradleビルド
./gradlew clean build -x test

# ステップ4: アプリ起動
./gradlew bootRun --args='--spring.profiles.active=dev'

新しいターミナルを開くのが最も確実です!

これで解決しない場合は、以下のコマンドの出力を教えてください:

bash
echo $JAVA_HOME
java -version
ls -la ~/.sdkman/candidates/java/
cat ~/.bashrc | grep -A 5 sdkman

一緒に原因を特定しましょう!🔍

hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew bootRun --args='--spring.profiles.active=dev' > Task :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____|

pasted

やはり、テストからやり直さないと駄目ですか?

12月12日

いえいえ、テストは関係ありません!PostgreSQLが起動していないのが原因です。

問題の診断

エラーメッセージを見ると:

localhost:5432 への接続が拒絶されました
postmaster がTCP/IP接続を受け付けていることを確認してください

Java 21.0.9は正常に動作しています! 🎉 問題はデータベース接続です。

解決方法

ステップ1: Dockerコンテナの状態を確認

bash
# Dockerコンテナが起動しているか確認
docker ps

# もし何も表示されない場合、コンテナが停止しています

ステップ2: Docker Composeで起動

bash
cd ~/springboot-gradle-blog-main

# コンテナを起動
docker-compose up -d

# 起動確認(blog-postgres-devが表示されればOK)
docker ps

ステップ3: PostgreSQLの接続を確認

bash
# PostgreSQLコンテナのログを確認
docker logs blog-postgres-dev

# 正常なら「database system is ready to accept connections」が表示される

ステップ4: アプリケーションを再起動

bash
./gradlew bootRun --args='--spring.profiles.active=dev'
```

## 業界あるある:データベース接続エラー 😅
```
エラーログ: 100行の巨大なスタックトレース
開発者「うわ、何これ!?難しそう...」
↓
先輩「一番下まで見て」
↓
開発者「Connection refused...?」
↓
先輩「DB起動した?」
↓
開発者「あ...」← これが1日5回
```

**実は90%のエラーは、最後の行に答えが書いてあります。**

### スタックトレースの読み方(業界の知恵)
```
【読む順序】
❌ 間違い: 上から読む
✅ 正解:   下から読む(根本原因が最後にある)

あなたのエラー:
Caused by: java.net.ConnectException: 接続を拒否されました
                                      ↑
                                    ここが本質!

Dockerコンテナの状態確認と操作

よく使うDockerコマンド

bash
# 起動中のコンテナを表示
docker ps

# すべてのコンテナを表示(停止中も含む)
docker ps -a

# コンテナを起動
docker-compose up -d

# コンテナを停止
docker-compose down

# コンテナのログを表示
docker logs blog-postgres-dev

# コンテナのログをリアルタイム表示
docker logs -f blog-postgres-dev

# コンテナに入る(デバッグ用)
docker exec -it blog-postgres-dev psql -U postgres

Docker Composeの状態確認

bash
cd ~/springboot-gradle-blog-main

# docker-compose.ymlの内容を確認
cat docker-compose.yml

# コンテナの状態を確認
docker-compose ps

もしDockerが起動していない場合

Dockerサービスの確認(Podman使用時)

Fedoraではdocker-composeが実際にはpodman-composeを使っているので:

bash
# Podmanのコンテナを確認
podman ps

# Podman Composeで起動
podman-compose up -d

# または元のコマンド
docker-compose up -d

トラブルシューティング

問題1: コンテナが起動しない

bash
# エラーログを確認
docker-compose logs

# コンテナを完全に削除して再作成
docker-compose down -v
docker-compose up -d

問題2: ポート5432が既に使用されている

bash
# ポート5432を使用しているプロセスを確認
sudo lsof -i :5432

# または
sudo ss -tulpn | grep 5432

# もし別のPostgreSQLが動いていたら停止
sudo systemctl stop postgresql

問題3: application-dev.ymlの設定確認

bash
# dev環境の設定を確認
cat src/main/resources/application-dev.yml

おそらく以下のような設定のはず:

yaml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/blog_dev
    username: postgres
    password: postgres

正しい起動手順(完全版)

bash
# ステップ1: プロジェクトディレクトリに移動
cd ~/springboot-gradle-blog-main

# ステップ2: Dockerコンテナを起動
docker-compose up -d

# ステップ3: コンテナが起動したか確認
docker ps
# 期待される出力:
# CONTAINER ID   IMAGE          PORTS                    NAMES
# xxxxx          postgres:15    0.0.0.0:5432->5432/tcp   blog-postgres-dev

# ステップ4: PostgreSQLの準備完了を確認(数秒待つ)
sleep 5
docker logs blog-postgres-dev | tail -n 20

# ステップ5: Spring Bootアプリを起動
./gradlew bootRun --args='--spring.profiles.active=dev'

# ステップ6: ブラウザでアクセス
# http://localhost:8080
```

## Spring Bootのログから読み取れること
```
✅ Java 21.0.9で起動している
✅ Spring Boot 3.3.3が動作している  
✅ Tomcatが8080ポートで待機している
✅ devプロファイルが有効になっている
❌ PostgreSQLに接続できない ← 唯一の問題

実は95%成功しています! あとはDBを起動するだけです。

次のステップ

bash
# まずこれを実行
docker-compose up -d
docker ps

# 出力を教えてください

コンテナが起動していれば、すぐにアプリケーションが動き始めますよ!🚀

もしコンテナ起動に問題があれば、エラーメッセージを教えてください。一緒に解決しましょう!

hiroppy123@fedora:~/springboot-gradle-blog-main$ docker ps Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES hiroppy123@fedora:~/springboot-gradle-blog-main$ docker-compose up -d Emulate Dock

pasted

docker-compose.yml

44行

yml

application.properties

48行

text

application-prod.properties

28行

text

ユーザーやパスワードなどのミスですか?     どうしたら良いですか?

12月12日

はい、その通りです!ユーザー名とパスワードが一致していません

問題の特定

docker-compose.yml の設定

yaml
POSTGRES_USER: blog_dev_user
POSTGRES_PASSWORD: dev_password_123
POSTGRES_DB: blog_dev

application.properties の設定

properties
spring.datasource.url=jdbc:postgresql://localhost:5432/blog_dev  ✅
spring.datasource.username=blog_dev_user  ✅
spring.datasource.password=dev_password_123  ✅
```

**実は設定は合っています!** 問題は別にあります。

## 真の原因:Podmanのパーミッション問題
```
ls: can't open '/docker-entrypoint-initdb.d/': Permission denied

このエラーが重要です。PostgreSQLコンテナが正常に起動していません

解決方法

方法1: init-scriptsディレクトリを削除(推奨)

bash
cd ~/springboot-gradle-blog-main

# docker-compose.ymlを編集
nano docker-compose.yml

# 以下の行を削除またはコメントアウト
# - ./init-scripts:/docker-entrypoint-initdb.d  # この行を削除

# 修正後のdocker-compose.yml

修正版のdocker-compose.ymlを作成します:

bash
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  postgres:
    image: postgres:15.3-alpine
    container_name: blog-postgres-dev
    environment:
      POSTGRES_USER: blog_dev_user
      POSTGRES_DB: blog_dev
      POSTGRES_PASSWORD: dev_password_123
    ports:
      - "5432:5432"
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
      # init-scriptsの行を削除
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blog_dev_user"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - blog-dev-network

  pgadmin:
    image: dpage/pgadmin4
    container_name: blog-pgadmin-dev
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@blog.local
      PGADMIN_DEFAULT_PASSWORD: admin123
    ports:
      - "5050:80"
    depends_on:
      - postgres
    networks:
      - blog-dev-network

volumes:
  postgres_dev_data:
    driver: local

networks:
  blog-dev-network:
    driver: bridge
EOF

方法2: Podmanのルートレスモード対応(高度)

bash
# SELinuxのコンテキストを設定
mkdir -p init-scripts
chmod 777 init-scripts

完全な再起動手順

bash
cd ~/springboot-gradle-blog-main

# ステップ1: すべてのコンテナとボリュームを削除
docker-compose down -v

# ステップ2: docker-compose.ymlを修正(上記参照)

# ステップ3: コンテナを再作成
docker-compose up -d

# ステップ4: PostgreSQLの起動を待つ(重要!)
sleep 10

# ステップ5: コンテナの状態を確認
docker ps

# ステップ6: PostgreSQLのログを確認
docker logs blog-postgres-dev

# 正常なら以下が表示される:
# "database system is ready to accept connections"

# ステップ7: PostgreSQL接続テスト
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d blog_dev -c "SELECT version();"

# ステップ8: Spring Boot起動
./gradlew bootRun --args='--spring.profiles.active=dev'
```

## 業界あるある:Dockerのパーミッション地獄 😅
```
開発者「Docker Composeで起動したのに動かない...」
↓
先輩「Podman使ってる?」
↓
開発者「はい、Fedoraなので...」
↓
先輩「あー、ルートレスモードのパーミッション問題だ」
↓
開発者「ルートレス...?」
↓
先輩「Dockerは root権限で動くけど、Podmanは一般ユーザーで動くから、
     ファイルのパーミッションで引っかかることがあるんだよ」
↓
開発者「そんな違いが...」
```

### DockerとPodmanの違い(雑学)
```
Docker:
  - Daemon(root権限)で動作
  - /var/run/docker.sock を使用
  - セキュリティ的にやや心配

Podman:
  - Daemonless(rootless)
  - 一般ユーザー権限で動作
  - よりセキュア
  - でもパーミッションに厳しい ← 今回のトラブル

Fedora/RHELがPodmanを採用した理由:

  • Red HatがDockerから独立したかった(政治的理由)
  • セキュリティ重視(rootless)
  • Kubernetes互換性

トラブルシューティング

確認1: PostgreSQLが実際に起動しているか

bash
# コンテナのステータス確認
docker ps -a

# 期待される出力:
# STATUS が "Up" になっている

# PostgreSQLプロセス確認
docker exec blog-postgres-dev ps aux | grep postgres

確認2: ポート5432が開いているか

bash
# ホスト側から接続テスト
nc -zv localhost 5432

# または
telnet localhost 5432

# 成功すれば: "Connection succeeded"

確認3: データベースに直接接続

bash
# psqlで接続テスト
docker exec -it blog-postgres-dev psql -U blog_dev_user -d blog_dev

# 成功すれば psqlプロンプトが表示される:
# blog_dev=>

# 接続できたら以下を実行:
\l  # データベース一覧
\q  # 終了

最終的な解決手順(コピペ用)

bash
# 完全リセット
cd ~/springboot-gradle-blog-main
docker-compose down -v

# docker-compose.ymlを修正
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  postgres:
    image: postgres:15.3-alpine
    container_name: blog-postgres-dev
    environment:
      POSTGRES_USER: blog_dev_user
      POSTGRES_DB: blog_dev
      POSTGRES_PASSWORD: dev_password_123
    ports:
      - "5432:5432"
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blog_dev_user"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - blog-dev-network

  pgadmin:
    image: dpage/pgadmin4
    container_name: blog-pgadmin-dev
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@blog.local
      PGADMIN_DEFAULT_PASSWORD: admin123
    ports:
      - "5050:80"
    depends_on:
      - postgres
    networks:
      - blog-dev-network

volumes:
  postgres_dev_data:
    driver: local

networks:
  blog-dev-network:
    driver: bridge
EOF

# コンテナ起動
docker-compose up -d

# 20秒待つ(PostgreSQL起動に時間がかかる)
echo "PostgreSQL起動待機中..."
sleep 20

# ログ確認
docker logs blog-postgres-dev

# 接続テスト
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d blog_dev -c "SELECT 'Connection successful!' as status;"

# Spring Boot起動
./gradlew bootRun --args='--spring.profiles.active=dev'

もし起動に時間がかかる場合

PostgreSQLの初回起動は時間がかかります:

bash
# リアルタイムでログを監視
docker logs -f blog-postgres-dev

# 以下が表示されるまで待つ:
# "database system is ready to accept connections"

# 表示されたら Ctrl+C でログ監視を終了

この手順で解決するはずです!結果を教えてください 🚀

hiroppy123@fedora:~/springboot-gradle-blog-main$ docker-compose up -d Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. >>>> Executing external compose provider "/usr/libexec/docker/cli-plugins/docker-compose". Please see podman-compose(1) for how to disable this message

pasted

データベースがないという事ですか?     どうすれば良いですか?

12月12日

いえ、データベースは正常に作成されています! 🎉

エラーメッセージを見ると:

FATAL: database "blog_dev_user" does not exist

これはヘルスチェックが間違ったデータベース名で接続を試みているだけです。

実際の接続テストは成功しています:

SELECT version();  ← 成功!
PostgreSQL 15.3 ...

問題:ヘルスチェックの設定ミス

docker-compose.ymlのヘルスチェックが、ユーザー名をデータベース名として使おうとしています。

解決方法:docker-compose.ymlを修正

bash
cd ~/springboot-gradle-blog-main

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  postgres:
    image: postgres:15.3-alpine
    container_name: blog-postgres-dev
    environment:
      POSTGRES_USER: blog_dev_user
      POSTGRES_DB: blog_dev
      POSTGRES_PASSWORD: dev_password_123
    ports:
      - "5432:5432"
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blog_dev_user -d blog_dev"]
      #                                                 ^^^^^^^^^^^^
      #                                    データベース名を追加!
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - blog-dev-network

  pgadmin:
    image: dpage/pgadmin4
    container_name: blog-pgadmin-dev
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@blog.local
      PGADMIN_DEFAULT_PASSWORD: admin123
    ports:
      - "5050:80"
    depends_on:
      - postgres
    networks:
      - blog-dev-network

volumes:
  postgres_dev_data:
    driver: local

networks:
  blog-dev-network:
    driver: bridge
EOF

でも実は、このエラーは無視しても問題ありません。PostgreSQLは正常に動作しています。

Spring Bootアプリを起動してみましょう

bash
cd ~/springboot-gradle-blog-main

# そのまま起動
./gradlew bootRun --args='--spring.profiles.active=dev'

今度は成功するはずです! 🚀

もし完璧にしたい場合(オプション)

bash
# コンテナを再起動(ヘルスチェックのエラーを消すため)
docker-compose down
docker-compose up -d

# 少し待つ
sleep 10

# Spring Boot起動
./gradlew bootRun --args='--spring.profiles.active=dev'
```

## ログの解説(業界トーク)
```
✅ database system is ready to accept connections
   → PostgreSQL本体は正常起動

❌ FATAL: database "blog_dev_user" does not exist
   → ヘルスチェックが間違った接続を試みている
   → でもこれは「ヘルスチェックのバグ」であって
     PostgreSQL自体は動いている

✅ SELECT version(); が成功
   → 実際の接続は問題なし
```

### 業界あるある:ログの読み方
```
新人「FATALエラーが出てます!大変です!」
↓
先輩「どこで出てる?」
↓
新人「ヘルスチェックです...」
↓
先輩「実際の接続テストは?」
↓
新人「成功してます...」
↓
先輩「じゃあ動くよ。ヘルスチェックのミスだから」
↓
新人「えっ、FATALなのに...?」
↓
先輩「ログレベルは開発者が決めるから、
     本当に致命的かどうかは文脈で判断するんだよ」

ログレベルの真実:

  • FATAL = 開発者が「致命的」と思ったもの
  • 実際には無視できることも多い
  • 重要なのは「アプリが動くかどうか」

確認:Spring Bootが正常に起動するか

bash
./gradlew bootRun --args='--spring.profiles.active=dev'
```

以下のログが出れば**大成功**:
```
Tomcat started on port 8080 (http)
Started BlogApplication in X.XXX seconds
```

その後、ブラウザで以下にアクセス:
```
http://localhost:8080

トラブルシューティング(念のため)

もし起動に失敗したら:

bash
# PostgreSQL接続を手動確認
docker exec -it blog-postgres-dev psql -U blog_dev_user -d blog_dev

# psqlプロンプトで:
\l        # データベース一覧
\dt       # テーブル一覧(まだ空)
\q        # 終了

まとめ

現状:

  • ✅ Java 21.0.9 インストール済み
  • ✅ Gradle 9.2.1 動作中
  • ✅ PostgreSQL 15.3 起動中
  • ✅ データベース blog_dev 作成済み
  • ✅ ユーザー blog_dev_user 作成済み
  • ⚠️ ヘルスチェックにバグ(でも無害)

次のステップ:

bash
./gradlew bootRun --args='--spring.profiles.active=dev'

これで起動するはずです!結果を教えてください 🎉

./gradlew bootRun --args='--spring.profiles.active=dev' > Task :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____|

pasted

これは、マイグレーションに失敗しているのですか?   どうしたら良いですか?

12月12日

はい!マイグレーションに失敗しています。でも原因は明確です!

問題の診断

sql
ERROR: syntax error at or near "AUTO_INCREMENT"
```

**原因:** SQLの構文が**MySQL用**になっています。
PostgreSQLでは`AUTO_INCREMENT`ではなく`SERIAL`
または`GENERATED ALWAYS AS IDENTITY`を使います。

## データベース間の方言の違い(業界トーク)
```
MySQL:        AUTO_INCREMENT  ← よく使われる
PostgreSQL:   SERIAL または GENERATED ALWAYS AS IDENTITY
Oracle:       SEQUENCE + TRIGGER
SQL Server:   IDENTITY
```

**これ、データベースあるあるトップ3に入ります!** 😅
```
開発者「MySQLで動いたコードをPostgreSQLに移したら動かない...」
↓
先輩「SQLの方言が違うんだよ」
↓
開発者「SQLって標準じゃないんですか?」
↓
先輩「理論上は標準があるけど、実際は各DBが独自拡張しまくってる」
↓
開発者「えっ...」
↓
先輩「だからORMが流行ったんだよ(遠い目)」

解決方法:Flywayマイグレーションファイルを修正

ステップ1: マイグレーションファイルの場所を確認

bash
cd ~/springboot-gradle-blog-main
ls -la src/main/resources/db/migration/

ステップ2: すべてのマイグレーションファイルを修正

以下のコマンドで一括修正できます:

bash
cd ~/springboot-gradle-blog-main

# V1__Create_users_table.sql を修正
cat > src/main/resources/db/migration/V1__Create_users_table.sql << 'EOF'
-- Flywayマイグレーションファイル: PostgreSQL用
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    enabled BOOLEAN DEFAULT TRUE,
    account_non_locked BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
EOF

MySQL vs PostgreSQL 構文対応表

機能 MySQL PostgreSQL
自動採番 BIGINT AUTO_INCREMENT BIGSERIAL または BIGINT GENERATED ALWAYS AS IDENTITY
現在時刻 NOW() CURRENT_TIMESTAMP または NOW()
真偽値 TINYINT(1) または BOOLEAN BOOLEAN
文字列連結 CONCAT() || または CONCAT()
LIMIT LIMIT 10 LIMIT 10 (同じ)
バッククォート `column` "column"

ステップ3: 他のマイグレーションファイルも確認

bash
# すべてのマイグレーションファイルを表示
find src/main/resources/db/migration/ -name "*.sql"
 -exec echo "=== {} ===" \; -exec cat {} \;

もし他にもAUTO_INCREMENTが含まれているファイルがあれば教えてください。一緒に修正しましょう。

ステップ4: データベースをリセット

Flywayはマイグレーションに失敗すると、中途半端な状態になることがあります。クリーンな状態から再スタートします:

bash
# PostgreSQLのデータベースを削除して再作成
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "DROP DATABASE IF EXISTS blog_dev;"

docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "CREATE DATABASE blog_dev;"

# または、コンテナを完全に再作成
docker-compose down -v
docker-compose up -d
sleep 10

ステップ5: アプリケーションを再起動

bash
./gradlew clean bootRun --args='--spring.profiles.active=dev'

完全な修正スクリプト(コピペ用)

以下をまとめて実行してください:

bash
cd ~/springboot-gradle-blog-main

# マイグレーションファイルをPostgreSQL用に修正
cat > src/main/resources/db/migration/V1__Create_users_table.sql << 'EOF'
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    enabled BOOLEAN DEFAULT TRUE,
    account_non_locked BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
EOF

# データベースをクリーンアップ
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "DROP DATABASE IF EXISTS blog_dev;"

docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "CREATE DATABASE blog_dev;"

# アプリケーションをクリーンビルド&起動
./gradlew clean bootRun --args='--spring.profiles.active=dev'

他のマイグレーションファイルも修正が必要かも

もし複数のマイグレーションファイルがある場合、以下のパターンで修正してください:

テーブル作成の基本パターン

sql
-- MySQL版(NG)
CREATE TABLE posts (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT,
    user_id BIGINT,
    created_at DATETIME DEFAULT NOW()
);

-- PostgreSQL版(OK)
CREATE TABLE posts (
    id BIGSERIAL PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT,
    user_id BIGINT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
```

## 業界の知恵:マイグレーションのベストプラクティス

### 1. データベース方言を意識する
```
開発環境: H2 / SQLite(軽量)
↓
本番環境: PostgreSQL / MySQL
↓
問題: 方言が違って動かない 😱
```

**推奨:**
- 開発環境でも本番と同じDBを使う(今回のようにDocker使用)
- ORMの抽象化に頼りすぎない
- Raw SQLを書く場合は必ずDB方言を確認

### 2. Flywayのバージョン管理
```
V1__Initial_schema.sql       ← 最初
V2__Add_posts_table.sql      ← 追加
V3__Add_comments_table.sql   ← さらに追加
```

**ルール:**
- ファイル名は変更厳禁
- 一度適用したマイグレーションは変更厳禁
- 修正したい場合は新しいマイグレーションを追加

### 3. ロールバック戦略

Flywayは基本的に**ロールバック非対応**(有料版のみ対応)
```
失敗したら:
1. データベースを削除して再作成
2. マイグレーションファイルを修正
3. 再実行

本番環境では:
- テスト環境で十分確認
- バックアップ必須

トラブルシューティング

問題1: 他のマイグレーションファイルにもエラーがある

bash
# すべてのマイグレーションファイルでAUTO_INCREMENTを検索
grep -r "AUTO_INCREMENT" src/main/resources/db/migration/

# 見つかったら、すべて BIGSERIAL に置換
find src/main/resources/db/migration/ -name "*.sql"
 -exec sed -i 's/BIGINT AUTO_INCREMENT/BIGSERIAL/g' {} \;

問題2: Flywayのメタデータが残っている

bash
# Flywayのメタデータテーブルを削除
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d blog_dev -c "DROP TABLE IF EXISTS flyway_schema_history;"

問題3: 完全リセットしたい

bash
# すべてのコンテナとボリュームを削除
docker-compose down -v

# 再作成
docker-compose up -d
sleep 10

# アプリ起動
./gradlew clean bootRun --args='--spring.profiles.active=dev'

まとめ

現状:

  • ✅ Java 21.0.9 動作中
  • ✅ PostgreSQL 15.3 動作中
  • ✅ データベース接続成功
  • ❌ マイグレーションファイルがMySQL用の構文

修正内容:

sql
MySQL:      BIGINT AUTO_INCREMENT
            ↓
PostgreSQL: BIGSERIAL

次のアクション: 上記の修正スクリプトを実行して、再度起動してください!

うまくいかない場合は、以下を教えてください:

bash
ls -la src/main/resources/db/migration/
cat src/main/resources/db/migration/V1__Create_users_table.sql

一緒に解決しましょう!🚀

./gradlew bootRun --args='--spring.profiles.active=dev' > Task :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____|

pasted

これはユーザーロールが二重に作られようとしているのですか?    どうしたら良いですか?

12月12日

はい、その通りです!V4とV6でテーブルが重複して作成されようとしています

問題の診断

ログを見ると:

✅ V1 - Create users table (成功)
✅ V2 - Create roles table (成功)
✅ V3 - Create posts table (成功)
✅ V4 - Consolidated migration (成功) ← ここでuser_rolesを作成済み
✅ V5 - Insert sample data (成功)
❌ V6 - Create user roles table (失敗) ← すでに存在するため失敗

V4でuser_rolesテーブルを作成しているのに、V6でも作ろうとしている

業界あるある:マイグレーションの重複問題 😅

初期開発:
V1: users作成
V2: roles作成
V3: posts作成
↓
後から整理:
V4: 「まとめて作り直そう!」← user_rolesも含む
↓
さらに後:
V6: 「あれ?user_rolesまだ作ってなかった?」← 忘れてた
↓
結果: 重複で失敗 💥

これ、チーム開発あるあるトップ3!

解決方法:重複マイグレーションを修正

方法1: V6を削除(推奨)

V4ですでに作成されているので、V6は不要です。

bash
cd ~/springboot-gradle-blog-main

# V6マイグレーションファイルを削除
rm src/main/resources/db/migration/V6__Create_user_roles_table.sql

# データベースをクリーンアップ
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "DROP DATABASE IF EXISTS blog_dev;"

docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d postgres -c "CREATE DATABASE blog_dev;"

# 再起動
./gradlew clean bootRun --args='--spring.profiles.active=dev'

方法2: V6を修正(IF NOT EXISTSを使用)

もしV6を残したい場合:

bash
cat > src/main/resources/db/migration/V6__Create_user_roles_table.sql << 'EOF'
-- user_rolesテーブルが存在しない場合のみ作成
CREATE TABLE IF NOT EXISTS user_roles (
    user_id BIGINT,
    role_id BIGINT,
    PRIMARY KEY (user_id, role_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
);

-- インデックスも存在チェック
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_user_roles_user') THEN
        CREATE INDEX idx_user_roles_user ON user_roles(user_id);
    END IF;
    
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_user_roles_role') THEN
        CREATE INDEX idx_user_roles_role ON user_roles(role_id);
    END IF;
END
$$;
EOF

方法3: V4の内容を確認して整理(ベストプラクティス)

bash
# V4の内容を確認
cat src/main/resources/db/migration/V4__Consolidated_migration.sql

# もしV4に全て含まれているなら、V6を削除
rm src/main/resources/db/migration/V6__Create_user_roles_table.sql

すべてのマイグレーションファイルを確認

bash
cd ~/springboot-gradle-blog-main

# すべてのマイグレーションファイルを一覧表示
ls -la src/main/resources/db/migration/

# 内容を確認
for file in src/main/resources/db/migration/*.sql; do
    echo "========== $file =========="
    cat "$file"
    echo ""
done

推奨:完全にクリーンアップして再構築

マイグレーションファイルが混乱している場合の最善策:

bash
cd ~/springboot-gradle-blog-main

# ステップ1: すべてのマイグレーションファイルを確認
ls -la src/main/resources/db/migration/

# ステップ2: 重複しているV6を削除
rm src/main/resources/db/migration/V6__Create_user_roles_table.sql

# ステップ3: データベースを完全リセット
docker-compose down -v
docker-compose up -d
sleep 10

# ステップ4: クリーンビルド&起動
./gradlew clean bootRun --args='--spring.profiles.active=dev'
```

## Flywayのベストプラクティス(業界の知恵)

### マイグレーションファイルの命名規則
```
V1__Initial_schema.sql           ← 初期スキーマ
V2__Add_posts_table.sql          ← 追加テーブル
V3__Add_comments_column.sql      ← カラム追加
V4__Create_indexes.sql           ← インデックス作成

❌ 避けるべき:
V4__Consolidated_migration.sql   ← 「まとめ直し」は混乱の元
V10__Fix_previous_migration.sql  ← 過去のマイグレーションは修正不可
```

### 統合マイグレーション (Consolidated) の問題点
```
初期開発時:
V1: users
V2: roles
V3: user_roles
↓
後で「整理したい」と思って:
V4: Consolidated (users, roles, user_rolesを全部再作成)
↓
問題:
- V1-V3がすでに実行済み
- V4で同じテーブルを作ろうとして衝突
- さらにV6でまた重複...
```

**正しいアプローチ:**
```
V1: users
V2: roles  
V3: user_roles
V4: Add_posts_table          ← 新しい機能を追加
V5: Add_comments_table       ← さらに追加
V6: Add_indexes_to_users     ← 既存テーブルの改善

トラブルシューティング

問題1: V4の内容が分からない

bash
# V4を表示
cat src/main/resources/db/migration/V4__Consolidated_migration.sql

もしuser_rolesが含まれていたら、V6は削除してください。

問題2: マイグレーション履歴を確認したい

bash
# Flywayの履歴テーブルを確認
docker exec -it blog-postgres-dev psql -U blog_dev_user
 -d blog_dev -c "SELECT * FROM flyway_schema_history ORDER BY installed_rank;"

問題3: 特定のマイグレーションだけやり直したい

Flywayの制限: 一度実行したマイグレーションは変更・削除できません。

解決策:

  1. データベースを完全削除して再作成
  2. または新しいマイグレーション(V7)で修正

完全解決スクリプト(コピペ用)

bash
cd ~/springboot-gradle-blog-main

# V6を削除(V4で既に作成済みのため)
rm -f src/main/resources/db/migration/V6__Create_user_roles_table.sql

# データベースを完全リセット
echo "データベースをリセット中..."
docker-compose down -v
docker-compose up -d

# PostgreSQL起動を待つ
echo "PostgreSQL起動待機中..."
sleep 15

# 起動確認
docker logs blog-postgres-dev | tail -n 5

# アプリケーション起動
echo "Spring Boot起動中..."
./gradlew clean bootRun --args='--spring.profiles.active=dev'
```

## 成功の確認

起動が成功すると、以下のログが表示されます:
```
Tomcat started on port 8080 (http)
Started BlogApplication in X.XXX seconds (process running for X.XXX)
```

その後、ブラウザで確認:
```
http://localhost:8080

まとめ

原因: V4とV6でuser_rolesテーブルが重複

解決策:

  1. V6を削除(推奨)
  2. データベースをリセット
  3. 再起動

業界の教訓:

  • マイグレーションは「前進のみ」
  • 過去のマイグレーションを変更したくなったら、新しいマイグレーションで修正
  • "Consolidated"マイグレーションは避ける

上記のスクリプトを実行して、結果を教えてください!🚀

0 件のコメント: