Mavenで作るJarのファイル名を変更する

MavenでJarを作ると以下フォーマットで名前が作られる。
[artifactId]-[version].jar

例えば、
com.hello
hello
1.0-SNAPSHOT
jar
というプロジェクトの場合、mvn packageを行うと、
hello-1.0-SNAPSHOT.jar が作成される。

このJarファイルの名前を変更したい場合は、pom.xmlに少し記述する必要がある。
■pom.xml

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <finalName>addon-hello</finalName>
        </configuration>
      </plugin>
    </plugins>
  </build>

これでmvn packageを実行すると、addon-hello.jarが作成される。

詳しくはリファレンスを参照するべし。
http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html

MavenでScalaプロジェクト

昔はarchetype:generateゴールに設定をいっぱいつけて、
archetypeCatalogをhttp://scala-tools.org/ってとこを見たりしたりで
ながーーーいコマンドを打つ必要があったみたい。

最近ではセントラルリポジトリにもscala-archetype-simpleのカタログが
入ってて、長いコマンド無しでscalaプロジェクトをはじめることができる。
http://search.maven.org/#search%7Cga%7C1%7Carchetype%20scala

では、mavenarchetype:generateでscalaプロジェクトの作成の仕方です。

「mvn archetype:generate」実行
ばばーっとセントラルリポジトリにあるカタログ一覧が現時点で603コも出てきて、
”Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): :”と表示されます。
つまり”番号選ぶ or フィルタして。”と言われているので、”scala”と打ってEnterします。
すると、現時点で、10コscala関連のカタログがヒットします。

1: remote -> com.github.igor-petruk.archetypes:maven-archetype-scala-executable (Creates executable Scala Project that is ready to run with 'java -jar')
2: remote -> de.schlichtherle:javafx-scala-demo (An archetype for a standalone JavaFX 2.0 application written in Scala.
The generated application is translated from the Colorful Circles demo from the JavaFX 2.0 SDK.)
3: remote -> org.apache.camel.archetypes:camel-archetype-scala (Creates a new Camel project using Scala DSL.)
4: remote -> org.fusesource.scalate.tooling:scalate-archetype-empty (An archetype which creates an empty Scalate web application)
5: remote -> org.fusesource.scalate.tooling:scalate-archetype-guice (An archetype which creates an empty Scalate Guice web application)
6: remote -> org.fusesource.scalate.tooling:scalate-archetype-jersey (An archetype which creates an empty Scalate web application)
7: remote -> org.fusesource.scalate.tooling:scalate-archetype-sitegen (An archetype which creates an empty Scalate static website generation project)
8: remote -> org.scala-tools.archetypes:scala-archetype-simple (The maven-scala-plugin is used for compiling/testing/running/documenting scala code in maven.)
9: remote -> org.wicketstuff.scala:wicket-scala-archetype (-)
10: remote -> org.wicketstuff.scala:wicketstuff-scala-archetype (Basic setup for a project that combines Scala and Wicket, depending on the Wicket-Scala project. Includes an example Specs test.)

あとは、一番シンプルな8番 scala-archetype-simple を選んであげればジェネレートしてくれます。
その後は普通のmvn archetype:generateと同じ。

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 8
Choose org.scala-tools.archetypes:scala-archetype-simple version:
1: 1.0
2: 1.1
3: 1.2
4: 1.3
Choose a number: 4:
Define value for property 'groupId': : com.hello
Define value for property 'artifactId': : helloworld
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  com.hello: :
Confirm properties configuration:
groupId: com.hello
artifactId: helloworld
version: 1.0-SNAPSHOT
package: com.hello
 Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: scala-archetype-simple:1.3
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.hello
[INFO] Parameter: artifactId, Value: helloworld
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.hello
[INFO] Parameter: packageInPathFormat, Value: com/hello
[INFO] Parameter: package, Value: com.hello
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.hello
[INFO] Parameter: artifactId, Value: helloworld
[INFO] project created from Archetype in dir: C:\workspace\helloworld
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9:55.996s
[INFO] Finished at: Thu Jun 14 16:53:31 JST 2012
[INFO] Final Memory: 8M/19M
[INFO] ------------------------------------------------------------------------

で、できたプロジェクトは以下のディレクトリ構成になります。

フォルダー パスの一覧
ボリューム シリアル番号は です
C:.
│  .gitignore
│  pom.xml
│
└─src
    ├─main
    │  └─scala
    │      └─com
    │          └─hello
    │                  App.scala
    │
    └─test
        └─scala
            └─samples
                    junit.scala
                    scalatest.scala
                    specs.scala

しかも良いことにpom.xmlには既にscalaの設定がされてる。
長いので一部だけ…。

  <build>
    <sourceDirectory>src/main/scala</sourceDirectory>
    <testSourceDirectory>src/test/scala</testSourceDirectory>
    <plugins>
      <plugin>
        <groupId>org.scala-tools</groupId>
        <artifactId>maven-scala-plugin</artifactId>
        <version>2.15.0</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>testCompile</goal>
            </goals>
            <configuration>
              <args>
                <arg>-make:transitive</arg>
                <arg>-dependencyfile</arg>
                <arg>${project.build.directory}/.scala_dependencies</arg>
              </args>
            </configuration>
          </execution>
        </executions>
      </plugin>

とかね、mavenにはscalaコンパイルとかするためにmaven-scala-pluginを利用するんだけど、
その設定(mvn compileでscalaコンパイルを動かす設定とか)が書かれてるのでかなり楽チンになった。

mvn compile とか mvn test とかで、最初からscalaを実行してくれます。

ということで、ぐぐると結構古い情報ばっかりだったので、記事にしてみました。
正直sbt(Simple Build Tool)とかgradleとかを調査してたんだけど、両方なんだかまだメンドクサイし、mavenで簡単にできないかなーと思ったら普通に簡単だったので素晴らしいですね。

まだまだmavenは使える!!

Mavenの使い方と、スキルとしての発展

ビルドツールとしての『Maven』。
そしてMavenをスキルとして昇華していく私なりのルートを
紹介したいと思います。


まずは『インストール』。
私は以下サイトさんをよく拝見させてもらってます。
他の記事も基本的なところから深いところまで記述されていてすごいです。
[ひしだまさんの技術メモ]
http://www.ne.jp/asahi/hishidama/home/tech/apache/maven/install.html

使い方
以下サイトで勉強しました。
[TECHSCORE]
http://www.techscore.com/tech/Java/ApacheJakarta/Maven/index/
Mavenのバージョン2を扱っていますが、基本的には同じなのでかなり勉強になります。

ここでだいたい理解したら、本家Mavenの"Learning about Maven"を眺めたり、
http://maven.apache.org/

プラグインについて知りたければ、本家Mavenのpluginページを眺めて、
「こんなGoalあるのね」とか「こんな設定もできたのか」とか面白くなってきます。
http://maven.apache.org/plugins/index.html


そして『発展』。

Mavenの恩恵を理解してきたところでもっとMavenの力を感じられる概念を学ぶと良いです。
それは「継続的インテグレーション(Continuous Integration:CI)」です。
Mavenは基本概念としてプロジェクトの「ライフサイクル」を管理するものですが、
ライフサイクルを利用して様々な恩恵を受けることができます。
その一部が"継続的インテグレーション"です。

継続的インテグレーションについてはいろいろなサイトで読むことができたり、
[オブラブ]さん
http://objectclub.jp/community/XP-jp/xp_relate/cont-j

私も購入して読みました。
継続的インテグレーション入門」という本があります。良書です。
[プログラマの思索]さんで紹介されてます。
http://forza.cocolog-nifty.com/blog/2011/09/post-b1d4.html


CIをするならCIツールである、Jenkinsを推します。Jenkins推しです。
日本人の川口さんが作ったものです。
[Jenkinsの生みの親が語る、継続的インテグレーションの未来]
http://www.atmarkit.co.jp/news/201106/06/jenkins.html

最近オライリーからもJenkins本が出ました。通称カエル本。
http://www.oreilly.co.jp/books/9784873115344/


ここまで来るとmojoも使うようなります。
mojoとはApacheプロジェクト外のpluginを扱う場所です。
http://mojo.codehaus.org/plugins.html
まぁカエル本読む前に既に使ってるかもしれませんが、
よく使われるのは、
・cobertura(コード・カバレッジ測定)
findbugs(静的ソース解析)
とかですか。


ここまで来ると社内でも固有のスキルを持つ人物として扱われだすように思います。
あとはMaven含め、継続的インテグレーションの『伝道師』(エヴァンジェリスト)として
積極的に活動していってください。

まだまだ開発やテスト、品質を軽視する現場は多いです。
そんな現場を変える力をMaven、CI、Jenkinsは持っているはずです。
それには仲間を増やさねばいけません。

ここを読んであなたも仲間になり、モダンな現場が増えればいいなと思います。

plyframework テンプレートに@inputHiddenってないの?

便利なplay framworkのタグ テンプレート。
http://www.playframework.org/documentation/2.0/ScalaTemplates

@inputTextでテキストボックスを作れる。
しかしtype hiddenのinputほしいなーとテンプレート探してみてもないみたい。

ぐぐってみたらやっぱり無くて、普通に

<input type="hidden" value="@hoge.id" name="id">

みたいにしろ、だとさ。

[Google-group] - play-framework
https://groups.google.com/forum/#!topic/play-framework/t4aeUiy1YpU
※見るにはgoogleアカウントが必要(グループには入らなくても見れる)


ちなみに、@inputTextとかはviews.html.helperパッケージ以下に存在してる。

anormでNULLを許容するテーブルをSelectする

scala初心者、playframeworkも初心者な私が触ってみてはまったことを解説していく。

playframeworkのチュートリアルをやってみて、ちょっと変更しようと思ったら「Null列がSelectできないでござる」とか言われてしまった。
チュートリアルhttp://www.playframework.org/documentation/2.0/ScalaTodoList

例えば、タスクの情報に"登録日"(createdate)と"締切日"(deadline)を追加したい

チュートリアルで作成した1.sqlを改良して、列を追加する。

# Tasks schema
# --- !Ups
CREATE SEQUENCE task_id_seq;
CREATE TABLE task (
  id integer NOT NULL DEFAULT nextval('task_id_seq'),
  label varchar(255),
  deadline date,
  createdate date DEFAULT sysdate
);
# --- !Downs
DROP TABLE task;
DROP SEQUENCE task_id_seq;

登録日はinsertした日でいいのでDEFAULT sysdate。

次にmodels/Task.scalaを修正。
case classの部分と、

case class Task(
    id: Long,
    label: String,
    deadline: Date,
    createdate: Date
)

val taskを変更。

val task ={
  get[Long]("id") ~
  get[String]("label") ~
  get[Date]("deadline") ~
  get[Date]("createdate") map {
    case id~label~deadline~createdate =>
      Task(id,label,deadline,createdate)
  }
}

val taskってのはSQLの結果をパースするParserを変数にしている。
チュートリアルでは、SQL("select * from task").as(task *) と書いている。


そしてviewも変更する。
チュートリアルをちょっと変更してtableでタスク一覧を表示する。
index.scala.html

@(tasks: List[Task], taskForm: Form[String])

@import helper._

@main("Todo List") {

  <h1>@tasks.size task(s)</h1>

  <table border="1">
      <tr>
        <td>ID</td>
        <td>タスク</td>
        <td>締切日</td>
        <td>登録日</td>
      </tr>
      @tasks.map { task =>
        <tr>
          <td>@task.id</td>
          <td>@task.label</td>
          <td>@task.deadline</td>
          <td>@task.createdate</td>
          <td>
          @form(routes.Application.deleteTask(task.id)) {
            <input type="submit" value="Delete">
          }
          </td>
        </tr>
      }
    </table>
  <h2>Add a new task</h2>
  @form(routes.Application.newTask) {
    @inputText(taskForm("label"))
    <input type="submit" value="Create">
  }
}

これでタスクを登録してみると・・・

insertは成功して、再表示のTask.all()メソッドでエラーです。
[RuntimeException: UnexpectedNullableFound(TASK.DEADLINE)]
deadlineがNULLなので型が解析できないようです。

Optionを使ってNULLを許容できるようにしてあげます。

case class Task(
    id: Long,
    label: String,
    deadline: Option[Date],
    createdate: Date
)

object Task {
  val task ={
    get[Long]("id") ~
    get[String]("label") ~
    get[Option[Date]]("deadline") ~
    get[Date]("createdate") map {
      case id~label~deadline~createdate =>
        Task(id,label,deadline,createdate)
    }
  }
〜〜〜

これでおっけー!

こう見ると単純で簡単なんだけど、scala初心者には
SQLParserってなにこれどう動くのとか、case classにもOption必要なの?とか
ハマりどころだったわけです。


まずはScalaをじっくり学んだほうが良さそうですな。

おわり!

怒らないこと

もう1年以上前に、「怒りを押さえる or 阻止するにはどうしたらいいんだろうか」ということを真剣に考えたことがあった。
つまり、どうでもいいことで怒って気分を悪くしてしまうことをそろそろ避けたいと考えた訳だ。
例えば、満員電車でいらいらするとか、ちょっとした言葉のニュアンスで不満を持つだとか、昔あった嫌なことを思い出しては壁パンするとか、そういうことがもう嫌になったな、と考えた。

とりあえず、これは哲学の世界に近そうだ、と考えた。*1
しかし感情を扱う哲学はそう多くは無いような気がしたし、哲学は膨大なので探すのが大変だと感じた。

そこで思いついたのは儒教、仏教などの「教え」はヒントにならないか、ということだった。
私は以前からwikipediaで宗教に関する由来や考え方を読むことはたまにあったし仏教の「他力本願」という言葉が好きだったりもした。

とりあえず駅の本屋へ向かった。
私は「日本人の考え方は儒教に似ている」とどこかで読んで鵜呑みにしていたため、儒教の本を探した。
しかしあまりたいした本は見つからず(研究結果のような本はいくつかあったが)その場で見つけた仏教の本をターゲットにした。
最初に開いたのは電車の広告でみた本だったが、ほかの本も開いてみた。
その中でこれだ!と思ったのが、まんまタイトル怒らないこと著:スリランカ初期仏教長老 アルボムッレ・スマナサーラ700円)だった。
書いた人は全然しらないが、目次にあった「他人が吐いたゴミを食べる必要はない」というところが気に入った。
その頃何度も感じていた言葉だったからだ。

読んでみてわかったがこの本には、

  • 「怒り」とは何か
  • その定義は
  • 「怒るのは当たり前だ」への反証
  • 怒りによる自己の破壊
  • 怒らないとはどういうことか
  • 怒りの治め方
  • 怒りと幸福の関係

・・・など私が読みたかった事柄がほぼ書かれていた。

いろいろと書かれていることを紹介したいが、それに興味がある人には読んでもらった方が早いと思うので、先に書いた「他人が吐いたゴミを食べる必要はない」の部分だけ書き出そうと思う。

怒りは雪だるま式に大きくなるので、だいたい怒っている人は、怒って怒って、もうたまらない状態になっているのです。
怒りを自分でなくせない人間は、自分の心に怒りの毒が生まれたら、そのエネルギーを外に出さなくてはいけません。ですから、怒っている人は、そのためにしゃべっているだけなのです。こちらとしてはたいへん迷惑ですが、聞いている側に悪いところはありません。
能力のない上司が有能な部下をけなしているとします。そういう場合は、けなされているほうの部下が、心の中で「この人は歳も取っていて、能力もない。それで自分のことが心配で悩んでいて、そのストレスを発散しているんだ。だから、その状態から救い出してあげよう。」と思いながら、その人の話を聞けばいいのです。
話は聞いてあげても、相手の怒りを感情的に引き受けて気落ちする必要はまったくありません。その人は、自分のからだに溜まったゴミを外に出しているだけなのですから、わざわざ自分がゴミ箱になる必要はありません。
怒っている人の状態は、何かひどいものを食べておなかを壊して吐いているのと同じなのです。その人の言葉や行動は溜まっている毒を出しているだけですから、きれいになって落ち着くまで、思う存分出させてあげましょう。「あの人が吐いたものを食べて、私までおなかを壊す必要はない」という態度でよいのです。
たとえ、もとがどんなに美味しいものであっても、食べて吐いたものを拾ってまた食べるというのは無理でしょう?怒りもそういうものなのです。怒る人々というのは、自分がまず怒った上で、さらに人を怒らせようとしています。からだに悪いものを食べてそれを吐き、誰かに食べさせようとしているのと同じ状態なのです。
ですから、そんなものを拾って食べてはいけません。まわりの人が怒って話しているのにつられて自分も怒るということは、「腐ったものを食べた人が吐いたものを、拾って食べているようなものだ」と肝に銘じておきましょう。けっして受け入れてはならないのです。心をそういう状態にまで育てられれば、相手の怒りに対する怒りなど、なんのことはなく即座に消えてしまいます。

書いてみると意外に大変だった・・・読むと2ページにしかならないんだけどね。
この部分はだいぶ最後の方なのでここで、上司を救い出そう、としている部分は相手の怒りを見通した上での行動、ということになるんだと思っている。

ちなみにこれらのことを自分なりに少しづつ意識して考えるようになってきたと思う。
最近は満員電車で疲れることはあっても怒りを持つことはなくなってきたし、悪い思い出もすぐに吹き消すように努力している。
それなりにでも「気の持ちよう」というものは変わるもので、仕事上でも怒りを含めることは少なくなったと勝手に思っている。

最後に、この本が一番伝えたい言葉は、「怒る人ほど頭が悪いという真理」・「怒らない人ほど智慧を持つ」だとおもっている。

同じような悩みを持つ人は自分だけで考えないで、知識を拾ってから考えたら良いと思う。
この話はおしまい。

*1:精神科という方向もあったかもしれないが、自分の中で上記事柄は「願望」であったため、「治療」であると認識している精神医療への意識は消えていた。

Cygwin上でgemを使おうとすると、"No such file or directory"

久しぶりに投稿。

RubyにはRubyGems(コマンド名:gem)っていうrubyのアプリケーションやライブラリを管理できるツールがある。
それをCygwin上で利用した時に以下エラーになる場合がある。

$ gem --help
C:\Ruby193\bin\ruby.exe: No such file or directory -- /cygdrive/c/Ruby193/bin/gem (LoadError)

恐らくrubyからはwinパスでアクセスしたいけどcygwinunixパスでやろうとするから変だーって感じなんじゃね。

手っ取り早く解決するならば、aliasを設定しちゃうと上手くいく。

alias gem='C:/Ruby193/bin/gem'

まぁgemでいろいろアプリ入れるたびにalias設定してやらないといけないから結構面倒なんだけどね。