67005
# 前置き

Spring Boot で作ったプロジェクトのデフォルトの`classpath`について気になっております。

## 似たような質問

[Spring -
Springのclasspathは、「main/resourcesディレクトリをトップレベル」に見なすとは？｜teratail](https://teratail.com/questions/83170)  
上記にも似たような質問がありました。 回答には

> それはSpringFrameworkが定めているものではなくて、mavenのプロジェクト構成が定めているものです。

とあります。上記の質問は Spring BootではなくSpring単体（この表現でいいかわかっていない？）を使った場合のようですし、そもそも
mavenの構成とありますが、`maven`や`gradle`を使って`classpath`を設定するものなのでしょうか？

## Mavenのデフォルトについて言及している記事

加えて下記にも  
[Spring Bootがプロパティファイルを読み込む方法に一同驚愕！！ | Tagbangers
Blog](http://blog.tagbangers.co.jp/2019/07/12/how-spring-deals-with-
properties)

> 実はsrc/main/resourcesディレクトリはMavenのデフォルトのクラスパスの一つです。

とあります。

# 質問

Spring Bootの`classpath`を知るにはどすればいいのでしょうか？  
その前に`maven`や`gradle`の`classpath`についての基礎知識をおさえておかないといけない場合は、`maven`や`gradle`についての必要箇所についても教えて下さい。
CC BY-SA 4.0
2020-05-25T23:32:05.990
66984
2020-05-26T09:28:54.467
9008
question
spring spring-boot gradle maven
Spring Boot で作ったプロジェクトのデフォルトのclasspathはどこですか？
一般的に、JavaのWebアプリケーション(war)の場合、クラスパス（クラスがロードされるパス）は`WEB-INF/classes`と`WEB-
INF/lib`です。

すごく簡単に説明します。

MavenやGradleの標準的なディレクトリー構成に従い、`src/main/java`以下にJavaファイルを、`src/main/resources`にプロパティー・ファイルを置いてビルドすると、コンパイルされたクラスファイルやプロパティー・ファイルは`WEB-
INF/classes`ディレクトリーに出力されます。

サーブレットの仕様で、サーブレット・コンテナー（Tomcatなど）のWebアプリケーション・クラス・ローダーは最初に`WEB-
INF/classes`ディレクトリーからクラスファイルやプロパティー・ファイルをロードしなければならないことになってます(次は`lib`ディレクトリー内のjarファイルから)。

Mavenのディレクトリー構成や成果物の出力先を変えたり、Spring
Bootアプリにクラスパスを他の場所に追加することもできますが、特別な理由が無ければ、そのようなことをする必要はないです。
CC BY-SA 4.0
2020-05-26T04:04:35.333
66994
2020-05-26T07:24:01.663
2020-05-26T07:24:01.663
21092
21092
66984
answer
* 実行時に必要なクラスパスは実行時に指定するもので、ビルド時に指定するものではありません。
  * 質問文に記載されている2つのリンク先は、実行時に指定することになるクラスパスに配置するファイル(を包含するディレクトリ)の指定についての説明です。 
    * 後者の"実はsrc/main/resourcesディレクトリはMavenのデフォルトのクラスパスの一つです。"という説明は誤っています。このディレクトリが即ちクラスパスというわけではありません。

という前置きをした上で、

> Spring Bootのclasspathを知るにはどすればいいのでしょうか？

について、実際に知りたいのはクラスパスではなくてクラスパスに配備される対象がどれか、ということだと考えました。  
これについては、Gradleの場合[SourceSet](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSet.html)で設定します。  
(また、上記リンクから辿れる[Declaring your source files via source
sets](https://docs.gradle.org/current/userguide/building_java_projects.html#sec:java_source_sets)では具体的に何をやっているのかが図解されています。"output
directory"に出力されたファイルが実際の対象ファイルです。)

リンク先では、javaプラグインがSourceSetのデフォルト値として`${project.projectDir}/src/${sourceSet.name}/java`(など)を設定していますが、例えばkotlinプラグインを適用しているのであれば[kotlinプラグインがデフォルト値を設定します](https://kotlinlang.org/docs/reference/using-
gradle.html#targeting-the-jvm)。

[`allSource`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSet.html#org.gradle.api.tasks.SourceSet:allSource)を出力してみると対象がわかるようなので、`build.gradle.kts`に次を追記し`gradle`コマンドをを実行してみてください:

```

    sourceSets.forEach{
      println(it)
      it.allSource.forEach{
        println(it)
      }
    }
    
```

* * *

> mavenやgradleを使ってclasspathを設定するものなのでしょうか？

GradleのコマンドでSpring
Bootアプリケーションを実行した場合どうなのか、という話であれば、必要に応じてプラグインが設定してくれるようになっていますのでyesと言えるでしょう。  
例えば`gradle
bootRun`コマンド実行時に用いられるclasspath設定は[`runtimeClasspath`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSet.html#org.gradle.api.tasks.SourceSet:runtimeClasspath)を出力すれば確認できるようです:

```

    sourceSets.forEach{
      println(it)
      it.runtimeClasspath.forEach {
        println(it)
      }
    }
    
```

GradleのコマンドでSpring Bootアプリケーションをパッケージングした場合にどうなのか、という話であれば、"output
directory"のファイルを所定の位置に置いたりマニフェストに[Class-
Path属性](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/jar/jar.html#classpath)を追加したりというのをまた別のプラグインで行うことができますでこれもまたyesと言えるでしょう。  
(これはjarファイルとしての設定なので、実行時のクラスパス指定はまた別ですが、普通はこの設定をそのまま使うはずです)
CC BY-SA 4.0
2020-05-26T09:28:54.467
67005
2020-05-26T09:28:54.467
2808
66984
answer