2025年12月13日土曜日

リポジトリを安全に動かすための修正点

READMEに記載されている問題点と、Spring Bootアプリケーションの一般的なセキュリティ課題を踏まえて、このリポジトリを安全に動かすための修正点をまとめます。

このリポジトリを安全に動かすための修正点

READMEに詳細なアーキテクチャの問題点が記載されていますが、実際に安全に動作させるための最優先の修正事項は以下の通りです。

🔴 最優先(Critical)- すぐに修正が必要

1. H2データベースの本番環境での使用停止

  • リポジトリにh2-2.2.224.jarh2-2.3.232.jar、さらにtest.mv.dbなどのデータベースファイルが直接コミットされています
  • 問題: H2はインメモリ/開発用DBであり、本番環境には不適切
  • 修正:
properties
  # application-prod.properties を作成し、本番用DBに変更
  spring.datasource.url=jdbc:postgresql://localhost:5432/blogdb
  spring.datasource.username=${DB_USERNAME}
  spring.datasource.password=${DB_PASSWORD}

2. データベースファイルとJARファイルをGit管理から除外

  • .gitignoreに以下を追加:
gitignore
  *.mv.db
  *.trace.db
  h2-*.jar
  /test.mv.db
  /~.mv.db

3. 機密情報のハードコーディング防止

  • InsertUserData.javaInsertRoleData.javaなどに直接書かれているであろう初期パスワードやデータを確認
  • 修正: 環境変数または外部設定ファイルを使用
java
  // 悪い例(直接記述)
  String password = "admin123";
  
  // 良い例(環境変数から取得)
  String password = System.getenv("ADMIN_PASSWORD");

4. Spring Securityの設定強化

以下の設定が必要です:

java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // CSRF保護を有効化(デフォルトだが明示的に)
            .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
            
            // セキュアなヘッダー設定
            .headers(headers -> headers
                .contentSecurityPolicy("default-src 'self'")
                .frameOptions().deny()
                .xssProtection()
                .and()
                .contentTypeOptions()
            )
            
            // HTTPSの強制(本番環境)
            .requiresChannel(channel -> channel
                .anyRequest().requiresSecure()
            )
            
            // セッション管理
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .maximumSessions(1)
                .expiredUrl("/login?expired")
            );
        
        return http.build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        // BCryptを使用(平文保存は絶対NG)
        return new BCryptPasswordEncoder(12);
    }
}

🟡 重要(High)- 早めの修正が推奨

5. H2 Consoleの無効化

  • 開発環境でのみ有効にする:
properties
  # application-dev.properties
  spring.h2.console.enabled=true
  spring.h2.console.settings.web-allow-others=false
  
  # application-prod.properties
  spring.h2.console.enabled=false

6. SQLインジェクション対策

  • JDBCを直接使用している場合、PreparedStatementを必ず使用
  • Spring Data JPAを使用している場合も、ネイティブクエリには注意
java
// 悪い例 String query = "SELECT * FROM users WHERE username = '" + username + "'"; 

// 良い例 String query = "SELECT * FROM users WHERE username = ?"; PreparedStatement stmt = connection.prepareStatement(query); stmt.setString(1, username);

7. 入力バリデーションの追加

java
public class PostDto {
    @NotBlank(message = "タイトルは必須です")
    @Size(max = 100, message = "タイトルは100文字以内です")
    private String title;
    
    @NotBlank(message = "内容は必須です")
    @Size(max = 5000, message = "内容は5000文字以内です")
    private String content;
    
    // XSS対策(HTMLエスケープ)
    @SafeHtml
    private String description;
}

🟢 推奨(Medium)- 時間があれば修正

8. ロギング設定の追加

properties
# application.properties
logging.level.org.springframework.security=DEBUG
logging.level.com.yourpackage=INFO
logging.file.name=logs/application.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} - %msg%n

9. レート制限の実装

java
@Configuration
public class RateLimitConfig {
    @Bean
    public RateLimiter rateLimiter() {
        return RateLimiter.create(10.0); // 秒間10リクエスト
    }
}

10. エラーメッセージの適切な処理

java
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        // スタックトレースを公開しない
        log.error("Error occurred", e);
        return ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("エラーが発生しました");
    }
}

📋 チェックリスト

安全に動かすための最低限のチェックリスト:

  • .gitignoreにDBファイルとJARファイルを追加
  • 機密情報(パスワード、APIキーなど)を環境変数化
  • パスワードをBCryptでハッシュ化
  • CSRF保護が有効になっているか確認
  • 本番環境ではH2を使用しない
  • H2 Consoleを本番環境で無効化
  • HTTPSを本番環境で強制
  • SQLインジェクション対策の確認
  • XSS対策の確認
  • 適切なエラーハンドリング

これらの修正を行うことで、基本的なセキュリティレベルを確保できます。特に1〜4の最優先事項は必ず対応してください。

CustomUserDetailsService.java

32行

java

CustomUserDetailsServiceTest.java

60行

java

これらは、どの様に修正して、正常に動く様に出来ますか?

12月11日

提供されたコードを分析したところ、いくつかの問題点が見つかりました。以下、修正版のコードと説明を提示します。

🔍 主な問題点

  1. Userクラスのコンストラクタ不一致 - テストでは4引数コンストラクタを使用していますが、実際のUserエンティティの定義が不明
  2. CustomUserDetailsクラスの実装が不明 - このクラスの実装が提供されていません
  3. パッケージ構造 - すべてがcom.example.blogに配置されており、適切なレイヤー分けが必要

修正版コード

User.java (エンティティクラス)
コード
package com.example.blog.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Entity @Table(name = "users") @Data @NoArgsCo
application.properties (設定ファイル)
コード
# アプリケーション基本設定 spring.application.name=blog server.port=8080 # データベース設定(H2 - 開発環境) spring.datasource.url=jdbc:h2:file:./data/blogdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= # JPA設定 sp

📝 修正内容の詳細説明

1. パッケージ構造の整理

com.example.blog/
├── entity/         # エンティティクラス
│   └── User.java
├── repository/     # データアクセス層
│   └── UserRepository.java
├── security/       # セキュリティ関連
│   └── CustomUserDetails.java
└── service/        # ビジネスロジック
    └── CustomUserDetailsService.java

2. 主な修正ポイント

User.java(エンティティ)

  • JPAアノテーションを追加(@Entity, @Table, @Idなど)
  • Lombokを使用してボイラープレートコード削減
  • enabledaccountNonLockedフィールドを追加
  • テスト用の4引数コンストラクタを追加

CustomUserDetails.java(新規作成)

  • UserDetailsインターフェースを完全実装
  • ロールをGrantedAuthorityに変換
  • アカウントロックや有効/無効の状態を反映

UserRepository.java

  • Spring Data JPAを使用した標準的な実装
  • 必要なクエリメソッドを定義

CustomUserDetailsService.java(修正版)

  • ロギング機能を追加(SLF4J)
  • アカウント無効化・ロックのチェックを追加
  • トランザクション管理(@Transactional
  • メールアドレスでの検索メソッドを追加
  • より詳細なエラーメッセージ

CustomUserDetailsServiceTest.java(修正版)

  • @ExtendWith(MockitoExtension.class)を使用(最新のJUnit 5方式)
  • @InjectMocksで依存性注入を自動化
  • テストケースを大幅に拡充:
    • 正常系: ユーザー検索、管理者ロール
    • 異常系: ユーザー不在、無効化アカウント、ロック
    • 境界値: null、空文字列
    • メールアドレスでの検索
  • @DisplayNameで日本語のテスト名

3. セキュリティ強化

java
// パスワードのハッシュ化
String encodedPassword = passwordEncoder.encode(rawPassword);

// アカウント状態のチェック
if (!user.isEnabled()) {
    throw new UsernameNotFoundException("アカウントが無効化されています");
}

// ロギングで監査証跡を残す
logger.warn("無効化されたアカウントへのログイン試行: {}", username);

4. テストの実行方法

bash
# 全テストの実行
./gradlew test

# 特定のテストクラスのみ実行
./gradlew test --tests CustomUserDetailsServiceTest

# テストレポートの確認
# build/reports/tests/test/index.html を開く

5. 動作確認手順

  1. データベースの準備
sql
-- Flywayマイグレーションファイル: 
src/main/resources/db/migration/V1__create_users_table.sql

CREATE TABLE users (
    id BIGINT AUTO_INCREMENT 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
);

CREATE TABLE user_roles (
    user_id BIGINT NOT NULL,
    role VARCHAR(50) NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
  1. 初期データの投入
java
// DataLoader.java(アプリケーション起動時に実行)
@Component
public class DataLoader implements CommandLineRunner {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    public void run(String... args) {
        if (userRepository.count() == 0) {
            User admin = new User(
                "admin",
                "admin@example.com",
                passwordEncoder.encode("admin123"),
                List.of("ROLE_ADMIN", "ROLE_USER")
            );
            userRepository.save(admin);
        }
    }
}
  1. アプリケーションの起動
bash
./gradlew bootRun
  1. 動作確認
  • ブラウザで http://localhost:8080 にアクセス
  • H2コンソール: http://localhost:8080/h2-console
  • ログイン: admin / admin123

これで正常に動作するはずです!何か問題があれば教えてください。

hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew test ERROR: JAVA_HOME is set to an invalid directory: /usr/lib/jvm/temurin-17-jdk Please set the JAVA_HOME variable in your environment to match the location of your Java installation. hiroppy123@fedora:~/springboot-gradle-blog-main$        ーーーーー     これはどうしたら良いですか?

12月11日

JAVA_HOMEの設定が正しくないようです。Fedoraシステムで適切なJavaのパスを確認して設定しましょう。

🔧 解決手順

1. インストールされているJavaを確認

bash
# インストールされているJavaのバージョンを確認
java -version

# Javaのインストール場所を確認
which java

# 利用可能なJavaのリストを表示
sudo alternatives --config java

2. 正しいJAVA_HOMEを見つける

bash
# Javaの実際のパスを確認
readlink -f $(which java)

# 通常、Fedoraでは以下のいずれかにインストールされています
ls -la /usr/lib/jvm/

# 出力例:
# java-17-openjdk-17.0.x.x-x.fc38.x86_64/
# java-21-openjdk-21.0.x.x-x.fc38.x86_64/

3. JAVA_HOMEを設定する

方法A: 一時的に設定(現在のセッションのみ)

bash
# Java 17の場合(最も一般的)
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk

# または具体的なバージョンを指定
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-17.0.9.0.9-2.fc38.x86_64

# PATHにも追加
export PATH=$JAVA_HOME/bin:$PATH

# 確認
echo $JAVA_HOME
$JAVA_HOME/bin/java -version

# テストを実行
./gradlew test

方法B: 永続的に設定(推奨)

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

# または
vim ~/.bashrc

以下をファイルの最後に追加:

bash
# Java環境変数設定
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export PATH=$JAVA_HOME/bin:$PATH

保存して反映:

bash
# 設定を反映
source ~/.bashrc

# 確認
echo $JAVA_HOME
java -version

4. Java 17がインストールされていない場合

bash
# Java 17をインストール
sudo dnf install java-17-openjdk-devel

# インストール確認
java -version

# JAVA_HOMEを設定
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk

5. 正しいJAVA_HOMEのパターン

Fedoraでの典型的なパスは以下のいずれか:

bash
# パターン1(シンボリックリンク - 推奨)
/usr/lib/jvm/java-17-openjdk

# パターン2(完全なバージョン指定)
/usr/lib/jvm/java-17-openjdk-17.0.9.0.9-2.fc38.x86_64

# パターン3(Java 21の場合)
/usr/lib/jvm/java-21-openjdk

6. トラブルシューティング用スクリプト

以下のスクリプトを実行して、正しいJAVA_HOMEを自動検出できます:

bash
# スクリプトを作成
cat > find_java_home.sh << 'EOF'
#!/bin/bash

echo "=== Java環境診断 ==="
echo ""

echo "1. 現在のJAVA_HOME:"
echo "   $JAVA_HOME"
echo ""

echo "2. javaコマンドの場所:"
which java
echo ""

echo "3. javaのバージョン:"
java -version 2>&1
echo ""

echo "4. 実際のjavaバイナリの場所:"
readlink -f $(which java)
echo ""

echo "5. /usr/lib/jvm/の内容:"
ls -la /usr/lib/jvm/
echo ""

echo "6. 推奨されるJAVA_HOME:"
if [ -d "/usr/lib/jvm/java-17-openjdk" ]; then
    echo "   export JAVA_HOME=/usr/lib/jvm/java-17-openjdk"
elif [ -d "/usr/lib/jvm/java-21-openjdk" ]; then
    echo "   export JAVA_HOME=/usr/lib/jvm/java-21-openjdk"
else
    echo "   $(ls -d /usr/lib/jvm/java-*-openjdk* 2>/dev/null | head -1)"
fi
EOF

# 実行権限を付与
chmod +x find_java_home.sh

# 実行
./find_java_home.sh

7. 最も簡単な解決方法(おすすめ)

bash
# 1. まずJava 17が入っているか確認 
ls /usr/lib/jvm/ | grep java-17 

# 2. 以下のコマンドを実行(一発設定) 
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java)))) 

# 3. 確認 
echo $JAVA_HOME 

# 4. テスト実行 
./gradlew test 

# 5. 問題なければ永続化 
echo "export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))" >> ~/.bashrc source ~/.bashrc

8. それでもダメな場合

Gradleが独自のJavaを使用するように設定:

bash
# gradle.propertiesを編集
nano gradle.properties

以下を追加:

properties
org.gradle.java.home=/usr/lib/jvm/java-17-openjdk

または、直接Javaを指定してGradleを実行:

bash
/usr/lib/jvm/java-17-openjdk/bin/java -jar gradle/wrapper/gradle-wrapper.jar test

📋 チェックリスト

以下を順番に確認してください:

  1. java -version でJavaがインストールされているか確認
  2. /usr/lib/jvm/ 配下にJava 17があるか確認
  3. export JAVA_HOME=/usr/lib/jvm/java-17-openjdk を実行
  4. echo $JAVA_HOME で設定を確認
  5. $JAVA_HOME/bin/java -version でJavaが動作するか確認
  6. ./gradlew test を再実行
  7. ✅ 問題なければ ~/.bashrc に追記して永続化

これで解決するはずです!実行結果を教えてください。

hiroppy123@fedora:~$ docker run -d -p 5432:5432 \ -e POSTGRES_USER=loco \ -e POSTGRES_DB=loco_app \ -e POSTGRES_PASSWORD="loco" \ postgres:15.3-alpine Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. 2ddb012ed0ff0eb9c420ee8940db1bfd1e5c20bf45b40629f6cbb2df0b47cf1e hiroppy123@fedora:~$ docker run -d -p 5432:5432 -e POSTGRES_USER=testuser -e POSTGRES_DB=loco_app -e POSTGRES_PASSWORD="testpassword" postgres:15.3-alpine Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. Error: pasta failed with exit code 1: Failed to bind port 5432 (Address already in use) for option '-t 5432-5432:5432-5432' hiroppy123@fedora:~$ docker run -d -p 5432:5432 -e POSTGRES_USER=testuser -e POSTGRES_DB=testdb -e POSTGRES_PASSWORD="testpassword" postgres:15.3-alpine Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. Error: pasta failed with exit code 1: Failed to bind port 5432 (Address already in use) for option '-t 5432-5432:5432-5432' hiroppy123@fedora:~$       ーーーーー      これはどうしたら良いですか?      それと、今、Javaは21以上しかインストール出来ませんがこれについても解説してください。

12月11日

2つの問題について解説します。

🐘 PostgreSQLのポート競合問題

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

すでに1つ目のPostgreSQLコンテナが起動しているため、2つ目を同じポート5432で起動できません。

解決方法

方法A: 既存のコンテナを確認して使用する(推奨)

bash
# 実行中のコンテナを確認
docker ps

# 出力例:
# CONTAINER ID   IMAGE                    PORTS                    NAMES
# 2ddb012ed0ff   postgres:15.3-alpine     0.0.0.0:5432->5432/tcp   ...

# コンテナの詳細情報を確認
docker inspect 2ddb012ed0ff | grep -A 10 "Env"

# 既存のコンテナに接続してテスト
docker exec -it 2ddb012ed0ff psql -U loco -d loco_app

既存のコンテナが使えるなら、それを使用してください。

方法B: 既存コンテナを停止して新しいものを起動

bash
# 実行中のコンテナを確認
docker ps

# コンテナを停止
docker stop 2ddb012ed0ff

# コンテナを削除
docker rm 2ddb012ed0ff

# 新しいコンテナを起動(Spring Boot用の設定)
docker run -d -p 5432:5432 \
  --name springboot-postgres \
  -e POSTGRES_USER=bloguser \
  -e POSTGRES_DB=blogdb \
  -e POSTGRES_PASSWORD="blogpass123" \
  postgres:15.3-alpine

# 確認
docker ps

方法C: 異なるポートで複数のPostgreSQLを起動

bash
# 1つ目はそのまま(ポート5432)
# 既に起動中: loco用のPostgreSQL

# 2つ目を別ポートで起動(ポート5433でSpring Boot用)
docker run -d -p 5433:5432 \
  --name springboot-postgres \
  -e POSTGRES_USER=bloguser \
  -e POSTGRES_DB=blogdb \
  -e POSTGRES_PASSWORD="blogpass123" \
  postgres:15.3-alpine

# アプリケーションからは localhost:5433 で接続

方法D: Docker Composeを使用(最も推奨)

docker-compose.ymlを作成:

yaml
version: '3.8'

services:
  postgres:
    image: postgres:15.3-alpine
    container_name: springboot-postgres
    environment:
      POSTGRES_USER: bloguser
      POSTGRES_DB: blogdb
      POSTGRES_PASSWORD: blogpass123
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U bloguser"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:
bash
# 起動
docker-compose up -d

# 停止
docker-compose down

# ログ確認
docker-compose logs -f

Spring Boot用のapplication.properties設定

方法B(既存停止)または方法D(Docker Compose)の場合

properties
# PostgreSQL設定(ポート5432)
spring.datasource.url=jdbc:postgresql://localhost:5432/blogdb
spring.datasource.username=bloguser
spring.datasource.password=blogpass123
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=true

# H2 Consoleを無効化(PostgreSQL使用時)
spring.h2.console.enabled=false

方法C(ポート5433)の場合

properties
# PostgreSQL設定(ポート5433)
spring.datasource.url=jdbc:postgresql://localhost:5433/blogdb
spring.datasource.username=bloguser
spring.datasource.password=blogpass123
spring.datasource.driver-class-name=org.postgresql.Driver

build.gradleの依存関係

groovy
dependencies {
    // PostgreSQL JDBCドライバーを追加
    runtimeOnly 'org.postgresql:postgresql:42.7.1'
    
    // H2は開発用として残しておく(プロファイルで切り替え)
    runtimeOnly 'com.h2database:h2'
}

Java 21での動作について

Spring Boot 3.xはJava 17以上が必要ですが、Java 21でも動作します

Java 21で動作させる場合の修正点

build.gradle (Java 21対応版)
コード
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 21を指定 java { sourceCompatibility = '21' targetComp
Java環境設定スクリプト (setup_java.sh)
コード
#!/bin/bash echo "==========================================" echo "Java環境診断 & 設定スクリプト" echo "==========================================" echo "" # 色の定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 1. 現在のJava状態

Java 21を使用する場合の注意点

1. Java 21の確認

bash
# Java 21がインストールされているか確認
sudo dnf list installed | grep java-21

# インストールされていない場合
sudo dnf install java-21-openjdk-devel

# JAVA_HOMEを設定
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

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

2. Gradleの設定

gradle.propertiesを作成または編集:

properties
# Java 21を使用
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk

# Gradleのメモリ設定
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m

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

3. Java 21の新機能を活用する場合

Java 21では以下の機能が使えます:

java
// レコードパターン(Java 21で正式版)
public record User(String name, String email) {}

if (obj instanceof User(String name, String email)) {
    System.out.println("Name: " + name);
}

// Switch式のパターンマッチング
String result = switch (user) {
    case User(String name, _) when name.startsWith("admin") -> "管理者";
    case User(String name, _) -> "一般ユーザー: " + name;
    case null -> "ユーザーなし";
};

// Virtual Threads(仮想スレッド)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> {
        // 軽量スレッドで実行される処理
    });
}

📋 完全な実行手順

bash
# 1. Java環境診断スクリプトを作成
cat > setup_java.sh << 'EOF'
# (上記のスクリプト内容をコピー)
EOF

chmod +x setup_java.sh
./setup_java.sh

# 2. 既存のPostgreSQLコンテナを確認
docker ps

# 3. 既存コンテナを停止して削除(必要な場合)
docker stop $(docker ps -q)
docker rm $(docker ps -aq)

# 4. 新しいPostgreSQLを起動
docker run -d -p 5432:5432 \
  --name springboot-postgres \
  -e POSTGRES_USER=bloguser \
  -e POSTGRES_DB=blogdb \
  -e POSTGRES_PASSWORD="blogpass123" \
  postgres:15.3-alpine

# 5. 接続確認
docker exec -it springboot-postgres psql -U bloguser -d blogdb -c "SELECT version();"
# 6. JAVA_HOMEを設定 export JAVA_HOME=/usr/lib/jvm/java-21-openjdk export PATH=$JAVA_HOME/bin:$PATH
# 7. Gradleビルド cd ~/springboot-gradle-blog-main ./gradlew clean build
# 8. テスト実行 ./gradlew test
# 9. アプリケーション起動 ./gradlew bootRun

トラブルシューティング

Java 17をどうしても使いたい場合

bash
# SDKMANを使用してJava 17をインストール
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# Java 17をインストール
sdk install java 17.0.9-tem

# 使用するバージョンを切り替え
sdk use java 17.0.9-tem

# 確認
java -version

これで両方の問題が解決するはずです!実行結果を教えてください。

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. << WARN[0000] /home/hiroppy123/springboot-gradle-blog-main/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion unable to get image 'postgres:15.3-alpine': Cannot connect to the Docker daemon at unix:///run/user/1000/podman/podman.sock. Is the docker daemon running? Error: executing /usr/libexec/docker/cli-plugins/docker-compose up -d: exit status 1 hiroppy123@fedora:~/springboot-gradle-blog-main$         ーーーーー     これはどうしたら良いですか?

12月11日

PodmanのDockerソケットが起動していないようです。FedoraではPodmanを使用しているため、設定が必要です。

🔧 解決方法

方法A: Podmanソケットを有効化する(推奨)

bash
# Podmanソケットを起動
systemctl --user start podman.socket

# 自動起動を有効化
systemctl --user enable podman.socket

# 状態確認
systemctl --user status podman.socket

# ソケットの場所を確認
ls -la /run/user/$(id -u)/podman/podman.sock

その後、再度実行:

bash
docker-compose up -d

方法B: podman-composeを直接使用する(より簡単)

Dockerの互換レイヤーを使わず、Podman専用のコマンドを使用します。

bash
# podman-composeをインストール(まだの場合)
sudo dnf install podman-compose

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

# 確認
podman ps

方法C: docker-compose.ymlの修正

versionの警告も解消しましょう。

docker-compose.yml (修正版)
コード
# Docker Compose設定ファイル(Spring Boot Blog用) # versionフィールドは不要になりました(Compose V2以降) services: postgres: image: postgres:15.3-alpine container_name: springboot-postgres restart: unless-stopped environment: POSTGRES_USER: bloguser

方法D: Podmanで直接起動する(最も確実)

docker-composeを使わず、Podmanコマンドで直接起動します。

bash
# 既存のコンテナをクリーンアップ
podman stop -a
podman rm -a

# PostgreSQLコンテナを起動
podman run -d \
  --name springboot-postgres \
  -p 5432:5432 \
  -e POSTGRES_USER=bloguser \
  -e POSTGRES_DB=blogdb \
  -e POSTGRES_PASSWORD=blogpass123 \
  -v postgres_data:/var/lib/postgresql/data \
  --restart unless-stopped \
  postgres:15.3-alpine

# 起動確認
podman ps

# ログ確認
podman logs -f springboot-postgres

# ヘルスチェック(PostgreSQLが起動したか確認)
podman exec springboot-postgres pg_isready -U bloguser

完全な手順(おすすめ)

setup_postgresql.sh (PostgreSQL起動スクリプト)
コード
#!/bin/bash # PostgreSQL起動スクリプト(Podman対応) # Spring Boot Blog用 set -e # 色の定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}=========================================${NC}" echo -e

実行手順

bash
# 1. スクリプトを作成
cat > setup_postgresql.sh << 'EOF'
# (上記のスクリプト内容)
EOF

# 2. 実行権限を付与
chmod +x setup_postgresql.sh

# 3. スクリプトを実行
./setup_postgresql.sh

# 4. 確認
podman ps

# 5. 接続テスト
podman exec -it springboot-postgres psql -U bloguser -d blogdb

PostgreSQLコンソールに入ったら:

sql
-- データベース一覧
\l

-- テーブル一覧
\dt

-- 終了
\q

application.propertiesの設定

application.properties (PostgreSQL用)
コード
# Spring Boot Blog - PostgreSQL設定 # アプリケーション基本設定 spring.application.name=blog server.port=8080 # PostgreSQLデータベース設定 spring.datasource.url=jdbc:postgresql://localhost:5432/blogdb spring.datasource.username=bloguser spring.datasource.password=blogpas

トラブルシューティング

問題1: Podmanソケットエラーが続く場合

bash
# Podmanシステムサービスをリセット
systemctl --user daemon-reload
systemctl --user restart podman.socket

# 環境変数を設定
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock

# .bashrcに永続化
echo "export DOCKER_HOST=unix:///run/user/\$(id -u)/podman/podman.sock" >> ~/.bashrc
source ~/.bashrc

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

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

# または
sudo ss -tulpn | grep 5432

# PostgreSQLが既に起動している場合は停止
sudo systemctl stop postgresql

# Podmanコンテナを確認
podman ps -a | grep postgres

問題3: 権限エラーの場合

bash
# ユーザーをdockerグループに追加(Podmanの場合は不要だが念のため)
sudo usermod -aG docker $USER

# 再ログインするか、新しいセッションを開始
newgrp docker

# または完全にログアウト/ログイン

最終確認チェックリスト

bash
# ✅ 1. Podmanが動作しているか
podman --version

# ✅ 2. PostgreSQLコンテナが起動しているか
podman ps | grep springboot-postgres

# ✅ 3. PostgreSQLが接続可能か
podman exec -it springboot-postgres pg_isready -U bloguser

# ✅ 4. データベースにアクセスできるか
podman exec -it springboot-postgres psql -U bloguser -d blogdb -c "SELECT 1;"

# ✅ 5. ホストから接続できるか(psqlがインストールされている場合)
# psql -h localhost -p 5432 -U bloguser -d blogdb

これで問題が解決するはずです!実行結果を教えてください。

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. << WARN[0000] /home/hiroppy123/springboot-gradle-blog-main/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion [+] Running 3/3 ✔ Network springboot-gradle-blog-main_default Created 0.0s ✔ Volume springboot-gradle-blog-main_postgres_data Created 0.7s ✔ Container springboot-postgres Started 7.9s hiroppy123@fedora:~/springboot-gradle-blog-main$ ./setup_java.sh bash: ./setup_java.sh: 許可がありません hiroppy123@fedora:~/springboot-gradle-blog-main$ chmod -x setup_java.sh hiroppy123@fedora:~/springboot-gradle-blog-main$ ./setup_java.sh bash: ./setup_java.sh: 許可がありません hiroppy123@fedora:~/springboot-gradle-blog-main$       ーーーーー     これはどうしたら良いですか?

12月11日

PostgreSQLは起動成功しました!🎉

setup_java.shの実行権限の問題を解決しましょう。

🔧 実行権限の修正

bash
# -x ではなく +x で実行権限を付与
chmod +x setup_java.sh

# 確認
ls -la setup_java.sh

# 実行
./setup_java.sh

chmod -x は実行権限を削除してしまいます。chmod +x付与します。


📋 現在の状況確認と次のステップ

PostgreSQLは既に起動しているので、次はJavaの設定とアプリケーションの起動です。

1. PostgreSQLの動作確認

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

# PostgreSQLに接続してテスト
docker exec -it springboot-postgres psql -U bloguser -d blogdb

# PostgreSQL内で以下を実行
\l          # データベース一覧
\dt         # テーブル一覧(まだ空のはず)
SELECT version();  # バージョン確認
\q          # 終了

2. Java環境の設定

bash
# 実行権限を正しく付与
chmod +x setup_java.sh

# スクリプトを実行
./setup_java.sh

# または手動で設定
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

# 確認
echo $JAVA_HOME
java -version

3. Gradleの設定確認

gradle.properties ファイルを作成:

bash
cat > gradle.properties << 'EOF'
# Java 21を使用
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk

# Gradleの最適化設定
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.daemon=true
EOF

4. application.propertiesの作成

bash
# src/main/resources/application.properties を作成
mkdir -p src/main/resources

cat > src/main/resources/application.properties << 'EOF'
# Spring Boot Blog - PostgreSQL設定
spring.application.name=blog
server.port=8080

# PostgreSQL接続設定
spring.datasource.url=jdbc:postgresql://localhost:5432/blogdb
spring.datasource.username=bloguser
spring.datasource.password=blogpass123
spring.datasource.driver-class-name=org.postgresql.Driver

# JPA設定
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# H2 Consoleを無効化
spring.h2.console.enabled=false

# ログ設定
logging.level.root=INFO
logging.level.com.example.blog=DEBUG
logging.level.org.springframework.security=DEBUG
EOF

5. ビルドとテスト

bash
# クリーンビルド
./gradlew clean build

# テストのみ実行
./gradlew test

# テスト結果を確認
cat build/reports/tests/test/index.html

6. アプリケーションの起動

bash
# アプリケーションを起動
./gradlew bootRun

# または
./gradlew build
java -jar build/libs/*.jar

7. 動作確認

ブラウザまたはcurlで確認:

bash
# アプリケーションの起動確認
curl http://localhost:8080

# PostgreSQLの接続確認
docker exec -it springboot-postgres psql -U bloguser -d blogdb -c "\dt"

🚨 もし setup_java.sh が実行できない場合の代替方法

スクリプトを使わず、直接コマンドで設定:

bash
# 1. インストールされているJavaを確認
ls /usr/lib/jvm/

# 2. Java 21のパスを確認
ls -la /usr/lib/jvm/java-21-openjdk*

# 3. JAVA_HOMEを設定
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

# 4. 確認
java -version
echo $JAVA_HOME

# 5. .bashrcに永続化
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

# 6. 確認
java -version

📝 完全な手順(まとめ)

bash
# ========================================
# 1. PostgreSQL起動確認
# ========================================
docker ps | grep springboot-postgres

# ========================================
# 2. Java環境設定
# ========================================
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
java -version

# ========================================
# 3. Gradle設定ファイル作成
# ========================================
cat > gradle.properties << 'EOF'
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
org.gradle.jvmargs=-Xmx2g
EOF

# ========================================
# 4. application.properties確認・作成
# ========================================
cat > src/main/resources/application.properties << 'EOF'
spring.datasource.url=jdbc:postgresql://localhost:5432/blogdb
spring.datasource.username=bloguser
spring.datasource.password=blogpass123
spring.jpa.hibernate.ddl-auto=update
EOF

# ========================================
# 5. ビルド
# ========================================
./gradlew clean build

# ========================================
# 6. テスト実行
# ========================================
./gradlew test

# ========================================
# 7. アプリケーション起動
# ========================================
./gradlew bootRun

⚠️ よくあるエラーと対処法

エラー1: "JAVA_HOME is not set"

bash
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk

エラー2: "Could not connect to database"

bash
# PostgreSQLが起動しているか確認
docker ps | grep springboot-postgres

# 起動していなければ
docker start springboot-postgres

エラー3: "Permission denied"

bash
# 実行権限を付与(+x を使う)
chmod +x setup_java.sh
chmod +x gradlew

エラー4: ポート8080が使用中

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

# application.propertiesでポート変更
echo "server.port=8081" >> src/main/resources/application.properties

まず chmod +x setup_java.sh を実行してから、./setup_java.sh を実行してください。それでも問題がある場合は、上記の「代替方法」で直接コマンドを実行してください。

実行結果を教えてください!

hiroppy123@fedora:~/springboot-gradle-blog-main$ ./setup_java.sh ========================================== Java環境診断 & 設定スクリプト ========================================== [1] 現在のJava環境 ---------------------------------------- ✓ Javaコマンド: /usr/bin/java ✓ Javaバージョン: openjdk version "21.0.9" 2025-10-21 OpenJDK Runtime Environment (Red_Hat-21.0.9.0.10-1) (build 21.0.9+10) OpenJDK 64-Bit Server VM (Red_Hat-21.0.9.0.10-1) (build 21.0.9+10, mixed mode, sharing) [2] JAVA_HOME設定 ---------------------------------------- ✓ JAVA_HOME: /usr/lib/jvm/temurin-17-jdk ✗ ディレクトリが存在しません [3] インストール済みのJava ---------------------------------------- java-21-openjdk java-25 java-25-openjdk [4] 推奨設定 ---------------------------------------- ✓ Java 21が見つかりました (推奨) 推奨JAVA_HOME: /usr/lib/jvm/java-21-openjdk [5] 設定方法 ---------------------------------------- 以下のコマンドを実行してください: # 一時的な設定 (現在のセッションのみ) export JAVA_HOME=/usr/lib/jvm/java-21-openjdk export PATH=$JAVA_HOME/bin:$PATH # 永続的な設定 (~/.bashrcに追記) echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc source ~/.bashrc [6] 自動設定 ---------------------------------------- 自動的にJAVA_HOMEを設定しますか? (y/n): y 手動で設定してください ========================================== 診断完了 ========================================== hiroppy123@fedora:~/springboot-gradle-blog-main$ y bash: y: コマンドが見つかりませんでした... hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew test ERROR: JAVA_HOME is set to an invalid directory: /usr/lib/jvm/temurin-17-jdk Please set the JAVA_HOME variable in your environment to match the location of your Java installation. hiroppy123@fedora:~/springboot-gradle-blog-main$

12月11日

スクリプトが日本語の「y」を認識できなかったようです。直接コマンドでJAVA_HOMEを設定しましょう。

🔧 JAVA_HOMEを正しく設定

bash
# 1. 現在の間違ったJAVA_HOMEを上書き
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

# 2. 確認
echo $JAVA_HOME
java -version

# 3. .bashrcから古い設定を削除して新しい設定を追加
# まず古い設定を削除
sed -i '/temurin-17-jdk/d' ~/.bashrc

# 新しい設定を追加
echo '' >> ~/.bashrc
echo '# Java 21 環境変数' >> ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc

# 4. 設定を反映
source ~/.bashrc

# 5. 再度確認
echo $JAVA_HOME

動作確認とビルド

bash
# JAVA_HOMEが正しく設定されたか確認
echo $JAVA_HOME
# 出力: /usr/lib/jvm/java-21-openjdk

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

# Gradleをクリーン
./gradlew clean

# テスト実行
./gradlew test

# 成功したらビルド
./gradlew build

🚀 それでもエラーが出る場合の対処法

方法A: 環境変数を完全にリセット

bash
# 新しいターミナルを開いて以下を実行
unset JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

# 確認
echo $JAVA_HOME
$JAVA_HOME/bin/java -version

# Gradleを実行
./gradlew test

方法B: gradle.propertiesで直接指定

bash
# gradle.propertiesを作成(既に存在する場合は上書き)
cat > gradle.properties << 'EOF'
# Java 21を明示的に指定
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk

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

# パフォーマンス最適化
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.daemon=true
org.gradle.configureondemand=true
EOF

# 確認
cat gradle.properties

# Gradleを実行
./gradlew test

方法C: Gradle Wrapperを再生成

bash
# 既存のGradle設定を削除
rm -rf .gradle

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

# Gradle Wrapperを再実行
./gradlew --version

# テスト実行
./gradlew test

📋 完全な手順(ステップバイステップ)

以下のコマンドを順番に実行してください:

bash
# ========================================
# Step 1: 環境変数の設定
# ========================================
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH

echo "JAVA_HOME is: $JAVA_HOME"
java -version

# ========================================
# Step 2: .bashrcの修正
# ========================================
# 古い設定を削除
sed -i '/temurin-17-jdk/d' ~/.bashrc
sed -i '/JAVA_HOME/d' ~/.bashrc

# 新しい設定を追加
cat >> ~/.bashrc << 'EOF'

# Java 21 設定
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
EOF

source ~/.bashrc

# ========================================
# Step 3: gradle.propertiesの作成
# ========================================
cat > gradle.properties << 'EOF'
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
org.gradle.caching=true
EOF

# ========================================
# Step 4: Gradleキャッシュのクリア
# ========================================
rm -rf .gradle
./gradlew --stop

# ========================================
# Step 5: テスト実行
# ========================================
./gradlew clean test --info

# ========================================
# Step 6: 成功したらビルド
# ========================================
./gradlew build

🐛 デバッグ用コマンド

問題が続く場合、以下で詳細情報を確認:

bash
# Gradleが使用しているJavaを確認
./gradlew -version

# 環境変数の確認
env | grep JAVA

# Javaのインストール場所確認
ls -la /usr/lib/jvm/

# 実際のJavaバイナリの場所
readlink -f $(which java)

# Gradleのデバッグモードで実行
./gradlew test --debug 2>&1 | grep -i java

クイック修正(最短ルート)

時間を節約したい場合は、以下を一気に実行:

bash
# 一括設定スクリプト
cat > fix_java.sh << 'EOF'
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
sed -i '/temurin-17-jdk/d' ~/.bashrc
sed -i '/JAVA_HOME.*openjdk/d' ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
cat > gradle.properties << 'GRADLE_EOF'
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk
org.gradle.jvmargs=-Xmx2048m
GRADLE_EOF
rm -rf .gradle
echo "Java設定完了!"
echo "JAVA_HOME: $JAVA_HOME"
java -version
EOF

chmod +x fix_java.sh
./fix_java.sh
source ~/.bashrc

# テスト実行
./gradlew clean test

上記のいずれかを実行して、結果を教えてください!

hiroppy123@fedora:~/springboot-gradle-blog-main$ ./gradlew clean Downloading https://services.gradle.org/distributions/gradle-8.8-bin.zip .............10%.............20%.............30%.............40%.............50%.............60%..............70%.............80%.............90%.............100% Welcome to Gradle 8.8! Here are the highlights of this release: - Running Gradle on Java 22 - Configurable Gradle daemon JVM - Improved IDE performance for large projects For more details see https://docs.gradle.org/8.8/release-notes.html Starting a Gradle Daemon (subsequent builds will be faster) FAILURE: Build failed with an exception. * Where: Build file '/home/hiroppy123/springboot-gradle-blog-main/build.gradle' line: 85 * What went wrong: Could not compile build file '/home/hiroppy123/springboot-gradle-blog-main/build.gradle'. > startup failed: build file '/home/hiroppy123/springboot-gradle-blog-main/build.gradle': 85: Unexpected input: '{' @ line 85, column 29. tasks.withType(JavaCompile) { ^

1 error * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. BUILD FAILED in 26s hiroppy123@fedora:~/springboot-gradle-blog-main$

12月11日

0 件のコメント: