独自ライブラリを参照する
2012/06/21追記しました。
追記 - 独自ライブラリを参照する - clash_m45の開発日記
sbtでセントラルリポジトリにないライブラリ(例えばoracle jdbcなど)をクラスパスに入れるのに一番簡単な方法は、アンマネージ依存性でできる。
http://scalajp.github.com/sbt-getting-started-guide-ja/library-dependencies/
できるんだけど、IntelliJ IDEAで見てくれなかった。
なにも設定しなくても見てくれていい気がするんだけどなぁ・・・
[How to add Jar libraries to an IntelliJ Idea SBT Scala project?]
http://stackoverflow.com/questions/3796004/how-to-add-jar-libraries-to-an-intellij-idea-sbt-scala-project
Answer : File - Project structure - Libraries
いや・・・うん、まぁそうなんだけどね・・・
※ちゃんとしたやり方があったら教えて下さい。
Maven Jar マニフェスト設定
Maven 3.0の参考サイトがないので書いてゆきます。
まぁ基本的には同じなんだけど。
まずはjar:jarのリファレンスから
http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html
org.apache.maven.plugins maven-jar-plugin 2.4 ココにいろいろ設定を書いていきます。
manifestタグには以下のページで詳細に記載されてます。
http://maven.apache.org/shared/maven-archiver/index.html
よく使う manifest 設定エレメント
- addClasspath
- classpathLayoutType
- classpathPrefix
- customClasspathLayout
- mainClass
ひとつずつ説明していきます。
Mavenで作るJarのファイル名を変更する
MavenでJarを作ると以下フォーマットで名前が作られる。
[artifactId]-[version].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
では、mavenのarchetype: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をじっくり学んだほうが良さそうですな。
おわり!