Java Mavenで依存関係も含めたすべてのライブラリを実行可能jarにまとめる

photo of person typing on computer keyboard

Javaででビルドする際に,開発したプログラムだけでなく,依存しているjarも含めてすべてを単一のjarファイルにまとめたい時の方法について紹介します.

目次

ライブラリのクラスパス

Mavenで作成したプロジェクトで依存関係のあるライブラリを指定した場合、以下で起動しようとすると、依存しているライブラリのクラスパスが見つからないとエラーが表示されます。

% java -jar ./target/DirectoryMerge-1.0-SNAPSHOT.jar
Exception in thread "main" java.lang.NoClassDefFoundError: gnu/getopt/Getopt
        at org.example.DirectoryMerge.main(DirectoryMerge.java:33)
Caused by: java.lang.ClassNotFoundException: gnu.getopt.Getopt
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 1 more

maven-jar-pluginでjarを作成するだけでは、依存するライブラリは単一のjarにまとめてくれないためです。そのため、ライブラリのクラスパス、クラス名も含めて以下のように記述する必要が出てきています。

java -jar ./target/DirectoryMerge-1.0-SNAPSHOT.jar -classpath クラスパス1;クラスパス2; クラス名1;クラス名2

ちなみに、Mac OSの場合、mavenでダウンロードされたクラスは~/.m2/repository配下に保存されています。

~/.m2/groupID/artifactID/version/
cd ~/.m2/repository
% ls -alh
...
drwxr-xr-x  32 xxx  staff   1.0K Dec 27 12:56 .
drwxr-xr-x   3 xxx  staff    96B Dec 16 20:14 ..
drwxr-xr-x   3 xxx  staff    96B Dec 20 16:32 commons-lang
drwxr-xr-x   4 xxx  staff   128B Dec 25 21:16 commons-logging
...

単一のjarに依存ライブラリをまとめるMavenプラグイン

pom.xml

maven-assembly-plugin, maven-dependency-pluginの2つをプラグインに指定します。

appendAssemblyIdをtrueにすると、作成されたjarのファイル名にjar-with-dependenciesが追加されます。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
	<appendAssemblyId>false</appendAssemblyId>
	<descriptorRefs>
	<descriptorRef>jar-with-dependencies</descriptorRef>
	</descriptorRefs>
	<archive>
	<manifest>
		<mainClass>org.example.DirectoryMerge</mainClass>
	</manifest>
	</archive>
</configuration>
<executions>
	<execution>
	<id>make-assembly</id>
	<phase>package</phase>
	<goals>
		<goal>single</goal>
	</goals>
	</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
	<execution>
	<id>copy-dependencies</id>
	<phase>package</phase>
	<goals>
		<goal>copy-dependencies</goal>
	</goals>
	</execution>
</executions>
</plugin>

実行

以下のコマンドでビルド、実行が出来ます。

% mvn clean
% mvn package
% java -jar ./target/DirectoryMerge-1.0-SNAPSHOT.jar
よかったらシェアしてね!
目次