トップ 最新 追記

じじぃの日記、ツッコミ可

Twitter: @jijixi_org
Xbox Live: jijixi

初心者が書いた OCaml 入門
Spotlight tips サイト内リンク集
1970|01|02|
2003|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|11|
2011|05|
2012|01|

2009-09-09 [長年日記]

% [Scala] これは……バグなのか?

Android 関係を調べてて偶然遭遇した謎現象。

% scalac -version
Scala compiler version 2.7.5.final -- Copyright 2002-2009, LAMP/EPFL
% cat Test1.scala
package foo.bar.Baz

import android.app.Activity

object Test1 extends Application {
   Console.println("Hello")
}
% scalac -classpath (略)/android.jar Test1.scala

これは正常にコンパイルできるのに、

% cat Test2.scala
package com.azito.jijixi

import android.app.Activity

object Test2 extends Application {
   Console.println("Hello")
}
% scalac -classpath (略)/android.jar Test2.scala
Test2.scala:3: error: value app is not a member of package com.android
import android.app.Activity
               ^
one error found

謎すぎる。com.android ってどっから出て来たんだよ。

一応いろいろ試してみた感じだと、パッケージ名の最初が com ならいつもこうなっちゃうっぽい。 あと android 云々を import じゃなく他のところに直接書いても同じ。

android っていう名前にトリガーがあるのかと思って自分でそういう名前のパッケージ作ったりしてみたが特に問題は起きない。 ということは android-sdk 付属の android.jar が何かおかしいんだろうか。 でも、それにしたって自分のパッケージ名によっておかしかったりおかしくなかったりなのがわけわからん。

ともあれ、頭が com なパッケージ名を使わなきゃ良いとわかった時点で、これ以上追求する気は失せた。 つか、こんな意味不明な現象で丸一日悩んだのが悔しくてしかたがないよ(苦笑

(追記 2009/09/16)

どうも com.android というパッケージはどこか (わからんのだが) に実在するらしい。 で (適当に設定してある) PATH から自動生成される CLASSPATH の中にそれが含まれているっぽい。

結局、com.* なパッケージ内で android を参照しようとすると (近い階層から探索するので?) 先に com.android が見付かってしまい、それは android とは別のパッケージなのでエラーになるということのよう。 この場合以下のように書くと問題を回避できるそうな。

import _root_.android.app.Activity

(/追記)


2009-09-16 [長年日記]

% [Scala][Android] Scala on Android

Scala で Android の世界に "こんにちは" をするまで。 なかなか自分の環境にズバリな情報が見付けられず試行錯誤したが、ようやく何とかなったのでまとめ。

とりあえず参考にしたページは以下。

ref. http://robey.lag.net/2009/01/19/scala-on-android.html

ref. http://www.scala-lang.org/node/160

ref. http://chneukirchen.org/blog/archive/2009/04/programming-for-android-with-scala.html

Thanks these authors.

% [Scala][Android] Scala on Android - その1 - Android 用 scala-library.jar を作成する

最初に必要なもの。バージョンは今回わしが使ったもので、WindowsXP SP3 (cygwin 併用) で作業している。 あと空白入りパスでハマるのは嫌なので、あらかじめ全て空白が入らない場所に置いてある。

ProGuard はおそらく省略できそうなんだが、うちの貧弱マシンだといろいろと問題があって、これを使ったやり方しかうまくいかなかったので。 まあ、どっちにしろ使った方ができ上がるファイルは小さくなるのでおすすめ。 Android SDK はもたもたしてる間に 1.6 が出てしまったが、とりあえず 1.5 で。 1.6 で手順を変更する必要がある場合は後日フォローしたい。

Eclipse は貧弱マシンなので (というかそもそもあんまり好きじゃないし) 使わない。

  • JDK (1.6.0_16)
  • Apache Ant (1.7.1)
  • Scala (2.7.6.final)
  • ProGuard (4.4)
  • Android SDK (1.5)

まず Scala のソースを SVN か リポジトリスナップショット (ダウンロードページにある) で取得。 プリビルド版の Scala の src には android-library が含まれていないので注意。

% wget http://www.scala-lang.org/downloads/distrib/files/scala-2.7.6.final-sources.tgz
% tar zxf scala-2.7.6.final-sources.tgz

次に既存の scala-library.jar をどこかに展開し、android 用の部分だけ差し換える。 参考にしたページでは scala-library のソースを上書きして丸ごとビルドしろと書かれているが、 うちのボロマシンでは無理なのでビルド済みの jar をいじる。 実際に scala-android のディレクトリを見てみればわかるが、scala-library との差分はファイル二つだけ。

% mkdir workdir; cd workdir
% jar xf ${SCALA_HOME}/lib/scala-library.jar
% export SRC=${scala-src-path}/src/android-library
% scalac ${SRC}/scala/ScalaObject.scala
% scalac ${SRC}/scala/reflect/ScalaBeanInfo.scala
% jar cf ../scala-android.jar *

展開した場所で scalac を実行すればうまいこと該当するクラスファイルだけが上書きされるはず。 で、それを再度 jar で固めれば終了。

今回はこれを ${SCALA_HOME}/android-lib/scala-android.jar という場所に置くことにする。

% [Scala][Android] Scala on Android - その2 - プロジェクトを作成する

プロジェクトの作成に関してはマニュアルが日本語化されているので問題無いだろう。

ref. http://developer.android.com/intl/ja/guide/developing/other-ide.html

とりあえず例としてはこんな感じ。 あらかじめ Android SDK の tools ディレクトリを PATH に含めてある。

% android.bat create project --target 2 --path ./hello_scala --activity HelloScala --package com.azito.jijixi

こうすると、Android 1.5 用の (android.bat list target 参照) プロジェクトファイルが ./hello_scala 以下に作成される。 activity というのは Android アプリケーションのエントリーポイントになるクラス。 上記のように実行すると src/com/azito/jijixi/HelloScala.java というファイルができているはず。 まあ今回は必要無いのでさくっと消しちゃっても良い。

プロジェクトディレクトリに移り、build.xml に以下のパッチをあてる。 ほんとは完全に別ファイルにして build.xml から読み込むだけにしたかったんだけど、Ant の知識が足りなくて断念。

% cat ${where-place}/build.xml.diff
--- build.xml.orig	2009-09-15 19:35:12.781250000 +0900
+++ build.xml	2009-09-16 17:11:24.843750000 +0900
@@ -58,4 +58,89 @@
          targets are used.
     -->
     <setup />
+
+    <!-- for Scala settings. -->
+    <!-- set properties for your evnvironment. -->
+    <property name="scala-home"
+        value="c:/develop/scala" />
+    <property name="scala-android-library"
+        value="${scala-home}/android-lib/scala-android.jar" />
+    <property name="proguard-home"
+        value="c:/develop/proguard" />
+
+    <!-- override targets in platforms/android-1.5/templates/android_rules.xml -->
+    <target name="compile" depends="dirs, resource-src, aidl">
+        <javac encoding="ascii" target="1.5" debug="true" extdirs=""
+            includes="**/*.java"
+            destdir="${out-classes}"
+            bootclasspathref="android.target.classpath">
+            <src path="${source-folder}"/>
+            <src path="${gen-folder}"/>
+            <classpath>
+                <pathelement path="${scala-android-library}"/>
+                <fileset dir="${external-libs-folder}" includes="*.jar"/>
+                <pathelement path="${main-out-classes}"/>
+            </classpath>
+        </javac>
+
+        <taskdef resource="scala/tools/ant/antlib.xml">
+            <classpath>
+                <pathelement path="${scala-home}/lib/scala-compiler.jar"/>
+                <pathelement path="${scala-home}/lib/scala-library.jar"/>
+            </classpath>
+        </taskdef>
+
+        <scalac force="changed" deprecation="on"
+            includes="**/*.scala"
+            destdir="${out-classes}"
+            bootclasspathref="android.target.classpath">
+            <src path="${source-folder}"/>
+            <classpath>
+                <pathelement path="${scala-android-library}"/>
+                <fileset dir="${external-libs-folder}" includes="*.jar"/>
+                <pathelement path="${main-out-classes}"/>
+            </classpath>
+        </scalac>
+    </target>
+
+    <property name="stripped-jar-file"
+        value="${out-classes-location}/../classes.stripped.jar" />
+
+    <target name="dex" depends="proguard">
+        <echo>Converting compiled files and external libraries into ${out-folder}/${dex-file}...</echo>
+        <apply executable="${dx}" failonerror="true" parallel="true">
+            <arg value="--dex" />
+            <arg value="--output=${intermediate-dex-location}" />
+            <fileset file="${stripped-jar-file}" />
+        </apply>
+    </target>
+
+    <target name="proguard" depends="compile">
+        <taskdef resource="proguard/ant/task.properties"
+            classpath="${proguard-home}/lib/proguard.jar" />
+
+        <fileset id="external-jars"
+            dir="${external-libs-folder}" includes="**/*.jar" />
+        <pathconvert property="external-jars" refid="external-jars" />
+
+        <proguard>
+            <injar path="${out-classes-location}" />
+            <injar path="${scala-android-library}:${external-jars}"
+                filter="!META-INF/MANIFEST.MF,!library.properties" />
+            <outjar path="${stripped-jar-file}" />
+            <libraryjar path="${android-jar}" />
+            <keep name="**.R" />
+            <keep name="**.R$*" />
+            <keep name="org.xml.sax.EntityResolver" /> <!-- BK :-p -->
+            -dontwarn
+            -dontoptimize
+            -dontobfuscate
+            -keep public class * extends android.app.Activity
+        </proguard>
+    </target>
+
+    <!-- for debug. -->
+    <target name="show-prop">
+        <echoproperties />
+    </target>
 </project>
% cd hello_scala
% patch < ${where-place}/build.xml.diff
patching file build.xml

パッチをあてたら必要に応じて新しい build.xml の以下の箇所を編集。 まあパッチの方を直しちゃった方が早いかもしれないが、その辺は好き好きで。

<property name="scala-home"
    value="c:/develop/scala" />
<property name="scala-android-library"
    value="${scala-home}/android-lib/scala-android.jar" />
<property name="proguard-home"
    value="c:/develop/proguard" />

scala-home は Scala をインストールしてある場所。 scala-android-library は先に作った Android 用 scala-library.jar の場所。 proguard-home は ProGuard をインストールしてある場所。 他の場所については基本的にいじる必要が無いようになってるはず。 (だが、知識不足は否めないのであまり信用しないように)

% [Scala][Android] Scala on Android - その3 - Scala でソースを書いてビルドする

src/com/azito/jijixi/HelloScala.java を消して代わりに src/com/azito/jijixi/HelloScala.scala を作成。 とりあえず以下のような感じで。 ProGuard が必要無いクラスを消してしまうので、ある程度 Scala 的な操作を入れないと出来上がりがつまらなくなる。 ということで、ちょっと無駄に List とか使ってある。

% cat src/com/azito/jijixi/HelloScala.scala
package com.azito.jijixi

import _root_.android.app.Activity
import _root_.android.os.Bundle
import _root_.android.widget.TextView

class HelloScala extends Activity {
   override def onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      val tv = new TextView(this)
      val lst = List("Hello", "Android,", "it's", "me,", "Scala!")
      tv.setText(lst mkString(" "))
      setContentView(tv)
   }
}

できたらこれをビルド。

% ant debug
Buildfile: build.xml
    [setup] Project Target: Android 1.5
    [setup] API level: 3

dirs:
     [echo] Creating output directories if needed...
    [mkdir] Created dir: c:\home\jijixi\tmp\android_test\hello_scala\bin\classes

resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

aidl:
     [echo] Compiling aidl files into Java classes...

compile:
    [javac] Compiling 1 source file to c:\home\jijixi\tmp\android_test\hello_scala\bin\classes
   [scalac] Compiling 1 source file to c:\home\jijixi\tmp\android_test\hello_scala\bin\classes
   [scalac] Element 'c:\home\jijixi\tmp\android_test\bin\classes' does not exist.

proguard:
 [proguard] ProGuard, version 4.4
 [proguard] Reading program directory [C:\home\jijixi\tmp\android_test\hello_scala\bin\classes]
 [proguard] Reading program jar [C:\develop\scala\android-lib\scala-android.jar] (filtered)
 [proguard] Reading library jar [C:\develop\android-sdk\platforms\android-1.5\android.jar]
 [proguard] Note: You're ignoring all warnings!
 [proguard] Preparing output jar [C:\home\jijixi\tmp\android_test\hello_scala\bin\classes.stripped.jar]
 [proguard]   Copying resources from program directory [C:\home\jijixi\tmp\android_test\hello_scala\bin\classes]
 [proguard]   Copying resources from program jar [C:\develop\scala\android-lib\scala-android.jar] (filtered)

dex:
     [echo] Converting compiled files and external libraries into bin/classes.dex...

package-resources:
     [echo] Packaging resources
 [aaptexec] Creating full resource package...

debug:
[apkbuilder] Creating HelloScala-debug.apk and signing it with a debug key...
[apkbuilder] Using keystore: C:\Documents and Settings\jijixi\.android\debug.keystore

BUILD SUCCESSFUL
Total time: 46 seconds

エラーが出なければ完了。 一応 ProGuard が出力したファイルの中身なんかを見てみると、

% jar tf bin/classes.stripped.jar
com/azito/jijixi/HelloScala.class
com/azito/jijixi/R$attr.class
com/azito/jijixi/R$layout.class
com/azito/jijixi/R$string.class
com/azito/jijixi/R.class
scala/$colon$colon.class
scala/Array$Array0$class.class
scala/Array$Array0.class
scala/Array$ArrayLike.class
scala/Array.class
scala/collection/mutable/Buffer$$anonfun$$plus$plus$eq$1.class
scala/collection/mutable/Buffer$class.class
scala/collection/mutable/Buffer.class
scala/collection/mutable/CloneableCollection$class.class
scala/collection/mutable/CloneableCollection.class
scala/collection/mutable/ListBuffer$$anon$1.class
scala/collection/mutable/ListBuffer$$anonfun$equals$1.class
scala/collection/mutable/ListBuffer.class
scala/Collection$class.class
scala/Collection.class
scala/compat/Platform$.class
scala/Function1$class.class
scala/Function1.class
scala/Iterable$class.class
scala/Iterable.class
scala/Iterator$$anon$17.class
scala/Iterator$class.class
scala/Iterator.class
scala/List$$anon$2.class
scala/List$.class
scala/List.class
scala/MatchError.class
scala/Math$.class
scala/Nil$.class
scala/PartialFunction$class.class
scala/PartialFunction.class
scala/Product$class.class
scala/Product.class
scala/Product2$class.class
scala/Product2.class
scala/RandomAccessSeq$class.class
scala/RandomAccessSeq$Mutable$class.class
scala/RandomAccessSeq$Mutable.class
scala/RandomAccessSeq.class
scala/runtime/BoxedArray$AnyIterator.class
scala/runtime/BoxedArray.class
scala/runtime/BoxedObjectArray.class
scala/runtime/BoxedUnit.class
scala/runtime/BoxesRunTime.class
scala/runtime/Nothing$.class
scala/runtime/ScalaRunTime$.class
scala/Seq$class.class
scala/Seq.class
scala/StringBuilder$.class
scala/StringBuilder.class
scala/Tuple2.class

List を使っただけでこんなに関係するのか…… と思いつつも、元の jar が 3.7MB くらいあるのが 60KB 弱にまで減るんだからありがたいことだ。 最終的にはこれがさらに圧縮されて 18KB ほどになる (apk ファイル)。 ProGuard を使わない場合は 800KB くらいらしい。 (うちでは dx が謎のエラーで死んでしまうので実際には試せていないが)

% [Scala][Android] Scala on Android - その4 - エミュレータで実行

省略。 すでに紹介したが、

ref. http://developer.android.com/intl/ja/guide/developing/other-ide.html#Running

こちらのページの「アプリケーションの実行」という項を見ればとてもよくわかるはず。 インストールするとアプリケーションタブに HelloScala というアイコンが現れているはずなので、 そいつを起動して "Hello Android, it's me, Scala!" と表示されれば成功。


2009-09-28 [長年日記]

% [game] Forza Motorsport 3 体験版

出てたのでやってみたんだが、なんかもうスゴイ時代だね。 以前に PGR4 を安く買って遊んでみたりしてて、それでもすげー時代だなーと思ってたんだけど、その感覚を軽く凌駕してスゲーとしか言いようがない。 とりあえず見た目に関してはもう PGR4 には戻れないわ。 「うわ、グラフィックショボッ」ってなる。 まあ PGR はあれはあれでゲーム的なおもしろさがあるから、いらん子ではないけども。

ともあれ、なんかスゴイので製品版は買うでしょう。 アシスト機能を全部オンにするとアクセルベタ踏みで走れたりするので、ヌルゲーマーでも安心。 全部オフにしたらまともに走れなかったがw


2009-09-30 [長年日記]

% [Mac] TimeMachine が絶不調

昨日から何だか変。 バックアップが毎回やたらと時間がかかる上にすごい勢いで CPU 時間を持っていくわメモリは大量に消費するわで、他のあらゆるものがもっさり状態。 バックグラウンドでひっそりやるべき作業が 30 分もの間全力疾走ってどういうことさ。 しかもそれが一時間に一回来るわけで。

これまでにもおかしくなることはあったけど、ここまでヒドイのは初めてじゃなかろうか。 何か対処しようにも TimeMachine を止めるくらいしか思い付かんし、参ったね。

% [Mac] TimeMachine 絶不調の件、続報

とりあえず TimeMachine をオフにしてバックアップフォルダの中身を見てみたら、なんか inprogress とかいういかにも作業用的な拡張子のファイル (パッケージ) が残ってて、どうもこいつが匂う。

ので、とっととこいつをゴミ箱に突っ込んで、空にしようと思ったら…… わー、なんかさっきまでの backupd と同じ勢いで Locum とかいうプロセス (よくわからんが最近のバージョンでゴミ箱空にするときに走るやつ) が全力疾走し始めたわ orz

…… 小一時間ほど経つが終わらない。 ファイルサイズは 80KB とかだったんだけどね。 何が気に入らなくて発狂してんのかしらんが、もう勘弁して(泣

おそらく backupd はこいつを消そうとしてああなってたんだろうから、とりあえず TimeMachine の問題は解決されただろうとは思うが、消せないファイルはどうしたもんかな。 rm でおとなしく消えてくれるだろうか。

% [Mac] TimeMachine さらに続き

ようやくおさまったか…… と思ったらどうも Locum は志半ばで死んだらしい。 ゴミ箱が空になっていないしロックされたままで中身が見れない。 しかたないのでシェルで中身を見に行くことに。

% sudo su
# cd /Volumes/Backup/.Trashes/501/2009-09-29-200035.inProgress/(以下略)

一番奥の階層に降りたと思いねえ。 なんかファイル自体は com.apple.ADC_Reference_Library.CoreReference.docset というやつだった。 こいつはパッケージなのでさらに降りて QuickTime/IQ_InteractiveMovies/art てな感じのところが問題の箇所。

# ls
qt5_win_player.jpg   qt5_win_player.jpg   qt5_win_player.?if  qt5_win_player.?if

なんか文字化けしとる (?のとこはほんとは漢字)。 つか、それ以前になぜ同じ名前のファイルが二つずつ見えるの?

# ls -l
ls: qt5_win_player.jpg: No such file or directory
ls: qt5_win_player.jpg: No such file or directory
total 104
-rw-rw-r--@ 2 _devdocs  wheel  50200  5 14  2008 qt5_win_player.?if
-rw-rw-r--@ 2 _devdocs  wheel  50200  5 14  2008 qt5_win_player.?if

え〜〜?なんかファイルというよりディレクトリの方がぶっこわれてる感じ。 ちなみに実際のバックアップ元の同じ箇所を見ても特に壊れてる様子は無かった。 qt5_win_player.?if もちゃんと gif になってた。

あとここで、

# rm qt*

とかやるとシェルが (というか負荷でファンが) 唸りだすので即 ^C した。 ワイルドカード以外に補完 (^I) とかでも唸る。

# rm -f qt5_win_player.jpg
# ls
qt5_win_player.jpg   qt5_win_player.jpg   qt5_win_player.?if  qt5_win_player.?if

orz

sh-3.2# cd ..
sh-3.2# ls
art
sh-3.2# rm -rf art
^C

やっぱり唸る。 消せない orz

もはやできることは fsck しか残っておりません。 ディスクユーティリティで修復開始…… 予想時間 20 分とかダル……

% [Mac] ディスク修復中……

ふと見たらプログレスメーターがなぜか減ってて、予想時間 20 時間になっててワロタ。 アホかとw

いつ終わるんや……

% [Mac] First Aid が失敗しました

延々と時間かけた挙句このざまだよ orz

ディスクユーティリティは "Backup"の修復処理を中止しました。次のエラーが起きたためです:

ファイルシステムの検証または修復に失敗しました。

どうしたもんかな、これ……

% [Mac] しかもマウントできなくなったという

まあ、TimeMachine 専用にしてるボリュームだから、最悪初期化すりゃいいか。 過去のバックアップ分がパァだが。

一応、もう一回修復を試みてみよう。

% [Mac] 結局二回目の修復も失敗

初期化した。 はあ、ぐったりだ。


トップ 最新 追記

日記ってのは本来、自分で読み返すためにあるもんだよなあ……
もしくは有名人になったら死後に本になったりとかか?

RSS はこちら

jijixi at azito.com