コンピュータやソフトウェアのあれこれ@道民(&元道民)
Posts tagged all
MTPlugin-Starterを使ってみる
2月 6th
「Movable Typeプラグイン開発入門」のChapter 9に載っている、
MTPlugin-Starterを使ってみます。
「Movable Typeプラグイン開発入門」
ラトルズ シックス・アパート株式会社/監修 関根元和/著
まず、「MTPlugin-Starter」で検索してダウンロードをしてきます。
解凍すると分かるんですけど、”mt-plugin-start.pl”があるだけ。
そして、それを使うには、いくつかPerlモジュールを入れる必要があるようです。
$ cpanm YAML $ cpanm Template
これで、準備完了。
お次は、こんな感じ。
$ perl mt-plugin-start.pl
あとは、対話式に設定して、書き出すだけ。
これは便利!
それぞれの項目は、本をちゃんと読みましょうということで。
おしまい。
settingsActivityのメモ
2月 5th
settingsActivityを使ってみたので、
設定を伴わないライブ壁紙からの差分ということでメモ。
いつものライブ壁紙のコードを改良していきます。
まずは、ファイルの先頭に。
import android.content.SharedPreferences;
次に、設定の保存先を定義。
public class LifeGameWallpaper extends WallpaperService {
// 他のアプリとかぶらないようなのを使用する
public static final String SHARED_PREFS_NAME = "your.domain.preferencesName";
// 以下は、今まで通り
次に、ライブ壁紙エンジンのクラスに、
設定値の変更イベントを受け取るためのインターフェイスを追加。
class LifeGameWallpaperEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener {
// 今回は、この値を変更できるようにする
private final long _drawInterval = 1000 / 8; // 描画間隔
// ここは今まで通り
// 以下を追加
private SharedPreferences _prefs;
コンストラクタの中で、初回設定値読み出し。
_prefs = LifeGameWallpaper.this.getSharedPreferences( SHARED_PREFS_NAME, 0 ); _prefs.registerOnSharedPreferenceChangeListener( this ); onSharedPreferenceChanged( _prefs, null )
onSharedPreferenceChangedという関数を追加
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if ( sharedPreferences.getBoolean("speed", false) ) {
_drawInterval = 1000 / 16; // Hi-Speed mode
}
else {
_drawInterval = 1000 / 8;
}
}
“speed”はどっから出て来たかというと、
設定画面のXML(“lifegame_settings.xml”)として、以下を用意する。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="speed"
android:title="Hi-Speed mode"
android:summary="on: 16fps, off: 8fps"/>
</PreferenceScreen>
設定値は、”android:key=”に指定したキーを通じて取得できる。
ちなみに、今回は”AndroidManifest.xml”に以下の記述を追加している。
場所は、”application”タグ囲まれた、”service”タグの直後に同じインデントで追加。
<activity
android:label="@string/lifegame_settings"
android:name=".LifeGameWallpaperSettings"
android:theme="@android:style/Theme.Light.WallpaperSettings"
android:exported="true">
</activity>
“strings.xml”に、
<string name="lifegame_settings">(設定画面のタイトル)</string>
の追加もお忘れなく。
あとは肝心の設定用Activityのソースですが、
公式サイトの”src”フォルダの中を漁ると出てきます。
おしまい。
これはYAPC効果?
2月 3rd
最近、ひしひしと感じている。
なので、書き残しておこうと思う。
思えばいろいろあったので、振り返ってみる。
Hokkaido.pmの発足
すべてはここから始まった。
いわゆるキックオフミーティングから。
はじめてのLT
これも鮮明に覚えてる、すごい緊張したことを。
この時からYAPCを意識し始める。
正確には、YAPCの存在を知った。
LDD’10/Fall in KUSHIRO
LOCALさんと、ちゃんと交流したのはこの辺りだと思う。
そして、OSC 2011 Hokkaidoに繋がった。
そして、月日は流れ・・・
LTハッカソンとか、MTハッカソンとか、MT勉強会に、Hokkaido.pmがあって、
会う人、会う人に影響を受けて・・・。
YAPC::Asia 2011 Tokyo
ここで凄いショックを受けた。
うまく表現できないけど、雑に表現すると、
「もっと関わりたい欲」が出て来た。
そして調子に乗って、自分にも何か出来るんじゃないかって思い上がって。
結果的に、こうやってブログを書いてる。
そして、現在に至る
何か変わったのだろうか?
変わったんだとしたら、Perlを覚えたいとか、
いつかWebサービス始めたいとか、MovableTypeを使いこなしたいとか。
どれも、今の仕事とは関係ないことばかり。
そして、何より寂しくない。
こういうのは、多分、PerlとかYAPCに限った話じゃなくて、
ただ、自分の場合は、書籍だったりネットの記事がすべてだった訳で、
もちろん、仕事ではMSDNにお世話になった訳だけども、
そういった本の著者だったり、記事を書いた方に会ったりっていうのは、
憧れのあの人に会うのに等しくて、テンションが上がる訳で。
それに、YAPCで何かしゃべるという夢も叶ったし、
次の目標だったり、夢も出来たりして、欲も出て来たので、
どっかで踏ん切り付けて、ステップアップしたいと思う。
どういう形であれ、もっともっと貢献できるようにがんばりたい。
おしまい。
SSLのwebページにPOSTしても値が渡らなくなった話
2月 2nd
やあやあ。お仕事の山がひと段落して昼寝していたら怒涛の不機嫌な電話で叩き起こされた僕様ですよ。こんにちは。
SSLのwebページでフォームの値をPOSTで取得しようとしても値が取れないという謎事象。ついでにCSSが取れない、と。検索してもあまり情報当たらなかったから、メモだけ書いておきます。同じことで困った人いたら参考になれば。
環境
- apache 1.3.41 mod_ssl 2.8.31-1.3.41 openssl-0.9.8b
- 色々事情があって上げられないのです察してください
事象
- chrome/IE8 SSLのページでPOSTしてもPOST値が渡らない
- firefoxは大丈夫
- POSTリクエストの直後のGETリクエストが失敗する。apacheのerror_logを見ると、次のようになっている。
Invalid method in request hoge=&fuga=&…. GET /css/nantoka_base.css HTTP/1.1
推察
- この例だと、CSSにPOSTリクエストのパラメタを渡そうとしてしまっているが、CSSファイルはPOSTパラメタなんて受けないので、invalid methodと言ってる気がする(httpd.conf次第だけど)
- 原因はSSLの脆弱性対応でブラウザの動作が変わったこと。POSTデータの投げ方が変わった。このリクエストは受けられない方が標準から外れている。参考リンク
- httpsでバウンダリ文字列が分割されてpostされる (google groups forum)
- https ではじまる Plesk にログインできません。 (google groups forum)
- 通信を保護する「SSL/TLS」の脆弱性を突いたhttps攻撃、研究者が発表へ (セキュリティーホールmemo)
- MS12-006 SSL/TLS の脆弱性のちょっと詳しい解説 (Microsoft 日本のセキュリティチーム)
- たぶんこの、分割してPOSTっていうのに対応できてない。splitting とか fragment とか、その辺がキーワードっぽい。
対策
- chromeのフォーラムにあった「chrome に –
disable-ssl-false- startを付けて起動」を試してみたところ、期待通りの動作になったので、この問題で間違いなさそう - 可能ならApacheとかopensslとかその辺を新しくしちゃえばいい気がする
- やんごとなき理由により出来ない場合(だった)、Microsoftさんの記事の対策が僕の場合は参考になった
- サーバー側で RC4 を優先するよう設定する (Windows Server 2008, Windows Server 2008 R2)
- TLS 1.1 を使用する
- 今回はIE6を捨てられないので RC4のみを使えるようにapacheを設定したところ回避できた。以下のブラウザとりあえずOKぽい
- chrome 16.0.192.77
- IE 8.0.7601.17514
- Fx 3.6.16
- IE 6.0.2900.5512.xpsp_sp3_gdr.080814-1236 (@WindowsXP)
謎のメモ
[root@hagehgae conf]# openssl ciphers -v 'ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM:-SSLv2:!AES:!3DES' DHE-DSS-RC4-SHA SSLv3 Kx=DH Au=DSS Enc=RC4(128) Mac=SHA1 KRB5-RC4-MD5 SSLv3 Kx=KRB5 Au=KRB5 Enc=RC4(128) Mac=MD5 KRB5-RC4-SHA SSLv3 Kx=KRB5 Au=KRB5 Enc=RC4(128) Mac=SHA1 RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1 RC4-MD5 SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=MD5SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM:-SSLv2:!AES:!3DES
ほか
- たぶん Lotus Notes も同じ対策ぽい
- みんな困ってない?こんな古いの使ってないって話かな
- もし誰かの役に立てばということでまあご容赦を.
- てか、とりあえずのワークアラウンドとしてはこれでいいと思うんですが、抜本的対策法(ARCFOURに絞らない)をご存じの方いらっしゃったら教えてください。
[java][scala]Scalaの空括弧とUnit
2月 2nd
Unit周りでハマったのでメモ。
まず、() => Any という型はあるが、()という型はない。
scala> def id(x: () => Int): () => Int = x
id: (x: () => Int)() => Int
scala> def id(x: ()): () = x
<console>:1: error: '=>' expected but ')' found.
def id(x: ()): () = x
^
Unit型の唯一の要素が()である。
scala> ().isInstanceOf[Unit]
res67: Boolean = true
() => Any は Unit => Any とは違う。
// 型が違って代入できない scala> val emptyParentheses: () => Any = { () => 10 } emptyParentheses: () => Any = <function0> scala> val unit: Unit => Any = emptyParentheses <console>:17: error: type mismatch; found : () => Any required: Unit => Any val unit: Unit => Any = emptyParentheses ^ // 型が違って代入できない scala> val unit: Unit => Any = {(u: Unit) => 20} unit: Unit => Any = <function1> scala> val emptyParentheses: () => Any = unit <console>:17: error: type mismatch; found : Unit => Any required: () => Any val emptyParentheses: () => Any = unit ^
が、Unit => Any は空括弧で呼び出すことができる。
scala> def one(u: Unit): Int = 1 one: (u: Unit)Int scala> one(()) res68: Int = 1 // これ、なんでエラーにならないのかわからず (Value Discardingから??) scala> one() res69: Int = 1 scala> one <console>:18: error: missing arguments for method one in object $iw; follow this method with `_' if you want to treat it as a partially applied function one ^ // これは、要請がUnit型なら{ e; () }に変換するルール(Value Discarding)より scala> one("DUMMYYY") res71: Int = 1 // これもValue Discarding から?? scala> one(1, "XXX", Nil) res72: Int = 1
[scala][java]Scalaのvalとvarとdef
2月 2nd
valは定数、varは変数、defはコード、というのが大まかな理解になる。これらは名前空間を共有しているので、定数、変数、コードに同じ名前をつけることはできない。ただし、JSやPythonのように単純にフィールドにメソッドオブジェクトが入っていると思うとハマる部分があるので、その辺を含めて調べたことをメモ。(なお、このエントリは 2.9.1.final での挙動について書いている。)
クラス定義のvar、def、val はメソッド
valとvarはfinal付き、final無しの変数として解釈されると思われるが、クラスのフィールドとして定義した場合にはJVM上ではメソッド経由でアクセスすることになる。ので、abstract defをvarやvalでオーバーライド*1したりできる。
class ValVarDef { val x = 1 var y = 2 def z = 3 }
% javap -private ValVarDef public class ValVarDef extends java.lang.Object implements scala.ScalaObject{ private final int x; private int y; public int x(); public int y(); public void y_$eq(int); public int z(); public ValVarDef(); }
メソッドと関数型のフィールドは違う
JSなどと違い、def hoge(x: String): Int (メソッド)とdef hoge: String => Int (関数オブジェクトのフィールド)はまったく違うもの。
// 名前付き引数で呼べる scala> def hoge(x: String): Int = x.length hoge: (x: String)Int scala> hoge("abcde") // ←一見同じ振る舞いをするように見える res140: Int = 5 scala> hoge(x = "abcde") res141: Int = 5 // 名前付き引数で呼べない scala> def hoge: String => Int = x => x.length hoge: String => Int scala> hoge("abcde") // ←一見同じ振る舞いをするように見える res142: Int = 5 scala> hoge(x = "abcde") <console>:11: error: reassignment to val hoge(x = "abcde") ^ // 引数には自動的に名前がつく (コメント欄参照) scala> hoge(v1 = "abcde") res3: Int = 5
JVMのレベルで見ると、前者はメソッドに直接処理を記述したもので、後者は処理を記述されたFunctionNオブジェクト(ここでは MyTest$$anonfun$hoge2$1)を返すメソッドになる。
class MyTest { def hoge1(x: String): Int = x.length def hoge2: String => Int = x => x.length }
public class MyTest extends java.lang.Object implements scala.ScalaObject{ public int hoge1(java.lang.String); public scala.Function1 hoge2(); public MyTest(); } public final class MyTest$$anonfun$hoge2$1 extends scala.runtime.AbstractFunction1 implements scala.Serializable{ public static final long serialVersionUID; public static {}; public final int apply(java.lang.String); public final java.lang.Object apply(java.lang.Object); public MyTest$$anonfun$hoge2$1(MyTest); }
defの定義で、引数なしと空括弧は微妙に違う
def hoge = 1 と def hoge() = 1 は振る舞いが微妙に違う。特に関数オブジェクトが入っている場合。
scala> def func1 = (_: Int) + 1 func1: Int => Int scala> def func2() = (_: Int) + 1 func2: ()Int => Int // 引数無しで定義すると"func1()"では呼び出せない scala> func1 res136: Int => Int = <function1> scala> func1() <console>:9: error: not enough arguments for method apply: (v1: Int)Int in trait Function1. Unspecified value parameter v1. func1() ^ // 空括弧で定義すると"func2()"でも"func2"でも呼び出せる scala> func2 res138: Int => Int = <function1> scala> func2() res139: Int => Int = <function1> // func1は括弧付きで呼び出せないので、意図したように解釈される scala> func1(5) res131: Int = 6 // func2を5を引数として呼び出したと解釈されるため、エラーとなる scala> func2(5) <console>:9: error: too many arguments for method func2: ()Int => Int func2(5) ^ scala> func2()(5) res135: Int = 6
=> はJVM上では関数オブジェクト
まあそうだよね。
class MyTest { def hoge1(x: Int) = x + 1 def hoge2(x: => Int) = x + 1 def hoge3(x: () => Int) = x() + 1 }
public class MyTest extends java.lang.Object implements scala.ScalaObject{ public int hoge1(int); public int hoge2(scala.Function0); public int hoge3(scala.Function0); public MyTest(); }
lazy val はJVM上ではメソッドとして定義される
まあそうだよね。
class MyClass { def hoge1: Int = { val x = 1 lazy val y = 1 x + y } def hoge2: Int = { val x = 1 lazy val y = 1 x + y } }
public class MyClass extends java.lang.Object implements scala.ScalaObject{ public int hoge1(); Code: ..略.. 24: invokespecial #21; //Method y$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileIntRef;)I ..略.. 27: iadd 28: ireturn public int hoge2(); private final int y$1(scala.runtime.IntRef, scala.runtime.VolatileIntRef); private final int y$2(scala.runtime.IntRef, scala.runtime.VolatileIntRef); public MyClass(); }
objectはstatic
objectはシングルトンオブジェクトを定義するものだが、JVM上ではstaticとして解釈される互換性のためstaticメソッドも用意される。
class MyTest { val inClass = 1 }
object MyTest { val inObject = 2 }
% javap MyTest MyTest$ public class MyTest extends java.lang.Object implements scala.ScalaObject{ public static final int inObject(); public int inClass(); public MyTest(); } public final class MyTest$ extends java.lang.Object implements scala.ScalaObject{ public static final MyTest$ MODULE$; public static {}; public int inObject(); }
*1:コメント欄も参照
mavenで実行可能なjarファイルと依存ライブラリを含めたzipアーカイブを作成する
2月 2nd
以下の条件を満たすアーカイブを作成したいなーという状況が発生したときのmaven設定を忘れないように残しておく。
- コマンドから java -jar で実行可能なエントリーポイントを含むjarを作る
- 上記jarで必要なライブラリ類を同包したアーカイブを作る
外部に依存することなくエントリーポイントからの処理を実行する事が目的。
使用するプラグインは maven-jar-plugin と maven-assembly-plugin。
maven-jar-plugin
jarファイルのManifestファイルを設定することができる。
Manifestファイルを作成しておくことで、メインクラス(-jarで実行する際のエントリーポイント)を指定することができる。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>sample.hoge.Main</mainClass>
<addClasspath>true</addClasspath>
<addExtensions>false</addExtensions>
<classpathPrefix></classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
mainClass: メインクラスをフルパスで
addClasspath: pom.xml の dependenciesをクラスパスとしてマニフェストファイルに出力するか否か
addExtensions: pom.xml の dependenciesの拡張情報もマニフェストファイルに出力するか否か
classpathPrefix: addClasspathがtrueの場合にクラスパスにつける接頭語(lib/とかext/とか)
maven-assembly-plugin
配布用のアーカイブを作成するためのプラグイン。
必要なライブラリのjarも含めたアーカイブを作成するように設定すれば、外部に依存しない完結したアーカイブファイルを作成できる。
<pom.xml>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>batchfile/hogetarou</finalName>
</configuration>
<executions>
<execution>
<id>make-sample-batch-zip</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
finalName: 出力するファイル名 targetディレクトリからの相対パスになる。
executionタブでの設定は packageフェーズに assembly:single の実行を含むための設定です。
こうしておけば、mvn assembly:single を直接実行しなくても、mvn package 実行時にアーカイブができる。
デフォルトのアーカイブ形式は以下。
- bin: バイナリ配布用のアーカイブ
- jar-with-dependencies: プロジェクトと依存するライブラリをまとめた 1 つの JAR ファイル
- src: ソース配布用のアーカイブ
今回実現したい事は、jar-with-dependencies 形式を指定すれば実現できそうなのだけど、親モジュールとの関係で独自形式でアセンブリの設定をすることに。
依存関係の断ち切り方を時間内で発見する事ができなかったのです(assembly-plugin を使う場合、アセンブリファイルの配置が必須になってしまっていた)。※
独自形式でアセンブリの設定をする場合は pom.xml の他にアセンブリ記述子を配置する必要があります。
アセンブリ記述子はデフォルトで src/main/assembly 配下に置くことになっています。
<executable.xml>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>sample</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
<outputDirectory>output/</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
output というディレクトリ内にdependencyとMainのjarを含めたzipファイルを作成しますよ、という設定。
上記を設定で maven package を実行すると
- target/batchfile/hogetarou.zip ができている
- hogetarou.zipをunzipするとoutputというディレクトリが展開される
- outputのなかにはMainのjarと依存ライブラリのjarが同列に格納されている
- java -jar [Mainのjar] でプログラムが実行される状態になっている
と、なりました。
この記事がとても良くまとまっていて、自分が作成した方法以外も勉強になりました。
Sacrificed & Exploited – Mavenで配布用zipファイルを作成する
http://d.hatena.ne.jp/cnaos/20100102/1262430319
今後、m※の部分をなんとかできそうだったら、なんとかしてみたいと思います。時間があれば。
その他、四苦八苦している際に参考にさせてもらったサイト
ありがとうございました。
http://www.in-vitro.jp/blog/index.cgi/Maven/20060215_01.htm
リモート接続が切れてもプログラムの実行を続ける nohup
2月 1st
未来の自分へ。
リモート接続しているサーバー上でバッチジョブを実行する際に、
$ java -jar batch.jar &
と、ただジョブをバックグラウンド処理にするだけではssh接続が切れる or ログアウトするとジョブが終了してしまう。
nohupコマンドを使うと、ジョブをプロセスとして管理することができるので、ログアウト後も処理が続行する。
$ nohup java -jar batch.jar &
コマンドを実行したディレクトリに nohup.out ファイルが作成され、処理中に出力されたメッセージは全てnohup.out に書き込まれる。
nohup.outは追記型なので、同じプログラムを複数実行する場合(テスト中など)は、実行前にnohup.outを消す/移動させるなど対応しておいたほうがよい。
nohupを忘れて時間のかかる処理を実行すると、接続切れないから身動きが取れなくなる(経験談)ので注意する。
コマンドの前にバックスラッシュをつけるとエイリアスを無効にできる
2月 1st
きっといつかまたはまるので、未来の自分に向けて残しておく。
あるデータをフォルダごと上書きコピーする必要があった。
$ cp -rp soure target
バックグラウンド処理にしたいから上書き確認を無視(強制上書き)するために -f オプションを付ける
$ cp -rfp source target
しかし、上書き確認が消えない。
CentOS系のOSの場合、エイリアス設定で -i オプションが付いているらしい。
確認
$ alias alias cp='cp -i'
以下のように書くといいとたくさんのサイトに書いてあった。
$ \cp -rfp source target
できた、できたけど、なぜなのか。気持ち悪いので理由を調べる。
\(バックスラッシュ)をつけてコマンドを実行するとエイリアスを一時的に無効にできるんですね。
しらなかったー、しらなかったー。
参考にしたサイト
http://jehupc.exblog.jp/13355017/
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/214dsblalas.html
CentOSにRubyOnRailsを導入したときにハマったところまとめ
2月 1st
達人出版会から出ている「はじめる!Rails3」を読みはじめました。
基本的に開発はMacで行うのだけど、自鯖があるので環境構築だけでもやってみようと挑戦したところいろいろハマりました。(よって今日は眠い)
環境
CentOS release 5.7 (Final)
ruby 1.9.3p0 (2011-10-30 revision 33570) [i686-linux](rvm使用)
ここに「はじめる!Rails3」通りにサンプルが実行できるよう環境を整えていきました。
sqlite
サンプルアプリ用のDBインストールでいきなり躓く。
$ sudo yum install sqlite3-devel Loaded plugins: priorities, security 144 packages excluded due to repository priority protections Setting up Install Process No package sqlite3-devel available. Nothing to do
・・・ない。
sqliteはあるけど、sqlite3はいない。
SQLite/Rubyライブラリにはsqlite3.6.16以上が必要なのだが、yumではsqlite3.3.6以上はインストールできない事が判明。
ということでSQLiteのサイトからソースコードでインストール。
CentOSの場合は「sqlite-autoconf-3071000.tar.gz」を使いました。
# wget http://www.sqlite.org/sqlite-autoconf-3071000.tar.gz # tar xzvf sqlite-autoconf-3071000.tar.gz # cd sqlite-autoconf-3071000 # ./configure # make # make install
一発で成功したー。(珍しい・・・)
ブログ「俺の作業録」を参考にさせて頂きました。ありがとうございました。
http://d.hatena.ne.jp/pirosikick/20101103/1288796756
Bundlerが使えない
gem install rails でrailsはすんなりと入った。
その後、いざ、railsアプリを作ろうと
$ rails new hinagiku
と打ったところ、何やら末尾に大量のエラーが…。
とりあえず、動くかどうかやってみようと動かしてみたところ、やっぱり動かなかった。
エラー出てたもんね。
$ rails server Could not find jquery-rails-2.0.0 in any of the sources Run `bundle install` to install missing gems.
必要なライブラリがないからbundle installをしなければいけない。
(bundlerはこの前のえにしテックカフェで知ったよ ・∀・)
$ bundle install Fetching source index for https://rubygems.org/ (略・・・)LoadError: no such file to load -- openssl (ずらずらずらとライブラリのインストールエラー)
これ、rails newした時に出ていたのと同じエラーである。
なるほど、rails new したときにbundle installしようとしてコケていたのか。
ライブラリがインストールできていないのだけど、元をたどれば「opensslがない」と。
調べてみたら、rvmでrubyをインストールする場合、opensslのオプションを付けてあげる必要があることがわかった。rvmのサイトを見ながらrubyをreinstallして解決。
$ rvm pkg install openssl $ rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr
このあとbundle installしたら問題なくライブラリのインストール、紐付けが行われた。
期せずしてはじめてのbundle installコマンド。
ちなみに、上記はrvmで管理しているRubyのどれかのバージョンで1回やれば大丈夫みたい。
1.9.3でrails環境を作ったあとに、rvmにインストールした1.9.2(opensslの指定なし)でrails環境作ったときにはエラーにならなかった。
JavaScriptエンジンがない?
これでサーバーは立ち上がる・・・はず・・・!
rails server は rails s でも実行できるのね、ふmふm。
$ rails s (略)/lib/ruby/gems/1.9.3/gems/execjs-1.2.4/lib/execjs/runtimes.rb: \ 45:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes.
JavaScript runtimeがない、のか。
調べてみたところ、Rails 3.1 から内部で CaffeeScript を使うようになったことで、実行時にJavaScriptランタイムが必須になったようです。
railsアプリケーションフォルダ直下にあるGemfileに
gem 'therubyracer'
を書いてbundle install。
これでRubyで使えるv8インタプリタのtherubyracerが入りましたー。
node.jsでもよかったみたい。
Macにはnode.jsが入っていたから特にエラーにならなかったのかな。
参考にさせてもらったサイト
http://d.hatena.ne.jp/kano4/20110708/javascript_runtime_error
http://d.hatena.ne.jp/kano4/20111201/javascript_runtime_error_part2
http://blog.glidenote.com/blog/2012/01/07/rails3.1-could-not-find-a-javascript-runtime./
http://www.ruby-forum.com/topic/1899392
上記を乗り越えて、自鯖でrails構築ができるようになりました!
rails sを実行してから、自鯖で開発していたらrails sしても外から簡単にアクセスすることができないじゃないと気がついたりはしたのだけど、環境構築は繰り返して勘を掴んでいくのが慣れる近道なのかも。
ちなみにMacで同じ環境を作ったのだけど、1つも躓くことなくサクっと環境が出来上がりました。
開発や学習はMacメインでやっていく予定です。