名古屋Hackathonで学んだこと

mavenのローカルリポジトリに任意のjarを追加する方法

オレオレライブラリを作成した場合、それをmavenプロジェクトでどう使うのか、
というところを悩んでいたのですが、下記のサイトで解決。

Maven2のTipsを集めるWiki - CookBook

サードパーティのJarをインストールする

Mavenリポジトリで提供されていないサードパーティのJarをローカルリポジトリにインストールする。対象のJarをあらかじめダウンロードしておき、以下のコマンドを実行する。

mvn install:install-file -Dfile=jarまでの絶対パス -DgroupId= -DartifactId= \

  • Dversion=バージョン -Dpackaging=jar -DgeneratePom=true

例えば、C:\foo\hoge.jar をgroupId=hoge、artifactId=hoge、バージョン1.0としてインストールするには

mvn install:install-file -Dfile=C:\foo\hoge.jar -DgroupId=hoge -DartifactId=hoge \

  • Dversion=1.0 -Dpackaging=jar -DgeneratePom=true

と実行する。

これで好きなだけオレオレライブラリ生活をエンジョイできますな。

あと、作ったものは名古屋Scalaの下記のLiftプロジェクトに追加していたのだけど、
Bitbucketにauthorization errorのため、pushできなかったので公開はあきらめました。

yoshihiro503 / nagoyascala / source / — Bitbucket

java.net.URISyntaxException: Illegal character in path at index 18

scalateを試そうとしたところ、

mvn jetty:run

で下記のエラーが出ました。

[INFO] Starting jetty 7.1.5.v20100705 ...
2010-10-07 22:02:56.328:INFO::jetty-7.1.5.v20100705
2010-10-07 22:02:56.343:WARN::Failed startup of context JettyWebAppContext@14c02d4@14c02d4/,file:/E:/tools/development/Scala/scalate/scalate-distro-1.2-windows-bin/scalate-test/myArtifact/src/main/webapp/,file:/E:/tools/development/Scala/scalate/scalate-distro-1.2-windows-bin/scalate-test/myArtifact/src/main/webapp/
java.net.URISyntaxException: Illegal character in path at index 18: file:/C:/Documents and Settings/XXX/.m2/repository/org/mortbay/jetty/jetty-maven-plugin/7.1.5.v20100705/jetty-maven-plugin-7.1.5.v20100705.jar
at java.net.URI$Parser.fail(URI.java:2809)
at java.net.URI$Parser.checkChars(URI.java:2982)
at java.net.URI$Parser.parseHierarchical(URI.java:3066)
at java.net.URI$Parser.parse(URI.java:3014)
at java.net.URI.(URI.java:578)
at java.net.URL.toURI(URL.java:918)
at org.eclipse.jetty.webapp.WebInfConfiguration.preConfigure(WebInfConfiguration.java:81)
at org.mortbay.jetty.plugin.MavenWebInfConfiguration.preConfigure(MavenWebInfConfiguration.java:145)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:378)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:114)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
at org.eclipse.jetty.server.Server.doStart(Server.java:242)
at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:67)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:437)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:577)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
2010-10-07 22:02:56.437:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server

ちなみに環境はWindows XP SP3。
Apache Maven 2.2.1 (r801777; 2009-08-07 04:16:01+0900)
Java version: 1.6.0_14。


怪しそうな下記メッセージで検索。

java.net.URISyntaxException: Illegal character in path at index 18

でヒットしたのがこちら。

Re: java.net.URISyntaxException: Illegal character in path at index 18

Path to your maven repo (and therefore to your jar) has spaces
included, this might brake some things.

maven repo(jarを入れるところ)のパスにスペースが入っているよ、
何かおかしくなると思う。

とのこと。

で、こちらを見てrepoを修正。

Maven2 | plutoの日記 | スラド

setting.xmlのlocalRepositoryを下記のように書き換えました。

C:\hoge\repository

この場合、C:\hoge\repositoryにダウンロードしてきたライブラリが配置されます。


再度。

mvn jetty:run

で今度はエラーなくjettyが起動しました。

Scalatra on Google App Engine

Scalatra

Scalatraという、Rubyで言うところのSinatraにinspireされた軽量Webフレームワークがありまして。

それをGoogle App Engineに乗っけてみようと思い立ちましたとさ。

ググったらまずこちらがヒット。
Google グループ


上記リンクからこちらへ。
scala - How to use sbt with Google App Engine? - Stack Overflow

でこちらに。
HelloworldProject.scala · GitHub

Scalatra設定はこちらを参考。
ScalatraによるWebアプリケーション作成 - sbtを使った開発 - なんとなくな Developer のメモ


sbt環境の準備ができている前提で進めます。

sbtで雛形作製

mkdir helloworld
cd helloworld
sbt

内容を適当に入力。
scalaは2.8.0としておきます。

Plugin

{root}/project/plugins/Plugins.scala

を作成し、下記を入力。

import sbt._

class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
    val appenginePlugin = "net.stbbs.yasushi" % "sbt-appengine-plugin" % "2.0" from "http://github.com/downloads/Yasushi/sbt-appengine-plugin/sbt-appengine-plugin-2.0.jar"
}

Project

{root}/project/build/HelloworldProject.scala

を作成し、下記を入力。

import sbt._

class HelloworldProject(info: ProjectInfo) extends AppengineProject(info){
    val scalatraVersion = "2.0.0-SNAPSHOT"
    val scalatra = "org.scalatra" %% "scalatra" % scalatraVersion

    val servletapi = "javax.servlet" % "servlet-api" % "2.5"

    val scalaToolsSnapshots = "Scala Tools Repository" at "http://nexus.scala-tools.org/content/repositories/snapshots/"
    val sonatypeNexusSnapshots = "Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
    val sonatypeNexusReleases = "Sonatype Nexus Releases" at "https://oss.sonatype.org/content/repositories/releases"
    val fuseSourceSnapshots = "FuseSource Snapshot Repository" at "http://repo.fusesource.com/nexus/content/repositories/snapshots"

}

web.xml

{root}/src/main/webapp/WEB-INF/web.xml

を作成し、下記を入力。

<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
  <servlet>
    <servlet-name>helloworld</servlet-name>
    <servlet-class>com.rktm.HelloScalatra</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>helloworld</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

appengine-web.xml

{root}/src/main/webapp/WEB-INF/appengine-web.xml

を作成し、下記を入力。

<?xml version="1.0"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application>yourapplicationname</application>
  <version>1</version>
</appengine-web-app>

scalatra

{root}/src/main/scala/com/rktm/HelloScalatra.scala

を作成し、下記を入力。

package com.rktm
import org.scalatra.ScalatraServlet

class HelloScalatra extends ScalatraServlet {
    get("/") {
        "this is test."
    }

    get("/:foo") {
        val x = params("foo")
        "foo : " + x
    }
}

環境変数

APPENGINE_SDK_HOME

を設定しておきます。

sbtを起動

sbtを起動してupdate。
ごりごりいろんなものを落としてくるはず。

ローカルで確認

sbtにて

dev-appserver-start

でローカルサーバー起動。

http://localhost:8080/
にアクセスすると

this is test.

の文字が表示されます。

http://localhost:8080/xxx
にアクセスすると

foo : xxx

が表示されます。URLのxxxを変えると、表示される文言も変わります。

Google App Engine上にデプロイ

appcfg.sh update {root}/target/scala_2.8.0/webapp/

でGAE/J上にデプロイ。

今後

次はScalateを組み込みたいです。
その次はSlim3のデータストア機能で。

Scala 2.8 RC3でLift 2.0を動かす。


http://groups.google.com/group/liftweb/browse_thread/thread/59fd6a7726cd5382

に書かれている

mvn archetype:generate -U \
-DarchetypeGroupId=net.liftweb \
-DarchetypeArtifactId=lift-archetype-basic \
-DarchetypeVersion=2.0-scala280-SNAPSHOT \
-DarchetypeRepository=http://scala-tools.org/repo-snapshots \
-DremoteRepositories=http://scala-tools.org/repo-snapshots \
-DgroupId=$1 -DartifactId=$2

を($1、$2を変えて)実行したらサーバー起動まで行けた。

mavenあたりもちょっと勉強しないとつらくなってきたかも。

sbaz install scala-androidしたら、scalacが起動しなくなった件。

Androidscalaでかけないかなぁと色々やっているうちにscalacがエラーを吐くようになった。
下記のようなエラー。

Exception in thread "main" java.lang.VerifyError: (class: scala/tools/nsc/MainGenericRunner$, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

思い当たるところでは、scala-androidを入れるために、下記を実行してscala-androidをインストールしたぐらい。

sbaz install scala-android

上記でインストールされた
%SCALA_HOME%\lib\scala-android.jarをリネームしたところ、scalacが無事動くようになった。

環境は

sbazでインストールされるscala-androidが2.7.x系でビルドされたもののようで、
それが2.8系と合わないということですかねぇ。

かなり焦りました。

MANAGING THE DEVELOPMENT OF LARGE SOFTWARE SYSTEMSを英検4級がうとうとしながら訳す。

※いろいろな意味で途中です。



MANAGING THE DEVELOPMENT OF LARGE SOFTWARE SYSTEMS

大規模ソフトウェアシステム開発の管理。
Dr. Winston W. Rovce

導入
 これから、大規模ソフトウェア開発の管理について、個人的な見解を述べたいと思う。過去9年間、私は色々なアサインを経験した。
大部分は、宇宙船のミッションプランニング、コマンディング、ポストフライト分析だ。
これらのアサインメントでは、私は程度の異なる成功を体験した、実行可能な状態に、時間通りに、予算内で到達した。
私は経験により偏見を持つようになった。そして、この偏見を述べたいと思う。

コンピュータープログラムの開発機能
 規模や複雑度にかかわらず、全てのコンピュータープログラムの開発に共通する2つの本質的なステップがある。
まず初めに分析のステップがあり、続いてコーディングのステップが続く(図.1参照)。このある種簡単なコンセプトは、
実際のところ、努力が十分に小さく、最終的な製品がそれを作った人自身が使う場合には、十分だろう(内部で使うコンピュータープログラムでは普通だろう)。それはまた開発の努力の一種だ、ほとんどの顧客が喜んで支払うような、なぜならいずれのステップも
、最終製品の使い勝手に直接的に貢献する創造的な仕事である。しかしながら、大規模ソフトウェア開発に取り組むにあたり、これらのステップだけに注力するならば、失敗することになるだろう。多くの開発のステップが必要になるだろうが、それらは分析とコーディングほど最終製品には直接影響しないうえに、開発コストを要するだろう。顧客側はそういったものには支払いたくないだろうし、開発側はそれらを実施したくないだろう。管理の第一の機能は、これらのコンセプトを両方のグループに売り込み、開発側に服従を強いることだ。

 図1.内部で使用する小さなコンピュータプログラムを実現するステップ。


ソフトウェア開発におけるもっと雄大なアプローチを図2に示す。分析とコーディングステップは未だ図の中にあるが、それらは2つのレベルの要求分析に続き、プログラム設計ステップで分けられ、その後、テストのステップが続く。これらの追加物は、分析とコーディングとは区別される。ならぜならそれらが遂行される方法がまったく異なっているからだ。それらは計画されなければならない、プログラムリソースを最適化するために。
 図3は、この枠組みにおける継続的な開発フェーズにおけるイテレーティブな関係を示している。ステップの順番は、次のようなコンセプトにしたがっている。それぞれのステップが進行するに従い、設計はより詳細になり、先行する、または、後続するステップによるイテレーションがあるが、この流れにおけるリモートのステップというのは滅多にない。これによる美徳は、設計が変更プロセスの前に行われることは、管理可能な限界にスコープダウンされるということだ。要求分析の後の設計プロセスにおけるどの天においても、予見できない設計上の困難という出来事を引き起こすっようなベースラインが存在するということだ。我々が持っているものは、効果的なフォールバックポジションだ。それは、サルベージ可能で保存可能な初期の仕事を最大限拡張できる傾向にある。
 
 図.2 顧客に提供する大規模コンピュータプログラムの開発を実現するステップ。

 私はこのコンセプトを信じるが、前述した実現方法はリスキーであり、失敗を招くだろう。問題は図4に示した。開発サイクルの最後に発生するテスティングフェーズは、タイミング、ストレージ、I/Oトランスファーなど、分析では区別されないものを経験する初めてのイベントである。これらの現象は、正確には分析しづらいものである。それらは、例えば、数学的物理の***への解決ではない。それらの現象が色々な外部の制約を充足しない場合、大きな再設計が必要とされる。簡単なパッチや独立したコードのリドゥは、コードは、これらの問題を解決しないだろう。

続く。