この記事では、デフォルトでmavenにないライブラリを接続する方法と、ソースが長く失われている別のライブラリを接続する方法を説明します。
また、ライブラリでもあるアーティファクトを生成するMavenプロジェクトの作成方法、およびこのライブラリを他のMavenプロジェクトに接続する方法についても説明します。
この記事は、Javaを学習し始めたばかりの人を対象としています。
前回の記事では、maven自体がpom.xmlで指定されたすべての依存関係をダウンロードすると言われていました。 しかし、依存関係が見つからない場合はどうなりますか? この場合、mavenは依存関係が見つからなかったと言い、エラーでビルドプロセスを中断します。 この場合の対処方法
実際、この質問はいくつかの質問に分かれており、それぞれ個別に対処する必要があります。 ソリューションの選択は、この依存関係の場所によって決まります。
依存関係はインターネット上のどこかで発生する可能性がありますが、その存在はMavenにはわかりません。 また、jarファイルの形で手に入れることができ、最後に、Mavenプロジェクトとして設計されたソースコードの形にすることもできます。
これら3つのケースについて説明します。
しかし、最初に、1つの質問を簡単に明確にする必要があります。
Mavenはどこからライブラリをダウンロードしますか
インターネットには、Javaライブラリが配置されているサーバーがあります。 このサーバーはリポジトリと呼ばれ、ロシア語ではリポジトリです。 これはある種の抽象ではなく、非常に特定のリソースであり、そのアドレスはデフォルトのMaven設定に縫い付けられています。 したがって、それはデフォルトのリポジトリと呼ばれます。 これは、mavenがpom.xmlから依存関係を探す場所です。
ライブラリがデフォルトでリモートリポジトリにないが、別のリモートリポジトリにある場合
最初の、おそらく最も一般的な問題は、このデフォルトリポジトリにライブラリが存在しない場合、またはセキュリティ上の理由などから、このリポジトリが構築されているマシンから利用できない場合に発生します。
問題の原因はわずかに異なりますが、解決策は同じです-依存関係があるリポジトリを指定する必要があります。 これは、インターネット上の他のアドレス、またはローカルネットワークの管理者が発行したリポジトリのアドレスです。
追加のリポジトリを探す場所をプロジェクトにMavenに指示する方法
デフォルトのリポジトリだけでなく依存関係を検索する必要があることをMavenに伝えるために、通常のメカニズムがあります。 これは、検索用に別のアドレスを登録する方法です。
<repositories> <repository> <id>id </id> <url> </url> </repository> </repositories>
次に、このライブラリファミリの最新バージョンを見つけることができるSpringプロジェクトリポジトリを接続しました。 これはpom.xml内での見え方です
<repository> <id>com.springsource.repository.bundles.release </id> <url>http://repository.springsource.com/maven/bundles/release </url> </repository>
mavenは、デフォルトでリポジトリに依存関係が見つからない場合、または使用できないことが判明した場合、パニックに陥ることはありませんが、別のリポジトリでライブラリを検索し、すべてが計画どおりに進んだ場合、そこにあります。 プログラムが依存関係として使用できる場合、たとえばライブラリ自体である場合、pom.xmlにリポジトリタグを配置することはお勧めできません。 これがなぜそうなのかの説明は記事の範囲外ですが、 ここで見つけることができます 。
しかし、リポジトリにライブラリが存在しないことがあります。 たとえば、MSSQLのドライバである場合、または最近多額のお金で購入した独自のライブラリである場合。
リポジトリにないライブラリを接続する方法
このようなライブラリを接続するにはいくつかの方法があります。 たとえば、ローカルネットワーク上に独自のリポジトリがある場合は、ライブラリをそこに置くことができ(必要な場合もあります)、タスクを以前のものに減らすことができます。
ただし、可能であれば、そのようなライブラリをプロジェクトに配置し、バージョン管理システムに直接保存することをお勧めします。 その後、ライブラリはいつでも任意のマシンでプログラムで使用でき、このライブラリをリポジトリにコピーする手順はマニュアルから省略できます。
このような場合に対処するために、mavenには通常のメカニズムもあります。 デフォルト以外のMavenリモートリポジトリを指定する方法を見つけました。 そのため、リモートストレージを使用する必要はありません。 ローカルファイルシステムにリポジトリを作成し、そこにライブラリを配置し、mavenに依存関係を探すように指示することもできます。
ローカルリポジトリを作成する方法
このため、前述のように、mavenには通常のツールがあります。
hello-world-library-1.0-SNAPSHOT.jarという名前のjarファイルにあるライブラリがあるとします。 ライブラリには、HelloWorldクラスが1つあることがわかっています。このクラスには、ご存知のように、Hello Worldというコンソールに出力する静的なsayメソッドが1つ含まれています。
プロジェクトディレクトリにlibディレクトリを作成し、そこに追加のリポジトリを配置して、そこにライブラリを配置します。 これを行うには、プロジェクトディレクトリで次のコマンドを実行するだけで十分です。
mvn \ deploy:deploy-file \ -Durl=file:./lib \ -Dfile=hello-world-library-1.0-SNAPSHOT.jar \ -DgroupId=com.local \ -DartifactId=hello-world-library-local \ -Dpackaging=jar \ -Dversion=1.0-SNAPSHOT
Windowsオペレーティングシステムを使用している場合は、\を^に置き換える必要があります。つまり、
mvn ^ deploy:deploy-file ^ -Durl=file:./lib ^ -Dfile=hello-world-library-1.0-SNAPSHOT.jar ^ -DgroupId=com.local ^ -DartifactId=hello-world-library-local ^ -Dpackaging=jar ^ -Dversion=1.0-SNAPSHOT
または、単に\を削除して、コマンドを1行で記述することもできます。
mvn deploy:deploy-file -Durl=file:./lib -Dfile=hello-world-library-1.0-SNAPSHOT.jar -DgroupId=com.local -DartifactId=hello-world-library-local -Dpackaging=jar -Dversion=1.0-SNAPSHOT
他のアーティファクトについては、ライブラリについては、groupId、artifactId、およびバージョンを作成する必要があることに注意してください。 次に、依存関係を接続するときにpom.xmlでそれらを指定します。
チームが作成するディレクトリ内には、Mavenが配置されている場所を示すのに十分な本格的なリポジトリがあります。 どのライブラリがそこにあるかについてのすべての情報は、新しく作成されたリポジトリのディレクトリ構造に直接含まれています。 たとえば、他のマシンでリポジトリを後で使用する場合、deploy-fileコマンドは必要ありません。
上記の方法でリポジトリが存在することをプロジェクトに知らせることができます。ただし、リポジトリがローカルであるという事実に合わせて調整します。
<repositories> <repository> <id>localrep</id> <name>local repository</name> <url>file:${project.basedir}/lib</url> </repository> </repositories>
5行目に注意してください
<url>file:${project.basedir}/lib</url>
組み込み変数maven project.basedirが指すプロジェクトディレクトリでリポジトリを探す必要があると書かれています。
ライブラリを使用するクラスは非常に単純ですが、順序のためにコードを提供します。
package com; import static com.HelloWorld.say; public class Application { public static void main(String[] argv) { say(); } }
pom.xmlに依存関係を追加することは残り、プロジェクトをビルドできます。
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>library-user-with-local-repository</artifactId> <version>1.0-SNAPSHOT</version> <repositories> <repository> <id>localrep</id> <name>local repository</name> <url>file:${project.basedir}/lib</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.local</groupId> <artifactId>hello-world-library-local</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
チェック:
mvn clean compile exec:java -Dexec.mainClass="com.Application"
うまくいく!
libディレクトリはコンパイルする必要があり、ライブラリは常にプロジェクトで常に利用可能になります。
ただし、留意すべきルールが1つあります。
jarファイルが変更されるたびに、ローカルリポジトリ内のライブラリのバージョン番号を更新する必要があります
Mavenはリポジトリを外部として扱います。したがって、バージョン番号を変更しない場合、Mavenはlibディレクトリのライブラリバージョンを使用せず、ローカルマシンにキャッシュしたバージョンを使用します。 この特定のケースでは、これはSNAPSHOTサフィックスのために役割を果たすべきではありませんが、それについて知る必要があります。
別の一般的なシナリオがあります。 独自のライブラリがあり、自分でmavenを使用してビルドし、別のmavenプロジェクトに接続します。
Javaライブラリの作成方法
ライブラリを作成するには、public修飾子を付けてクラスを作成します。 そして、ライブラリが接続されているコードでこのクラスを使用することが可能になります。
たとえば、クラスは次のとおりです。
package com; public class HelloWorld { public static void say() { System.out.println("Hello world"); } }
次に、このクラスを含むライブラリをコンパイルするMavenプロジェクトを作成する必要があります。
思い出すと、Mavenの観点から見ると、ライブラリは単なるアーティファクトであるため、ピックアップは簡単に見えるでしょう。
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>hello-world-library</artifactId> <version>1.0-SNAPSHOT</version> </project>
したがって、静的メソッドを持つクラスと、Mavenのアーティファクトの説明があります。 このコードを収集してライブラリ、つまりjarファイルを取得するだけです。
コンソールに書くだけです:
mvn package
その後、 \ <artifactId>-\ <version> .jarという名前のファイルがターゲットディレクトリに表示されます。特定のケースでは、 hello-world-library-1.0-SNAPSHOT.jarがライブラリです。
新しく作成したライブラリをMavenプロジェクトに接続する方法
後でライブラリを別のプロジェクトに接続するには、 packageではなくinstallを記述する必要があります 。
mvn install
これは、ライブラリコードを変更するたびに、このライブラリを使用するすべてのコンピューターで実行する必要があります。
これで、ライブラリを使用する新しいプロジェクトを作成できます。
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com</groupId> <artifactId>hello-world-library</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
プロジェクト内には、ライブラリの静的メソッドを使用してHello worldと言うクラスが1つあります。 このクラスはすでに見ました。
package com; import static com.HelloWorld.say; public class Application { public static void main(String[] argv) { say(); } }
もう一度確認してください:
mvn compile exec:java -Dexec.mainClass="com.Application"
以前のバージョンと同じように機能します!
ライブラリが別のライブラリを使用している場合はどうなりますか?
質問は馬鹿げているように思えますが、念のために実験を行います。
空ではない依存関係を持つライブラリを作成しましょう。
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>hello-world-library</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> </dependencies> </project>
そしてそのためのコードを書く
package com; import static org.apache.commons.lang3.ArrayUtils.*; public class HelloWorld { public static void say() { String[] phrase = {"Hello"}; phrase = add(phrase, " "); phrase = add(phrase, "world"); for (String word : phrase) { System.out.print(word); } System.out.println(); } }
今それを集めます
mvn clean install
このライブラリを使用するプロジェクトのディレクトリに移動して、ビルドして実行してみましょう。
mvn clean compile exec:java -Dexec.mainClass="com.Application"
そしてそれは動作します!
仕組み
厳密に言えば、プロセスが内部にどのように配置されているかを知る必要はありませんが、それでも非常に便利です。
mvn installコマンドはライブラリをビルドし、ローカルのデフォルトリポジトリに配置します。 つまり、これまでにMavenプロジェクトに接続したすべてのライブラリが配置されているのと同じ場所に、もちろん、自分で作成したローカルリポジトリにあるライブラリは例外です。
次に、このライブラリを使用してプロジェクトをビルドすると、mavenはローカルストレージでそれを探し、それを見つけて接続します。
合計
- Mavenは、デフォルトでリモートリポジトリでライブラリを探します。
- デフォルトのリポジトリにないライブラリを接続するために、追加のリモートリポジトリを指定することができ、mavenはそれらのライブラリも検索します。
- リモートリポジトリにライブラリがない場合、通常のmavenメカニズムを使用して、ローカルリポジトリを作成し、pom.xmlに追加できます。
- プロジェクトのソースコードにあるリポジトリを更新するときは、ライブラリのバージョンを常に変更する必要があります。変更しないと、理解できない問題が発生する可能性があります。
- Mavenプロジェクトがある場合は、 mvn packageコマンドを使用して、プロジェクトからライブラリを作成できます 。
- mvn installコマンドを使用すると、デフォルトでローカルリポジトリにライブラリを配置できます。
- 別のプロジェクトでライブラリを使用するには、pom.xmlで依存関係として指定します。
UPD :コメントでは、 sshikov 、 igor_suhorukov 、 jbaruchなどが、NexusやArtifactoryなど、このために特別に設計された他のツールがあるため、ライブラリをソースとともに保存すべきではないという見解を表明しました。
ここで私は完全に同意します。 大規模なプロジェクトや企業開発に関しては、他の方法では不可能です。 しかし、私の観点からは、そうでない方が便利な場合があります。 初心者が通常このようなことを扱っているため、トレーニングプロセス中に作成された小さなプロジェクトを意味します。インフラストラクチャにアクセスできず、10分以内にライブラリをアセンブリに追加する必要がある場合があります。 その記事がそのような場合についてのものであることを明確にすることが最初から必要でした。
はい、バージョン管理システムにライブラリを保存するのはハッキングです。 しかし、すべてのハックと同様に、これは場合によっては使用できるものであり、その実装の可能性について知っておくとよいでしょう。
この記事で提案されている手法が企業開発に適していない理由は、コメントで十分に明らかにされています。 リンクの jbaruchのおかげで、Nexus開発者からの記事に注意することもお勧めします。 この記事は興味深いです。Habréで既存の翻訳が見つからない場合は、翻訳して別の投稿にする予定です。