VSCode＋Mavenでfat jarファイルを作ってうまくいかなかった話

ライブラリを使ったjavaプログラムを単一のファイルで動かしかったので、いろいろ調べて四苦八苦したときの備忘録だす。

## fat jarってなんぞ？
### jarって何よ？
jarファイルとは、Java Archiveの略で、利用するファイルをひとつにまとめて圧縮したものと書いてあった。
開発している端末とは別の端末で、Javaアプリを動かすとき好都合。１つのファイルをもっていけば良いので、手間がない。
しかし、依存関係のライブラリを使っているときは、
```bat
java -cp [本体のjarファイル];[ライブラリaのjarファイル];[ライブラリbのjarファイル]
```
みたいに、複数jarファイルを連ねないとならないので、不便。
ファイルも、ライブラリのjarファイルを一緒にもっていかないとならない。

### fat jar
そこで、ChatCPTに聞いてみた。
> 複数のライブラリをインポートしたプログラムを、ひとつのjarにまとめる方法はありますか？

> 複数のライブラリを含むプログラムをひとつのjarにまとめる方法はあります。このプロセスを「ファットJAR」と呼びます。

あるんかい！　スゲー

# Mavenでfat jarを作る　けど出来ない。
僕は、VSCodeでMavenを使ってjarを作っている。なのでネットで、「VSCode Maven fat jar」を検索してたどり着いた以下のサイトによると、

[覚えたら書く](https://blog.y-yuki.net/entry/2016/12/10/000000)

pom.xmlの、\<build\>→\<plugins\>タグの下に、以下の\<plugin\>セクションを追記。
さらに、メインクラスの「完全修飾クラス名」を \<manifest\>タグのところに記載するのだそうだ。

```pomの一部.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>{MainクラスのFQCN}</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
```

僕のプロジェクトのpom.xmlだと、以下のようになる。
分かりやすいように、上記の設定を挿入した部分をコメントで書いておこう。

```pomの一部.xml
<!-- 前略 -->
  <dependencies>

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10.1</version>
    </dependency>

<!-- 中略 -->

  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>

<!-- 中略 -->

        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!--　ここに挿入 -->
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>3.3.0</version>　<!-- 他のサイトを参考にバージョンを変えた -->
          <configuration>
            <archive>
              <manifest>
                <mainClass>com.example.App</mainClass> <!-- メインクラスの指定 -->
              </manifest>
            </archive>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef> <!-- ファットjarを生成する -->
            </descriptorRefs>
          </configuration>
          <executions>
            <execution>
              <id>make-assembly</id>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <!--　ここまで -->
      </plugins>
    </pluginManagement>
  </build>
</project>
```

ここで、DOSコマンドプロンプトからプロジェクトフォルダ直下で、`mvn clean install`とやると、プロジェクトディレクトリ配下のtargetディレクトリに、`[プロジェクト名].jar`　と　`[プロジェクト名]-jar-with-dependencies.jar`　の２つのjarファイルが出来るというのだけど・・・・・　

`[プロジェクト名].jar`しか出来ないじゃん。

# Mavenでfat jarを作る　やっと出来た。
buildブロックを`maven-assembly-plugin`のみにしてみたり、いろいろやった結果、最終的に、`<pluginManagement>`が悪さしていることが分かったので、それをコメントアウトした。`<pluginManagement>`を消した影響が分からないけど、動けばいいや。


```diff_xml
<!-- 前略 -->
  <build>
-    <pluginManagement>
+    <!-- <pluginManagement> コメントアウト-->

      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>

<!-- 中略 -->

        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!--　ここに挿入 -->
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>3.3.0</version>　<!-- 他のサイトを参考にバージョンを変えた -->
          <configuration>
            <archive>
              <manifest>
                <mainClass>com.example.App</mainClass> <!-- メインクラスの指定 -->
              </manifest>
            </archive>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef> <!-- ファットjarを生成する -->
            </descriptorRefs>
          </configuration>
          <executions>
            <execution>
              <id>make-assembly</id>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <!--　ここまで -->
      </plugins>
-    </pluginManagement>
+    <!-- </pluginManagement> コメントアウト -->
  </build>
</project>
```
ここで出来た、`[プロジェクト名]-jar-with-dependencies.jar`を適当なフォルダにコピーして、以下のようにコマンドをたたくと、動く！便利！

```bat
java -jar [プロジェクト名]-jar-with-dependencies.jar
```



:::note info
fat jar って言ったら、まず、ミヒマルＧＴさんの歌のフレーズが思い浮かんだ。

>猫背のイニシャル Fat J

勇者ヨシヒコのオープニングにも使われていた。
あのドラマもよかったなぁ。