ikeike443のブログ

ソフトウェアビジネスに関心がある系のブログ

Jenkins + Maven3.2.1 で IllegalAccessError on AbstractMapBasedMultimap

メモ。時間があるときに調べる。
Maven3.2.1とJenkins1.581のCoreとで依存しているGuavaのバージョンが違っていることが遠因になっていくつかのプラグインが動かなくなっている。(下記参照)
[#JENKINS-22252] Maven 3.2.1: IllegalAccessError on AbstractMapBasedMultimap - Jenkins JIRA

JenkinsでMavenプロジェクトを作って静的解析をしていて下記のようなエラーが出ていたらこの問題に該当すると思って良さそう。PMD, CheckStyle, FindBugs全て同じ。静的解析以外でも問題が起きそうだけど、今のところ聞いてない。

java.io.IOException: Remote call on channel failed
	at hudson.remoting.Channel.call(Channel.java:748)
	at hudson.remoting.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:168)
	at com.sun.proxy.$Proxy7.execute(Unknown Source)
	at hudson.maven.MavenBuildProxy$Filter.execute(MavenBuildProxy.java:206)
	at hudson.plugins.analysis.core.HealthAwareReporter.registerResultsOnMaster(HealthAwareReporter.java:325)
	at hudson.plugins.analysis.core.HealthAwareReporter.postExecute(HealthAwareReporter.java:316)
	at hudson.maven.Maven3Builder$MavenExecutionListener.recordMojoEnded(Maven3Builder.java:628)
	at hudson.maven.Maven3Builder$MavenExecutionListener.mojoSucceeded(Maven3Builder.java:610)
	at hudson.maven.Maven3Builder$JenkinsEventSpy.onEvent(Maven3Builder.java:306)
	...
Caused by: java.lang.LinkageError: Failed to load com.google.common.collect.AbstractMapBasedMultimap
	at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:326)
	at hudson.remoting.RemoteClassLoader.findClass(RemoteClassLoader.java:236)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at hudson.remoting.MultiClassLoaderSerializer$Input.resolveClass(MultiClassLoaderSerializer.java:113)
	... 
Caused by: java.lang.IllegalAccessError: class com.google.common.collect.AbstractMapBasedMultimap cannot access its superclass com.google.common.collect.AbstractMultimap
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
	at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:322)
	... 39 more

Workaroundとしては、Mavenプロジェクトをやめてフリースタイルプロジェクトで作るか、Mavenのバージョンを3.0.5くらいまで落とせば一応動く。細かいバージョンの組み合わせは試してないが、まあ3.0.5まで落とせば大丈夫っぽい、という程度の理解をしている。

これ結構直すのは面倒そうだなあ。JenkinsのGuavaバージョンをあげるのか、各プラグイン側でWorkaroundな修正を入れるのか。。

#DevLOVE 関西でお話させていただきました

進め、現場のチーム開発 〜チーム開発実践入門〜 (DevLOVE関西Ver) - DevLOVE関西 | Doorkeeper におよびいただき、チーム開発についてお話させていただきました。恐縮です。ちなみに場所ははてなさんにご提供いただきました。ありがとうございます!

以前東京で行った 池田尚史氏に聞くチーム開発の極意 ~「進め,現場のチーム開発 ~チーム開発実践入門」レポート:レポート|gihyo.jp … 技術評論社 の時の講演内容に事例を加えて少しラップアップを足したものです。


僕の発表の後、みんなでディスカッションを行いました。いろんな開発現場の方のいろんなケースを伺えて面白かったです。

台風が来ていたので勉強会は早めに切り上げ、近くの居酒屋で16時から飲んでおりました。。(恒例)

はてな新社長(!)の栗栖さんともご挨拶させていただき、一緒に串かつを頬張りました。

ステッカー欲しいな、って言ったらくれました! 言ってみるもんだ!


mackerel(https://mackerel.io/)、チョー気になる。使ってみたい。

#DevLOVE でお話させて頂きました

さる6月19日(木)、DevLOVEさんのイベントにお呼ばれして少しおはなしをしてきました。
進め、現場のチーム開発 〜チーム開発実践入門〜


資料は下記になります。


かんたんに本の紹介と、チーム開発にまつわるあれこれをお話させていただいたあと、会場の皆さんとディスカッションをしました。

来場された皆さんに聞いてみた印象としては、バージョン管理、チケット管理は行なっている現場が多いようでしたが、CIについてはほとんどやっていない、ユーザー受け入れテストの自動化についてはほとんど誰もやっていない、という傾向のようでした。

発表でも話しましたが、開発ツールをどう使うか、というのはプロジェクトを改善するための数ある手段のうちのごくごく一部ですし、必須のものでもありません。ツールを使うことが目的化してしまうことは避けないといけません。

とはいえ、最低限のレベルというのはあると思っていて、バージョン管理をする、チケット管理をする、CIをする、というところについては、ほぼ全ての現場において必須のプラクティスだと思いますし、拙著を参考にしていただけるといいなあと思いました。

なかには一切のソフトウェアダウンロードを禁じられているとか、15分毎に強制的にネットワークが遮断される環境にいるとか、チーム開発の改善どころの話ではない現場の方もいたようでした。

ここまでひどい閉鎖空間になってしまうと、どう言ったらいいか正直私にもわかりません。。それでその会社の業務が本当に成り立っているのならいいのかもしれませんが。。

そういう現場において、いかに改善のための予算取りをするか、稟議を通すか、あるいはダマでこっそりツール導入や改善を進めて既成事実を作りに行くか、みたいなところは本書には入れられてないのですが、いずれ別の機会にでも、語る場を持てればなあと思っています。

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

Play2 Scala + jacoco4sbt + jenkins でカバレッジを取る

Play2 Scalaで作ったプロジェクトをJenkins上で自動テストするのは簡単。フリースタイルジョブで作ってシェルの実行のところに下記のように書いてやれば普通に動く。JUnitスタイルのXMLを吐いてくれるので、テスト結果をJenkins上で綺麗に整形してみることができる。

play clean
play test


でもカバレッジとなると話は別で、Play1の時のようにCoberturaプラグインが用意されてるわけでもなく、上手い方法があるのかどうかよく分からない。

でもって、Scalaカバレッジ計測ができるツールないかなと探してたんだけど、メンテが止まってるのが数個見つかったくらいでいいのがなかった、んだけど、一個いい感じのを見つけた。

jacoco4sbt

https://bitbucket.org/jmhofer/jacoco4sbt/wiki/Home
jacocoの for sbt ということで、sbtプラグインとして書かれている。そこそこメンテもされてるよう。

jacoco4sbtをPlayで動かそう

そのままだと上手く動かないんだけど、下記の記事を参考にすると何とかなる。
http://ronalleva.com/2012/04/25/jacoco-and-play.html

記事の内容としては、jacocoというかsbtはデフォルトだとテストを並列に実行してしまう、けどもPlayは並列実行の設定をオフにしているため、jacocoだけ並列に動こうとして上手くいかないけどどうしたらいいのか、ってもの。

これを見ると、jacoco4sbtをPlayと共存させるための設定方法がよく分かる。(っていうかPeter Hausel*1に聞いた、って記事中にあるね。。)

詳しくは記事を見ればわかると思うけど、参考までに最終的に僕の設定がどうなったかを書いておく。

Build.scala
import sbt._
import Keys._
import PlayProject._
import de.johoop.jacoco4sbt.JacocoPlugin._
import de.johoop.jacoco4sbt.XMLReport
import de.johoop.jacoco4sbt.HTMLReport

object ApplicationBuild extends Build {

  val appName = "Hoge"
  val appVersion = "1.0-SNAPSHOT"

  lazy val s = Defaults.defaultSettings ++ Seq(jacoco.settings:_*)

  val appDependencies = Seq(
    // Add your project dependencies here,
  )

  val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA, settings = s ).settings( 
    // Add your own project settings here
    // for jacoco
    parallelExecution in jacoco.Config := false,
    jacoco.reportFormats in jacoco.Config := Seq(XMLReport("utf-8"), HTMLReport("utf-8")),
    jacoco.outputDirectory in jacoco.Config := new File("target/coverage/")

    )

}


Build.scalaに上記のように書いてやれば、jacocoに対していろいろ設定できる。jacoco.settingsをsに追記してやって、そのsをPlayProjectの引数として渡してるね。こんなことできるんだ。。

ここでは記事と同じく parallelExecutionをオフにしたほか、カバレッジレポートのスタイルをXMLとHTMLの2本立てにして*2、レポートの出力先をtarget/coverage/に変更した。

plugins.sbt
// Comment to get more information during initialization
logLevel := Level.Warn

// The Typesafe repository 
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

// Use the Play sbt plugin for Play projects
addSbtPlugin("play" % "sbt-plugin" % "2.0.3")


// jacoco
resolvers += "Sonatype" at "https://oss.sonatype.org/content/groups/scala-tools/"

libraryDependencies ++= Seq(
  "org.jacoco" % "org.jacoco.core" % "0.5.9.201207300726" artifacts(Artifact("org.jacoco.core", "jar", "jar")),
  "org.jacoco" % "org.jacoco.report" % "0.5.9.201207300726" artifacts(Artifact("org.jacoco.report", "jar", "jar"))
)

addSbtPlugin("de.johoop" % "jacoco4sbt" % "1.2.3")

plugins.sbtに、上記のようにjacoco4sdbtの設定を追記。バージョンはこのブログを書いている時点のものなので、適当に読み替えてほしい。


それから、jacocoが吐き出すXMLをJenkinsに解釈させるために、Jenkinsのjacoco Pluginも入れた。

Jenkinsではシェルの実行に下記のような記述をした。

play test
play jacoco:cover

ちなみに、running(TestServer(xxx))を使ってHTTPスタックのテストを書いてカバレッジをとろうとすると上手くいかない。これは今調査中。


Enjoy!

Jenkins

Jenkins

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

*1:Playのコミッターの一人。

*2:jenkinsに読ませるにはXMLにしてやる必要がある

The JenkinsPluginTotallySimpelGuideの翻訳(意訳) #jenkinsja

Jenkinsの公式Wikiに、The JenkinsPluginTotallySimpelGuideという、Jenkinsプラグイン開発入門に良さげな記事があったので、取り急ぎ翻訳してみました。

かなり適当に意訳しました。
下記に公開しておくのでご参考程度に。
https://www.evernote.com/shard/s18/sh/ca603adc-3200-45e3-aac2-6244fe8ae400/69be9f6c1a773383136e48cfd33440cc

※後ほどJenkins日本語Wikiに転載します

Hudson plugin for Playframwork を書いた

練習がてら、 Hudson のプラグインを書いてみました。

Play むけのプラグインなんて、ほとんど需要無さそうですが、Hudson の ML に投げたら受け入れてもらえたりするんでしょうか??

とりあえず、コードは下記に置いてあります。
https://github.com/ikeike443/HudsonPluginForPlay

出来ること

  • Play auto-test コマンドを実行できます
  • テスト結果を Calimoucho 風*1に閲覧することが出来ます

使い方

プラグインをインストールしたら*2、「Hudsonの管理>システム設定」の下記箇所に Play スクリプトの格納場所を記述します。
f:id:ikeike443:20110125020738p:image


次に、「新規ジョブ作成>フリースタイルプロジェクト」でジョブを作成し、下記2箇所を設定します。

1.「ビルド手順の追加」で 「Play!」を選択し、"auto-test" と設定します。
f:id:ikeike443:20110125020506p:image


2.「ビルド後の処理」で「Play! auto-test reports」にチェックを入れます。
f:id:ikeike443:20110125020508p:image


これで設定は完了です*3。ビルド実行してください。
f:id:ikeike443:20110125020740p:image


ビルドが完了すると、サイドパネルに下記のように Play! のアイコンとともに Play! Test Result というメニューが出現します。
f:id:ikeike443:20110125020509p:image

Calimoucho 風のテスト結果

テスト結果を Calimoucho 風に参照できます。Test runner の画面にも似ています。
f:id:ikeike443:20110125020739p:image


一つ一つのボックスがテストクラスになっています。クリックすると詳細を確認できます。
f:id:ikeike443:20110125022914p:image


Play の auto-test には Selenium がビルトイン*4されています。Selenium のテスト結果も下記のように確認できます。
f:id:ikeike443:20110125020511p:image


テストが失敗した場合、失敗したテストクラスが赤く表示されます。
f:id:ikeike443:20110125020510p:image


クリックすると詳細を見ることが出来ます。
f:id:ikeike443:20110125020512p:image


テストに失敗した場合、ビルドも失敗するようになっています。


と、ここまでが僕の書いたプラグインの機能です。

まとめ?

まとめ、っていっても、ただプラグイン書きましたってだけのブログなのであれですが。。

一応、このプラグインと Cobertura や Ivy などを組み合わせると、そこそこ CI 環境として整うかと思います。

Play! の CI 事情については、また日を改めて書きたいなと思います。

で、ぶっちゃけ、このプラグインって需要あるんでしょうか。。

追記

Hudson の ML に投稿してみたところ、 Hudson の Plugin Developer というものにしていただきました。
これがどういうものなのかまだよくわかってませんが、キャッチアップしてみたいと思います。
おそらく、程なくして Hudson のプラグイン管理画面からダウンロード出来るようになると思います。

追記2

先程Hudson改めJenkinsのアップデートセンターを確認したところ、play-pluginの名で登録されたようです。お使いのHudson改めJenkinsのプラグイン管理画面からインストールできると思います。
これからWikiなどを充実させていきます。

*1:Play の [http://integration.playframework.org/:title=CI Server] は Calimoucho という名前のようです。コードは[https://github.com/guillaumebort/calimoucho:title=ここ]にあります。

*2:Hudsonのリポジトリには置いていないので手動でインストールして下さい。

*3:特に書いていませんが、ソースコードをSCMから取得する設定ももちろんしてください。

*4: Htmlunit を使ってブラウザレスで実行できるので結構便利です。

Hudson勉強会行ってきました

Hudsonの生みの親、元Sunの川口さんが来日されるということで、Hudson勉強会に参加してきました。


当日はうちのQA(@magnet88jp)が発表してたので、その応援も兼ねて。
うちのQAのスライドは下記です。(Embedの仕方がよくわからん。。)
https://docs.google.com/present/view?id=d9tpj8h_31gf5xggs6
反復開発やってる、毎月リリースしてる、そのためのテスト自動化にHudson使ってる、っていう、割と普通な事例だと思ってたのですが、Twitterや懇親会では割と好評価をいただいたみたいです。


懇親会もたくさんの方が来ていましたね。Twitterでよく見る方々とお話できて楽しかったです。
当日、id:ikikkoさんから懇親会代金の運搬を頼まれてビビりましたがw 
持ち逃げしようかと思いましたが、グッとこらえて会場までもって行きました。たぶん試されたんだと思います。


当日のスライドとか、Togetterのまとめとかは下記からたどっていくのが一番まとまっていていいと思います。
http://wiki.hudson-ci.org/pages/viewpage.action?pageId=46336352



LTでは下記が会場の爆笑を誘っていました。関西の方のようで、センスがさすがです。


27秒で終わる合コンって、乾杯もできないじゃん。。