◀ 4.

【maven】ローカル(サードパーティ製)のjarを追加する方法

Mavenで手元のjarを使うには、jarとPOMの登録、利用側の依存宣言、配布時の起動方法を分けます。install-fileが成功しても、別PC/CIから解決できることや、アプリのjar一つへ依存が全て入ることまでは保証しません。

ローカルjarの登録、依存解決、配布時のクラスパスを分けた3工程

まず配布元と利用条件を確認する

配布元がMaven用リポジトリと正しい座標を提供しているなら、その案内を先に確認します。手動登録が必要な場合も、入手元・対象版・ハッシュ等の整合性・利用/再配布条件を確認してから扱います。未知のjarを試す手順ではありません。社内リポジトリへ置けば権利や安全性の確認が不要になるわけでもありません。

groupId/artifactId/version(GAV)は登録側と利用側で一致させます。groupIdはJavaのpackage名と同じである必要はありません。別の内容を同じGAVへ上書きして配布せず、提供元の版管理とチームの運用を確認します。classifierや独自packagingがある場合は、以下の単純なjar教材のまま流用しません。

検証用repoを指定して明示的に登録する

以下はPOSIX sh向けの教材です。REPOには新しい専用ディレクトリの絶対パスを設定します。既存の.m2/repositoryへ向けないでください。PowerShell/cmdでは環境変数と行継続の構文が異なります。install-fileのlocalRepositoryPathだけ指定しても、別のビルドが同じrepoを使うとは限らないため、ここでは全Maven呼出しへ同じmaven.repo.localを渡します。

例のlib/helper-1.0.jarとlib/third-party-1.0.jarは、検査用に自作したクラスのjarです。third-partyはhelperを利用し、配布元POMに相当するthird-party.pomへその依存を明示します。実製品の依存を推測して補う例ではありません。依存のないhelperだけgeneratePom=trueを使い、third-partyはpomFileを指定します。

新しい空の作業ディレクトリを用意し、Helper.java、ThirdParty.java、third-party.pom、app/pom.xml、app/src/main/java/example/App.javaを以下の掲載内容で配置します。Helper.javaとThirdParty.javaは作業ディレクトリの直下、App.javaは指定パスです。JDKのjavac/jar/javaとMavenが利用できることを先に確認します。

package example;

public final class Helper {
    public static String message() { return "local-jar-ok"; }
}
package example;

public final class ThirdParty {
    public static String message() { return Helper.message(); }
}
package example;

public final class App {
    public static void main(String[] args) {
        System.out.println(ThirdParty.message());
    }
}

作業ディレクトリで次を実行して自作2jarを準備します。既存の同名ファイルを使う検証ではありません。

#!/bin/sh
set -eu
# Use a new empty example directory, with the source files placed as shown.
mkdir -p lib classes-helper classes-third
javac -d classes-helper Helper.java
jar --create --file lib/helper-1.0.jar -C classes-helper .
javac -cp lib/helper-1.0.jar -d classes-third ThirdParty.java
jar --create --file lib/third-party-1.0.jar -C classes-third .

続いて下記のthird-party.pomとapp/pom.xmlを配置し、REPOを新規の専用絶対パスに設定して次の処理を実行します。シェルファイルとして使う場合はinstall-and-build.shという名前です。

#!/bin/sh
set -eu
# Run in the dedicated example directory; never point REPO at an existing repository.
: "${REPO:?Set REPO to a new absolute scratch repository path}"
mvn -B -ntp "-Dmaven.repo.local=$REPO" \
  org.apache.maven.plugins:maven-install-plugin:3.2.0:install-file \
  -Dfile=lib/helper-1.0.jar -DgroupId=example.local \
  -DartifactId=helper -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true
mvn -B -ntp "-Dmaven.repo.local=$REPO" \
  org.apache.maven.plugins:maven-install-plugin:3.2.0:install-file \
  -Dfile=lib/third-party-1.0.jar -DpomFile=third-party.pom
mvn -B -ntp "-Dmaven.repo.local=$REPO" -f app/pom.xml package \
  org.apache.maven.plugins:maven-dependency-plugin:3.11.0:copy-dependencies \
  -DincludeScope=runtime -DoutputDirectory=target/lib
java -jar app/target/demo-1.0.jar

この一連のコマンドは、必要なMaven plugin等を取得するネットワーク接続とローカルへの書込みを伴います。本番/普段の作業ディレクトリで無条件に実行しないでください。上限や配置先を含む隔離条件はこのページ末尾に記載します。mvn cleanは登録のために必須の手順ではなく、既存target等を削除する操作です。

依存POMを渡す理由

generatePomは最小POMを作る機能で、jarの中を解析して必要な別jar(推移依存)を完全に発見する機能ではありません。jar内のPOM等から情報を取得する場合もありますが、失われた依存情報を復元できると考えません。提供元の正しいPOMがある場合はpomFileを利用し、親POMや依存先も解決可能か確認します。今回の自作jarには埋込みPOMがなく、最小POMだけだとビルド後の実行でHelperが見つからないことを検査しています。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example.local</groupId>
  <artifactId>third-party</artifactId>
  <version>1.0</version>
  <dependencies>
    <dependency>
      <groupId>example.local</groupId>
      <artifactId>helper</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>
</project>

利用側の完全なpom.xmlと配布方法

次はJDK 21向けの独立したJavaアプリ例です。example.AppのmainはThirdParty.message()を出力します。compiler/jar pluginを固定し、Main-Classとlib/へのClass-Pathを設定します。コマンド中のcopy-dependenciesはruntimeの依存jarをapp/target/libへコピーします。これはfat jarではなく、demo-1.0.jarとlibディレクトリを相対配置のまま一緒に配る方式です。

この小さな教材ではjar pluginのforceCreation=trueでアプリjarを毎回作り直します。依存POMを切り替えた負例の後に、古いmanifestを再利用しないためです。これは依存の全鮮度やビルド全体の再現性を保証する設定ではなく、通常のプロジェクトへ理由なく必須化するものでもありません。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example.local</groupId>
  <artifactId>demo</artifactId>
  <version>1.0</version>
  <properties>
    <maven.compiler.release>21</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>example.local</groupId>
      <artifactId>third-party</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.14.1</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.4.2</version>
        <configuration>
          <forceCreation>true</forceCreation>
          <archive>
            <manifest>
              <mainClass>example.App</mainClass>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

アプリjarだけを別の場所へ移すと依存jarが見つかりません。manifestを書いただけで依存ファイルが自動で同梱されるわけでもありません。クラス名/ファイル名を教材と合わせ、ビルドした成果物をプロジェクト外の新しいディレクトリへ配置してjava -jarで確認します。実際の多数の依存では同名ファイルの衝突・scope・任意依存等も確認が必要で、この2jarの成功で全製品の配布を保証しません。

clean連動とSpring Bootを混ぜない

cleanとdefaultは別のライフサイクルです。旧例のphase=cleanはcleanを呼んだときの連動で、mvn packageやmvn verifyだけで必ずinstall-fileが走る設定ではありません。標準CLIにmvn buildというphaseはありません。Eclipseの「Maven Build」実行設定という名前とは区別し、Goalsへpackage等を指定します。教材の検査はCLIだけで、Eclipse実画面は未検証です。

Spring Bootで依存を含む実行可能アーカイブにする場合はrepackageとプロジェクトの親/設定を確認します。spring-boot-starter-parentから実行設定を継承する場合もあり、「plugin名だけ書けば必ず動く」「必ず何も実行されない」のどちらにも一律に断定しません。今回の新教材は通常Javaのmanifest/classpath方式で、Bootの起動/再パッケージや実アプリの動作を検証したものではありません。

チーム/CIで再現できるようにする

手元のrepoへのinstallは他の端末へ配布されません。利用条件を満たす共有リポジトリと配布元POMを使うか、CIに明示的な準備工程を設けます。資格情報はpom.xml/公開記事/ログへ埋め込まず、既存の認証管理を使います。実行機にMavenローカルrepoがある前提にせず、配布物として必要なjarと設定を確認します。IDEで通ること、CLIでpackageできること、配布先で起動できることは別の確認です。

旧記事のコードと手順

元の色付きコード表2個と章を以下に保持しています。現在の推奨手順と混同しないよう、問題点を各表の直前にも記載しています。削除されたタグ名の説明は本文へ補いました。

旧表の注意:旧要点の「実行可能jar内でも参照」は登録だけで保証されません。先に示した新しい手順では依存解決と配布時の配置/起動を分けています。

この記事の要点
  • Maven でローカルの jar(サードパーティ製)を追加する方法
  • 手順1: jar を lib/ 等に配置
  • 手順2: pom.xml で maven-install-plugin を使ってローカルリポジトリへ登録
  • 実行可能 jar 内でも参照できるよう、依存として正しく解決させる

 

前提

ローカルだけで依存解決できる状態と、他の環境で再現/実行できる状態を分けます。

依存の登録だけで起動を保証せず、配布方法に応じて必要な依存ファイルを確認します。

 

 

 jarファイルの設置

配布元/版/利用条件を確認したjarを、明示した準備用ディレクトリへ配置します。

(対象プロジェクトのlibディレクトリ配下など)

 

pom.xmlへの記述

まずはmavenのローカルリポジトリにサードパーティjarを保存する。

以下はcleanへ登録を結び付けた旧構成です。新しい教材では登録コマンドを明示し、cleanを登録の必須手順にしません。

旧表の注意:これはcleanへ連動させた旧設定です。plugin版/親設定は固定されておらず、packageだけでの登録やBootのrepackageを保証しません。repositoryLayoutは今回使うinstall-plugin 3.2.0の引数として採用せず、旧版の全組合せを未検証のまま非対応と断定しません。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>

                <execution>
                    <id>
install-external-test1</id>
                    <phase>clean</phase>
                    <configuration>
                        <file>${basedir}/lib/
test1.jar</file>
                        <repositoryLayout>default</repositoryLayout>
                        <groupId>
com.test1</groupId>
                        <artifactId>
test1</artifactId>
                        <version>1.0</version>
                        <packaging>jar</packaging>
                        <generatePom>true</generatePom>
                    </configuration>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                </execution>

            </executions>
        </plugin>

    </plugins>
</build>

旧構成で複数の実行を宣言する場所は<executions>内の<execution>です。ただし、登録をcleanへ連動させる方式の採否は準備工程と分けて判断します。

plugin内の各executionのidは区別できるようにします。警告の時期やビルド成否は対象版/全POM次第で、この断片だけでは断定しません。

 

次の依存宣言は<dependencies>内へ置く断片です。完全な利用側POMは上に示しています。

旧表の注意:このdependencyはdependenciesの内側へ置く断片です。GAVは登録側と一致させ、POMの依存情報と配布時のクラスパスも確認します。groupIdはJavaのpackage名と同一である必要はありません。

<dependency>
    <groupId>
com.test1</groupId>
    <artifactId>
test1</artifactId>
    <version>1.0</version>
</dependency>

 

ビルド

CLIではpackage等の目的のphaseを指定し、配布先の依存配置と起動も検査します。旧記述の「maven build」を標準CLIのphase名として実行しません。

 

確認範囲と公式資料

2026年10月26日確認。Maven 3.9.16/JDK 21.0.12.1のローカル隔離コンテナで、自作2jar・専用repoだけを使って検査しています。実サードパーティ製品/再配布権/署名/脆弱性の保証や、Eclipse/Spring Boot/Windowsシェル・別Maven/JDK・既存本番アプリの実行検証ではありません。起動前のplugin取得は公開リポジトリへの通信を伴い、既存の資格情報/.m2や本番環境を使っていません。

Mavenの親ページから子ページを選択できます。Eclipseのビルド、.m2の場所、エラー一覧も参照してください。

公式資料:第三者jarのローカル登録、install-fileとPOM、ライフサイクル、manifestとクラスパス、依存jarのコピー、Bootのrepackage。

子ページ

子ページはありません

同階層のページ
  1. ビルドする方法(eclipse)
  2. エラー一覧
  3. .m2フォルダの場所
  4. ローカル(サードパーティ製)のjarを追加する方法

最近更新/作成されたページ