ネストされた JAR

Java は、ネストされた jar ファイル(つまり、jar 内に含まれる jar ファイル)をロードする標準的な方法を提供しません。これは、コマンドラインから展開せずに実行できる自己完結型アプリケーションを配布する必要がある場合に問題になる可能性があります。

この問題を解決するために、多くの開発者は「シェーディングされた」jar ファイルを使用します。シェーディングされた jar は、すべての jar からのすべてのクラスを単一の "uber jar" にパッケージ化します。シェーディングされた jar ファイルの問題は、どのライブラリが実際にアプリケーションに含まれているかを見にくくなることです。また、複数の jar で同じファイル名(ただし、異なるコンテンツ)が使用されている場合、問題が発生する可能性があります。Spring Boot は異なるアプローチを採用しており、実際に jar を直接ネストできます。

実行可能な Jar ファイル構造

Spring Boot ローダー互換の jar ファイルは、次のように構成する必要があります。

example.jar
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-BOOT-INF
    +-classes
    |  +-mycompany
    |     +-project
    |        +-YourClasses.class
    +-lib
       +-dependency1.jar
       +-dependency2.jar

アプリケーションクラスは、ネストされた BOOT-INF/classes ディレクトリに配置する必要があります。依存関係は、ネストされた BOOT-INF/lib ディレクトリに配置する必要があります。

実行可能な War ファイル構造

Spring Boot ローダー互換の war ファイルは、次のように構成する必要があります。

example.war
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-WEB-INF
    +-classes
    |  +-com
    |     +-mycompany
    |        +-project
    |           +-YourClasses.class
    +-lib
    |  +-dependency1.jar
    |  +-dependency2.jar
    +-lib-provided
       +-servlet-api.jar
       +-dependency3.jar

依存関係は、ネストされた WEB-INF/lib ディレクトリに配置する必要があります。組み込みの実行時に必要であるが、従来の Web コンテナーにデプロイする場合には不要な依存関係は、WEB-INF/lib-provided に配置する必要があります。

インデックスファイル

Spring Boot ローダー互換の jar および war アーカイブには、BOOT-INF/ ディレクトリに追加の索引ファイルを含めることができます。classpath.idx ファイルは jar と war の両方に提供でき、jar をクラスパスに追加する順序を提供します。layers.idx ファイルは jar にのみ使用でき、jar を論理レイヤーに分割して Docker/OCI イメージを作成できます。

インデックスファイルは YAML 互換の構文に準拠しているため、サードパーティのツールで簡単に解析できます。ただし、これらのファイルは内部的に YAML として解析されないため、使用するには以下に説明する形式で正確に記述する必要があります。

クラスパスインデックス

クラスパスインデックスファイルは BOOT-INF/classpath.idx で提供できます。通常、これは Spring Boot の Maven および Gradle ビルドプラグインによって自動的に生成されます。これは、クラスパスに追加する必要がある順序で、jar 名 (ディレクトリを含む) のリストを提供します。ビルドプラグインによって生成される場合、このクラスパスの順序は、アプリケーションの実行とテストのためにビルドシステムによって使用される順序と一致します。各行はダッシュスペース ("-·") で始める必要があり、名前は二重引用符で囲む必要があります。

例: 次の jar が与えられた場合:

example.jar
 |
 +-META-INF
 |  +-...
 +-BOOT-INF
    +-classes
    |  +...
    +-lib
       +-dependency1.jar
       +-dependency2.jar

インデックスファイルは次のようになります。

- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"
Spring Boot は、jar または war ファイルが java -jar で実行される場合にのみクラスパスインデックスファイルを使用します。IDE からアプリケーションを実行する場合や、Maven の spring-boot:run または Gradle の bootRun を使用する場合は使用されません。
再現可能なビルドを有効にすると、クラスパスインデックスファイル内のエントリはアルファベット順にソートされます。

レイヤーインデックス

レイヤーインデックスファイルは BOOT-INF/layers.idx で提供できます。レイヤーのリストと、レイヤー内に含まれる jar のパーツを提供します。レイヤーは、Docker/OCI イメージに追加する順序で書き込まれます。レイヤー名は、ダッシュスペース("-·")とコロン(":")サフィックスが前に付いた引用符付き文字列として記述されます。レイヤーコンテンツは、スペーススペースダッシュスペース("··-·")を前に付けた引用符付き文字列として記述されたファイルまたはディレクトリ名です。ディレクトリ名は / で終わりますが、ファイル名は終わりません。ディレクトリ名が使用されている場合、そのディレクトリ内のすべてのファイルが同じレイヤーにあることを意味します。

レイヤーインデックスの典型的な例は次のとおりです。

- "dependencies":
  - "BOOT-INF/lib/dependency1.jar"
  - "BOOT-INF/lib/dependency2.jar"
- "application":
  - "BOOT-INF/classes/"
  - "META-INF/"