以下は元々Fablic在籍時の2016-12-07に会社の技術ブログinFablicに投稿した記事(http://in.fablic.co.jp/entry/2016/12/07/115501)でした。inFablicが閉鎖されてしまったため、会社の了承を取った上で転載しております。元記事にリンクを貼っていただいていた方に対しては大変お手数なのですが、こちらにリンクし直していただければ幸いです。Androidエンジニアの黒川(@hydrakecat)です。本日は、Androidのライブラリにパッチを当てた話をしたいと思います。先日、Picassoという画像ライブラリのバグにより、弊社のフリルで一部のユーザーさんに問題が発生しました。この記事では、その問題を解決するために、なぜパッチを当てることにしたのか、どのように行ったのか、どういう問題があったのか、という話をいたします。PRにするか、手元でパッチを当てるかOSSのライブラリを使う際に、よく挙げられるメリットとして「いざとなったらソースコードを読んで修正できる」というものがあります。これは真なのですが、実際に修正をして、自分のプロダクトに適用しようとすると意外に大変です。レポジトリをフォークして、開発環境を整えなければなりません。次に、修正を作ります。最後にPRにして投げる、あるいは手元でパッチを当ててビルドをするかを選ばなければなりません。前者の場合は(自分がコントリビュータになれるという魅力は措いておいて)正式に採用されれば今後もメンテナンスされることが保証されています。オーナーを含む多くの人がレビューしてくれることで、品質もある程度保証されるでしょう。一方で、手元でパッチを当てた場合は、たいてい本家に入った変更への追随が問題になります。乖離が発生する可能性もありますし、品質という意味でも不安が残ります。どのようなときに手元でパッチを当てることになるでしょうか。それは、本家がいつまで経ってもリリースしてくれなさそうなときです。Picassoは、最後のリリース2.5.2が行われたのが2015年3月で、すでに1半年以上も新しいバージョンが出ていません。開発が止まっているかというと、そんなことはなく、バージョン2.6.0として多くの変更が入っているのですが、まだ2.6.0のリリーススケジュールは決まっていないようです*1。該当の問題はすでに修正され2.6.0のブランチにマージされていたため、2.6.0では直ることがほぼ確実となっています。そこで、私たちは、本家をフォークしたレポジトリで修正を作り、2.6.0がリリースされるまでは、こちらでビルドしたものを使うことにしました。差分は最小限にして正式リリースを待つ作戦です。ちなみに、ここでは修正した問題の詳細については触れませんが、興味のある方は、こちらのissueとPRをご覧ください。起きるというものです。開発環境の構築まず、レポジトリをフォークし、開発環境を構築します。フォークしたものが、こちらになります。Picassoは2.5.2現在ではMavenビルドを採用しているため、Mavenベースのプロジェクトを作成する必要があります。Studioを使いつつMavenプロジェクトを同時に使うのは至難の技です。いうか、1日格闘したけれど無理でした。ここでは2.6.0がGradle移行していたのに目を付け、Gradle移行の変更を引っ張ってくることでGradle移行させました。自分がGradleに慣れているというのもありますが、Mavenに慣れていないならGradleにしておく方が余計な時間を取られることがないかもしれません。修正のマージ今回は修正は自分で作成したものではないため、内容を読み込み、理解しておく必要があります。なにか問題が発生したら自分で直さなければなりません。修正であり、それほど難しい修正でもなかったので、この部分は難なく済みました。UTが通ることを確認して、手元で問題が直っていることを確認したら完了です。修正したライブラリを利用するタイミングで2つの選択肢があります。Dependency)として指定する方法。Dependency)として利用する方法です。今回は、社内の他のプロジェクトでも利用するかもしれないこと、修正や履歴の管理が容易なこと、他に利用したい人がいるかもしれないこと、の3点からGitHubで公開して利用する形にしました。次にプロジェクトをGradleの外部モジュールとして利用するために、公開する必要があります。いくつか方法はありますが、ここでは最も手軽なJitPackを利用します。JitPackは、Gradleプラグインを設定すれば簡単にプロジェクトをライブラリとして公開できるサービスです。詳細な利用方法は他に譲りますが、手順としては以下だけで済みます。自分のライブラリを指定すれば完了です。}ここで、いくつかTipsがあります。1つは、タグを作成する前の状態でライブラリを利用したい場合、タグではなくコミットハッシュを指定できるというものです。クリックすることでも調べることができます。用いれば、常に最新のコミットのものが使われます。詳しくはドキュメントを参照してください。1つのTipは、プライベートレポジトリでもJitPackは利用可能ということです。こちらは試していないのですが、ドキュメントによればアクセストークンを使うことで可能となるようです。以上で終わりでしょうか?運が良ければ、終わりですが、運が悪ければ、アプリのビルド時にエラーが出るかもしれません。1つの可能性は、アプリが依存している別のライブラリがパッチを当てた元のライブラリに依存している場合です。いう依存が発生している場合です。ライブラリPとは異なります。従ってライブラリAの依存先としてP'だけでなく元のライブラリPもダウンロードされ、クラスの衝突が起こるのです。依存しているために発生しました。具体的には、以下のようなエラーが出ました。[picasso-2.5.2.jar:com/squareup/picasso/Action$RequestWeakReference.class]))この場合、一番手っ取り早い解決策は、ライブラリAの依存からライブラリPを除いてしまうことです。書くことで実現できます。バージョンがそれほど乖離していないことは確認しましょう。下手をするとランタイムエラーが発生してしまいます。}以上で、パッチを当てたライブラリが使えるようになります。自分のアプリで問題が直っていることを確認して、いざリリースをしましょう。おわりにこの記事では、Picassoを例に、OSSのライブラリにパッチを当てて運用するにはどうしたら良いか紹介しました。Picassoのようにリリース間隔が長くなってしまったライブラリの場合は、必要とする修正がなかなか取り込まれずヤキモキすることがあります。そのような場合は、必要に応じてフォークすることも選択肢の1つとなってきます。コードベースがあまりに乖離するとメンテナンスに苦労するため、積極的に推奨できる方法ではありません。各自で行う場合はご注意ください。振り返る2016年2016年がもうすぐ終わってしまう。移行ガイドArchiveはてなブログをはじめよう!hydrakecatさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。