jruby on railsでwarblerを使ってJava EE Serverにデプロイするときcreateだけができなくなる現象について

14 07 2011

jruby on railsでwarblerを使ってJava EE Serverにデプロイするときcreateだけができなくなる現象について

何が起こったか

WEBrickサーバーでは正常にcreateできるが、jruby on railsをwarblerを使ってJava EEサーバー(自分の場合はglassfish)にデプロイしたときに、突然createだけができなくなってしまった。(正確にはcontroller/にリダイレクトされてしまい、それ以外のupdate等は正常動作する)。

原因

publicにコントローラーと同名フォルダがあった場合に発生する。glassfishの場合postするとコントローラーではなくpublicの同名フォルダに優先的に誘導してしまうためである。(WEBrickではコントローラー優先)。

解決法

createだけを別名にするか、publicの同名フォルダを別名に変えると言った方法が有効である。(ひょっとするとglassfish等の設定であったりする気もしないわけでもないがこれは、自分は調べてはいない。これは読者に任せる)

広告




jruby on rails3 + JavaEE Server + WindowsでUnknown Error(20047)

2 01 2011

JavaEE Server(tomcatしかりglassfishしかり)でUnknown Error

サーバーログが以下の通り

2011/01/02 13:52:35 org.apache.catalina.core.ApplicationContext log
致命的: Application Error
org.jruby.rack.RackInitializationException: Unknown error – Unknown Error (20047) – C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\dosaf\WEB-INF\classpath:
    from classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:217:in `mkdir_p’
    from classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:215:in `reverse_each’
    from classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:215:in `mkdir_p’
    from classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:201:in `each’
    from classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:201:in `mkdir_p’
    from C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:259:in `configure_gem_home_and_path’
    from C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:72:in `configure’
    from C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:126:in `definition’
     … 9 levels…
    from classpath:/vendor/rack-1.2.1/rack/builder.rb:46:in `initialize’
    from <script>:2:in `new’
    from <script>:2

    at org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:183)
    at org.jruby.rack.DefaultRackApplicationFactory.getApplication(DefaultRackApplicationFactory.java:60)
    at org.jruby.rack.PoolingRackApplicationFactory.getApplication(PoolingRackApplicationFactory.java:94)
    at org.jruby.rack.DefaultRackDispatcher.process(DefaultRackDispatcher.java:28)
    at org.jruby.rack.RackFilter.doFilter(RackFilter.java:63)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:242)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:402)
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:310)
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:575)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1555)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.jruby.exceptions.RaiseException: Unknown error – Unknown Error (20047) – C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\dosaf\WEB-INF\classpath:
    at (unknown).new(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:243)
    at FileUtils.fu_mkdir(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:217)
    at FileUtils.mkdir_p(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:215)
    at Array.reverse_each(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:215)
    at FileUtils.mkdir_p(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:201)
    at Array.each(classpath:/META-INF/jruby.home/lib/ruby/1.8/fileutils.rb:201)
    at FileUtils.mkdir_p(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:259)
    at #<Class:01x359ad71f>.configure_gem_home_and_path(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:72)
    at #<Class:01x359ad71f>.configure(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:126)
    at #<Class:01x359ad71f>.definition(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:116)
    at #<Class:01x359ad71f>.load(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:100)
    at #<Class:01x359ad71f>.setup(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/config/boot.rb:8)
    at (unknown).(unknown)(C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps/dosaf/WEB-INF/config/boot.rb:165)
    at Kernel.require(classpath:/jruby/rack/rails.rb:165)
    at JRuby::Rack::RailsBooter::Rails3Environment.load_environment(classpath:/jruby/rack/rails.rb:173)
    at JRuby::Rack::RailsBooter::Rails3Environment.to_app(classpath:/jruby/rack/rails.rb:194)
    at #<Class:01x4a30db6d>.new(<script>:2)
    at (unknown).(unknown)(classpath:/vendor/rack-1.2.1/rack/builder.rb:46)
    at Kernel.instance_eval(classpath:/vendor/rack-1.2.1/rack/builder.rb:46)
    at Kernel.instance_eval(classpath:/vendor/rack-1.2.1/rack/builder.rb:46)
    at Rack::Builder.initialize(<script>:2)
    at (unknown).new(<script>:2)
    at (unknown).(unknown)(:1)

対処法

WEB-INF/gems/gems/bundler-1.0.7/lib/bundler.rb:259の
FileUtils.mkdir_p bundle_path.to_sをコメントアウトする

※ただし、この対処法はあんまり検証してないので注意。たぶん問題はないと思うけれど。





プログラミング言語の用途や傾向についてのまとめ

16 01 2010

プログラミング言語の用途や傾向についてのまとめ

自分の利用する主なプログラミング言語について、主に自分の感じた範囲で用途や傾向についてまとめてみたいと思う。

本音を言えばブログをあまりに放置しすぎているのでどうにかしなければというのが実際のところなので内容についてある程度ぐだぐだ感があるのは大目にみてもらいたい。

プログラミング言語の大まかな分類

プログラミング言語の大まかな性向についてリスト形式で分類する。

  • 医療、宇宙工学等非常に少ないバグでシステムを作らなければならないものに適合するもの
    これに適合するという点でまず思いつくのがAdaである。これの言語が大きく参考にしている言語はPascalだがこの言語も、昔は特に実行効率の観点から非常に悪評があったものだが、少ないバグで作れるよういろいろな文法があった。このような言語では、非常に強い型付け(数値の範囲チェックや型適合検査が言語レベルでサポートされている)や高いモジュール性(Pascalはそうでもない。そもそも元々が教育目的であったために標準では分割コンパイルすら存在しない。)が確保される。言語の記法でも、書きやすさより読みやすさや保守を優先とする記法であり、1機能あたりの人的コストがかかるものの、こういった分野では非常に有効なものである。
  • 主に基幹システムなど大きなシステムだが、ある程度のバグは許容され、その代わりに経済性が求められるものに適合するもの
    こういった言語はいろいろある。有名なのはJavaだろう。C#などの.net系もそうである。特に最近のこういう部類の言語は非常に標準ライブラリも多く、複雑な機能をより簡単に作成できるようになってきているのが現状であると思う。少なからず一般的な基幹システム向けに言語自体が設計されており、Adaみたいにがちがちに型付けをせず、プログラマに書きやすいようになってあるのが普通と思われる。
  • 簡単なツール等簡単にある程度のことができる言語 バグは基本的に許容される
    PerlやRuby、JavascriptやActionScriptなどもそうだろう。言語文法には、実現する機能に対し、書くコード量が短くなるように設計され、基本的に読んだり、保守には目を向けられない。(ただしPythonやRuby、ActionScript3などはある程度読みやすさも追求されており必ずしもそうとはいえない状況である。特にActionScript3はほぼJava似の文法を採用しており、ある程度の大規模開発にも向いているのではと思っている。)おそらく、VBやDelphiもこの中に入るだろう。こういった言語はプログラマーのお供として比較的、プログラマーが短期的には楽できるという言語である。長期的に言えば保守の問題等そうでもなくなってくる。
  • 主に研究向けであり(少なくとも現状では)あまり実用的でない言語
    LispやScheme、Prolog、Haskellなどがそうであろう。主に、手続き型やオブジェクト指向ではない、関数型、論理型プログラミング言語であればほぼこの中に入ってくるだろう。しかし、実務をこなすプログラマが学ばなくてもいいかといわれればそうでもない。プログラマらしい理論的な考え方を身につけること。また、手続き型では解きにくい問題であってもこのような言語では説きやすいという問題も存在する。こういった言語を学ぶことは後々、プログラミングスタイルに大きな影響を与えると思う。
  • ある分野に特化している言語
    HTML、スタイルシート、SQL、Luaなどある問題を解決するために作成された言語がここに当てはまる。こういった言語は、ある特定分野のみに対し、非常に高能力な解決法を提供する。こういった言語を知ってるのと知らないのでは天と地の差が出やすい。そういった分野を学習するなら当然覚えておくべき言語である。

それぞれの分類について

プログラミング言語の分類について、それぞれ個人的な感想を述べたり、いろいろな言及をしていく。

医療、宇宙工学等非常に少ないバグでシステムを作らなければならないものに適合するもの

特にこういった分野の言語で触れたことのある言語はAdaのみなので、Adaに絞って感想を述べていきたいと思う。

こういった言語は、ソースコードのコンパイルレベルでも相当のバグがとれるように設計されており、逆に言えば、それだけの情報をソースコードに含んでいるとも言う。ソースコードに人為的ミスが入りにくいように設計され、その分言語規約も複雑になっている。コンパイルだけでも通すことができれば相当量のバグがとれるようになっているのだが、逆に、通すまでに非常に多くの難関を突破しなければならない。慣れればそういったコンパイルまでの苦労はある程度軽くなるのかもしれない。しかし、コンパイルできない。つまり、動くものが出力されないというものはプログラマにとってある程度の精神的負担になりやすく、そういったところで、先ほど述べた経済性と共にあまり一般的には好まれない言語なのかもしれない。

また、これはAdaのみに限ったことだが、多くのプログラマが親しんだC言語ライクな文法ではなくPascalライクな文法を採用している。確かにこれはこれで読みやすいが、多くのプログラマにとっては敬遠される要素になってるのではないかと自分は思う。そして、Adaのできた当時としては非常に先進的な言語過ぎた。1985年に初めての標準規格が制定されたが、Adaの新しい文法は今やJavaにも普通にある総称プログラミング、パッケージ概念などはここからきている。コンパイラの問題も大きくそういった普及当初の点でも失敗しているところが多いと思う。

ただ、自分の好みからするとこういった試みのなされたプログラム言語は実用言語としてはすばらしいと思う。現代のシステム構築にかかる問題を言語面からアプローチして行ってると私は思う。あくまで、この言語はコンパイル時点で相当数のバグとれるよう言語設計時点でいろいろな制約を課してあるが、Javaにも同じことはできないわけではない。現状では強い型付け等は一般的にあり、それをうまく用いればAdaにある制限はほとんどはJavaにも適用しようとすればできると思う。いかに強固なプログラムを作るか。そういった方法論を学ぶという意味では良いお手本になると思し、実際にこういった言語を使い強固なプログラムを作れることは、システムバグが取り上げられる現状からして考えると重要になると思う。

主に基幹システムなど大きなシステムだが、ある程度のバグは許容され、その代わりに経済性が求められるものに適合するもの

こういった言語は良くも悪くもありきたりな言語が多いと思う。しかし、こういった言語にはいろいろなリソースが集まりやすく、プログラムを作るときにはいろいろ扱いやすいと言うこともあり、少なからずこういった言語は1言語は学んでおきたい言語だと思う。その中の1つでも学んでおけば、ほかはある程度つぶしがきくような感じではある。無論、ある程度の差は当然存在するので、利用する必要があるときには、そういったことは学んでおかなければならないだろう。

こういった言語の特徴は、ほとんどの場合C言語ライクな文法を用い、プログラマにソースコードの善し悪しに関する判断をある程度任せてはいるものの、基本的にシステム構築上の障害としかなり得ないものに関しては除外している。また、ある程度学習もしやすいようになってあるということである。そいういうことで、ある程度プログラムの型が決まっており、ありきたりということなのである。

ただ、こういった言語は、はやり廃りがある程度あると思われる。言ってしまえば、BasicやCが一般的にこういったシステムを作成するために使われていた、(今も使われているが)一般的なシステムの発注元が別の言語を要求すれば別の言語に変わると思うし、そういった点では常に追っていかねばならない言語の分類と思う。

簡単なツール等簡単にある程度のことができる言語

こういった言語は、非常に短い表現で、非常に高度な動作を要求するが、基本的にエラー対処はしないといった用途に向いた言語である。一般的にプログラムの中のほとんどのコードはエラー処理という状況なので、本当に実行したい正常ケースはごく短いコードであったりする。特に簡単なツールを作りたいときにはこういった言語は重宝する。ただ、JavascriptやActionscriptも含めたがこれは特定の分野に特化した言語でもあるので、少し微妙な立ち位置であり、簡単なツール作りと必ずしも関連しないことはあるが、どちらにしろかなりライトの言語ではある。

こういった言語はいろいろな記法をサポートしており、望めば関数型プログラミングライクなことや、コマンドプロンプトでやるようなことをこれらの言語上でやれたりする。そういった点ではいろいろなプログラマがそれぞれのやり方でやれるといった、自由度の高い言語がほとんどである。使う分には非常に簡単に使い始めることができるが、任意に使える要素が大量にあるため、言語全体として結局は非常に複雑になっており、書きやすいが読みにくくソースコード自体は非常に保守しにくいものとなっている。

特にPerl、Python、Ruby(私はRubyかPythonをおすすめするが)から1つの言語はできた方がいいと思う。あることをしたいときに作業効率がぐんとあがることが多いからだ。また、この機会にコマンドプロンプトの使い方につい勉強をしておくことをおすすめする。Perl等これらの言語は、Linuxのコマンドプロンプトに当たるものから一部言語要素を拝借してきている。その中にはコマンドプロンプトでも変わらず使えるものがあり、またそれは非常に便利なので是非覚えてほしい。これらができるようになればちょっとしたことでも圧倒的な作業能率の違いができるだろう。

余談だが、表計算処理ソフトも非常に適用範囲の広いソフトなので、是非使い方を覚えよう。提出書類の作成だけではなく、ちょっとした計算や集計などでは非常に高い威力を発揮するものである。

主に研究向けであり(少なくとも現状では)あまり実用的でない言語

主に関数、論理型言語をあげるが、その記法においては非常に独特なものがあり、日常的に使われている言語からすれば全くの別物ではある。しかし、その言語に利用されている理論は現実のプログラムにおいて非常に実用的、もしくは将来的な見通しにおいて実用的なものも多い。少なくとも、コンピューター科学から出た理論が現実の実用的な言語にも適用されており、その理論を学ぶことは非常に有用なことである。特にデータ構造などは理論を知りよく扱えるようになればプログラム効率はかなり上がるようになるだろう。また、関数型なら高階関数のような考え方や、再帰的な関数のような非常に強力なプログラミング要素に親しむことができる。

ただ、最大の問題は基本的にこういったものはわかりやすい本がなかったりして、導入部分でくじけやすいという問題がある。コンピューター科学と非常に結びつきが強く実務では直接利用されることはないと言うことが非常に高い影響を持っているのだろうが非常にもったいないとは私は思う。

ある分野に特化している言語

この分野に属している言語は、ある分野に対して非常に強い能力を持っているがそれを外れると使い物にならないか、あまり意味をなさない言語である。しかし、ある分野に対し特化している言語はそれを解決するためだけなら非常に強いパワーを持つ。自分のやりたいことを簡単に書くことができるのだ。また、この分野はそれぞれの言語に基本的にそれぞれの特色があり、必ずしも我々が親しんでいるような言語とはにてもにつかないものが多い。また、あるツール等にべったりくっついていたりすることも多く、リソースもたまりにくいことがある。(まあそもそもリソースの蓄積があまり必要とされないこともある)簡単に自分の考えたことを成果物にすることができるのは非常に魅力的だろう。

ただ、こういった言語は将来的にどうなるか予想がつかない言語が多いので、こういった言語に執着しすぎるのもあまり良くないと思う。少なからず、こういった言語とは利用するが、利用されないことが必要になると思う。

最後に

自分の偏見も多分に含んで話してきたが、いかがだろうか。言語もプログラマーの一つのツールであり、それ以上でもそれ以外でもないが、古くから主要な地位を占めてきているものではある。ある違う分野の言語を使えばプログラマーとして視野が大きく広がるだろうが、それは言語だけでなくツールにもいえる。なので、言語ばかりに執着するのはいいとはいえない。言語がある程度できる。ということであれば、周りのツールたとえばデバッガー、プロファイラ、バグトラッキングシステム、バージョン管理システムといったものにも視点を当ててみることをおすすめする。そうでないなら、言語を学ぶことは非常にいい案であると思う。