このエントリはJava アドベントカレンダー 2015の20日目となります。 ただし今日は12月21日です。21日目のエントリがもう公開されているというレベルです。ごめんなさいごめんなさいごめんなさい。
さて、年末年始を前にして何か大きな機能追加とかリリースとかやって「やらかして」しまうとクリスマスも正月もドナドナになってしまうのを避けるために、 この時期はあまり大きな仕事はしないことになっております。そういうスキマ時間にしかできないことを少しやってみようと思いまして、 職場のエンジニアを集めてmavenの勉強会をやってみました。題して「mavenと書いて達人と読む」。
夕方に30分 x 4日連続。講師は全部自分。はい。2日目で力つきそうになって、4日シリーズにしたことを後悔しましたw。 そもそも自分自身だって達人にはほど遠いのですが、 プロジェクトの中でpom.xmlのメンテをやる人が限られてしまうとこうなるみたいなことがあったので、 やっぱり経験の浅い若手相手に座学っぽくやるのも時には必要なんだなーと思いました。 なお、いまどきgradleでしょ!とか言う話はスルーです。セントラルリポジトリのお世話になったことがないという者だけがmavenに石を投げなさい。
そんなわけで、以下、メモです。
1日目 maven標準ディレクトリ構造と基本コマンド
- ソースコードを動作可能な状態にまで変換することをビルドという。これはスクリプト言語でもコンパイル言語でも変わらない。コンパイル言語の場合にはビルドにはコンパイルという工程が含まれる。ビルドを支援するのがビルドツール。かつてはant、いまはmavenかgradle.
- IDE使わずにエディタだけでsrc/main/java/HelloWorld.javaとpom.xmlをつくる
- compile, exec:java, package, install など一通りたたいてみる
- 教科書にあるようなjavac HelloWorld.javaもやってみて、なにがどこにどう生成されるのか、比較してみる
- src/main/java, src/main/resources, src/test/java, src/test/resources というシンプルかつ機能的なディレクトリ構造と、依存関係の自動解決というのがmavenの最大の功績。
- 他のビルドツールを使っていても、結局 src/main/java みたいな構造は一緒であることが多い。
- ls ~/.m2/repository してみる。このディレクトリは何なのだろう?は次回以降のお楽しみ。
2日目 依存関係の自動解決、リポジトリという概念
- System.out.println("Hello World") のところをlog.info("...")に書き換える。当然まだコンパイルはできない。
- このときpomのdependencyにcommons-loggingを追加。mvn compileができるようになる。
- HelloWorldというクラスはorg.apache.commons.logging.Logというクラスに「依存している」同様にhelloというartifact(プロジェクト)はcommons-loggingというartifactに「依存している」依存関係をdependencyタグで表す。
- ちなみにjavacでやろうとすると javac -claspath "~/.m2/repository/commons-logging/commons-logging/1.1.1/commons-loggin-1.1.1.jar" src/main/java/HelloWorld.java みたいにすればコンパイルできる
- コンパイルのときや実行のときにクラスパスをいい感じにやっておいてくれるのがmavenのいいところ。それが依存関係の自動解決。
- リポジトリにはローカルとリモートの2種類がある。~/.m2/repositoryがローカル。リモートリポジトリのキャッシュみたいな役割になる(それだけじゃないけど)
- mvn help:effective-pom ってやるとセントラルリポジトリのurlがわかるよ。そのurlをブラウザで見てみると。。。
- mvn dependency:tree
- リモートリポジトリは誰でも立てられる。公開してもいいし、非公開ならインハウスリポジトリってことになる。ex. http://repository.apache.org
3日目 推移的な依存関係とビルドライフサイクル
※この日は疲れていたので内容が薄いw
- spring-boot-starterとか使って簡単なpom.xmlを作っただけなのにWebアプリがいきなりできあがるマジック
- mvn dependency:tree するとすごい数のjar(artifact)がツリー上に見える。これが「推移的」な依存関係。
- ビルドライフサイクルというものがある
4日目 マルチプロジェクト構造
- packagingというところにはpom, jar, war みたいな種類を書く。Project Object Model, Java Application Archive, Web Application Archive...
- たまにearというやつもあってだな、Enterprise...と口に出した瞬間からjarを含んだwarを複数含んだのがearでWebLogicだかなんだかで動いて起動に15分とかかかってもうねアホか..トラウマに襲われて取り乱すもなんとか平静を取り戻す
- parentとmodulesというタグを使って親子関係を形作ることができる。普通のファイルシステムとディレクトリ構造と同じような感じになる。src/main/javaも含めて総合的にこれがmavenの標準ディレクトリ構造。
- なお、依存関係(dependency)と親子関係(parent,module)は似て非なる概念なのでご注意。
- parentタグにrelativePathを指定して強制的にフラットなディレクトリ構造にしてしまう手法がよく取られる。これはEclipseの制約という歴史的な事情がある。
- IntelliJなど、設計思想の段階でビルドツールの存在を前提にしたIDEが台頭してきたおかげで、本来のmaven標準ディレクトリ構造を生かせるようになった。
- だからIntelliJ IDEA Ultimateを買う予算をちゃんと引き当ててください。(※実際、買うことになってる)
そろそろ風呂に入って寝たいのでこのへんで。明日はn_slenderさんによるPlayFramework 2.4 Java Ebeanでのアプリ開発です!お楽しみに!