2008年5月25日日曜日

シンボリックリンクのリンク先を取得

UNIXでシンボリックリンクのリンク先を取得するためには、readlinkコマンドを使えばいいらしいのだが、入っていない場合はどうすればよいのだろう?
というよりも、問題として言われたUNIXマシンにはreadlinkコマンドがなかった。。。


というわけで、lsとsedの文字列処理でやってみる。


ls -l コマンド | sed -e "s/^l.*-> //"

これでリンク先が取れる。スクリプトの中では"-L"で対象のファイルがシンボリックリンクか否かを判断できるので、


if [-L ${COMMAND}]; then
COMMAND=`ls -l "$COMMAND" | sed -e "s/^l.*-> //"`
fi

とやって$COMMANDからリンク先を取得する




参考
http://nao.s164.xrea.com/td/2008-01-05.html
http://cyberam.dip.jp/linux_command/shellscript/shellscript_main.html

64bit JVM on 32 bit Linux

仕事で急に32bit Javaアプリを64bit(x64 Windows & Linux)に対応させるため、バンドルさせるJVMを64bitにするように言われた。しかも締め切りは1週間後。リリースは1ヶ月後。ちょっといろいろと考えさせられますね。こんなプロセスで大丈夫?


さて、プロセスも問題だが、技術的にも疑問が。

JVMを置き換えること自体は問題ないのだが、本当に必要なのだろうか?

というのも32bitのアプリケーションは64bit OS上でも(ほぼ)そのまま動くので、JVMをわざわざ64bitにする意味がよくわからない。そのまま今の32bit Javaアプリケーションを64bit OS上で動かし、問題があがったところだけ修正すればいいと思うし、リソースや64bit JVMの実績を考えるとそうすべきだろう。32bitバージョンは残すらしいので、将来のワークも多くなってしまう。唯一現時点でヒープがたりなくて困っているというのならJVMを64bitにする価値はあるが、対象のアプリケーションはそういうたぐいのアプリケーションではないはずだ。Redhatも64bit jvmの特徴でメリットはヒープサイズだけだと言っているし。お客様は下で動いているのが32bit JVMだろうが64bit JVMだろうが気にしない。64bit OSをサポートしているかどうかは重要だが。

もっというと、今回のケースではインストーラーのJVMを変更するのでリスクが大きい。このアプリケーションはインストーラーにInstallShield Multi Platformを使って、Javaで動くインストーラーになっているのだが、問題はInstallShieldのバージョンが古いということ。最新バージョンではないし、製品自体もInstallAnywhereという別製品に置き換わっているので、64bit JVMに対応しているかどうかあやしい。内部でJNIをいろいろ使っているので対応していない可能性も十分ある。まず、それを調べるだけでも何日か使ってしまうし、最悪、巧みに回避するプログラムを自分で作らないといけない。そんなことをしていたら、とてもリリースに間に合わないだろうし、品質もあやしくなる。そこまでして、64bit JVMにしたいのだろうか?


さて、ここまで32bitアプリケーションが64bit OSで普通に動くという前提で書いてきたが本当だろうか?今このBlogを書いているのはVista 64bit上の32 bit FirefoxだからWindows上では問題ない。ではLinuxは?わざわざMicrosoftがWoW64と言っているくらいだから、これってWindowsだけ?


ということで調べてみましたが、結論としてはライブラリさえあれば動きます。というかWoW64と大げさにいっているけれど、これは単純に32bitライブラリと64bitライブラリの両方がデフォルトでインストールされているだけっぽい(もちろん実行するサブシステムを分けるとかいろいろありますが)。Linux(RedHat)の場合は、32bit用に/usr/libが、64bit用に/usr/lib64が作られ、必要に応じて適切なライブラリが使われるようになっている。そのため、Windowsと同じように特に意識することなく32bit アプリケーションを64bit OS上で使用することができる。実際に実験してみたが、なんの問題もなく動いてしまった。

参考までに、JVMのGuideにあった以下の記述を引用。
In RHEL4, the 64-bit versions of the packages are available in the Compatibility Arch Support package group.

You can use the RPM tool to check which versions of the packages you have installed by adding the option --queryformat "%{NAME}.%{ARCH}\n" to your RPM command. For example:

/home/username : rpm --queryformat "%{NAME}.%{ARCH}\n" -q libstdc++
libstdc++.x86_64
libstdc++.i386

つまり、32bit/64bitに関わりなく、適切なライブラリがインストールされていれば動くということ。

2008年5月22日木曜日

InstallShield Multi PlatformでLog

Install Shieldでlogが出てこないので設定を確認してみる。

IDEを起動し、

  1. View Listの[Behavior and Logic]-[Sequences]

  2. Explorerの[Sequences]-[Product Sequence]-[Installation Sequence]を選択

  3. [Standard Properties]の[Wizard Log]にある[...]ボタンをクリック

  4. [Wizard Log]Dialogが出てくるので設定


で確認







Logging Context:Install
Logging Options:Log all events と Log exception traces にチェック。
Standard Output Enableはアンチェック
Events Logged:dbg,wrn,msg2,err,msg1
Log file:Enable loggging to fileにチェック

ファイル名は $D(temp)/install.trace
Optoin File:Enable loggint to optional file にチェック

$P(absoluteInstallDirectory)/installLog.txt


$P(absoluteInstallDirectory)/installLog.txtだけだとインストールに失敗した場合にログがないという事態に陥る。そのため、optionalにもログを書き出すようにし、Temporaryディレクトリ($D(temp)/installLog.txt)にはき出すようにする。そうすれば、失敗してもOK。また、Temporaryだけだと消される可能性もあるので、InstallDirectoryにもログは残しておきたい。そのため、両方使う。

EclipseのDiff

で空白を無視するオプション
http://d.hatena.ne.jp/uunfo/20080109/1199878546

しかし、なんか変なところでマッチして、思った通りの結果が出ないんだよなぁ。XMLのdiffは本当に使い物にならないし。
こりゃ、自分で開発する?(そして、diffの大変さを理解し、我慢する?)

2008年5月18日日曜日

C#でstatic初期化

GotDotNet Japan 掲示板を参考に、静的コンストラクタでやってみる。

以下抜粋
private static string str; // シングルトン的な動的文字列

static HogeHoge() // 静的コンストラクタ
{
 StringBuilder sb = new StringBuilder();

 foreach (string boo in ALL_BAR)
 {
  sb.Append(boo);
 }

 str = sb.ToString();
}

C#で西暦を和暦に

@ITにまさに書いてあった。以下抜粋。

using System;
using System.Globalization;

class WarekiSample2 {
static void Main() {

CultureInfo culture = new CultureInfo("ja-JP", true);
culture.DateTimeFormat.Calendar = new JapaneseCalendar();

DateTime target = new DateTime(2003, 7, 1);
string result = target.ToString("ggyy年M月d日", culture);
Console.WriteLine(result);
// 出力:平成15年7月1日
}
}

2008年5月17日土曜日

DataRow.ItemArrayの更新(.net)

MSDNに書いてある使用例より、
    // Make a DataTable using the function below.
DataTable dt = MakeTableWithAutoIncrement();
DataRow relation;
// Declare the array variable.
object [] rowArray = new object[2];
// Create 10 new rows and add to DataRowCollection.
for(int i = 0; i <10; i++)
{
rowArray[0]=null;
rowArray[1]= "item " + i;
relation = dt.NewRow();
relation.ItemArray = rowArray;
dt.Rows.Add(relation);
}

このように、DataRowの中身を更新するには
relation.ItemArray = rowArray;

とやって、配列を丸ごと更新する。
こうではなく、
relation.ItemArray[0]=null;
relation.ItemArray[1]="item " + i;

と配列の要素を更新しようとしてもうまくいかない。最初これで試してみて、「更新されないなぁ?」と悩みました。
ちゃんと考えてみれば、配列の要素を更新できると危険なので、このDataRow.ItemArrayの設計自体は問題なのだが、VisualStudioのIntelli Senseのヘルプだけだと、後者の方法で書いてしまいがち。

2008年5月16日金曜日

JavaでEnclosing Classのフィールドを参照する方法

<Enclosing Class>.this.<Field Name>とすればよい。

public class EnclosingClass {
private String param = "hogehoge";

public class EnclosedClass {
public void hoge() {
System.out.println(EnclosingClass.this.param);
}
}
}


http://blogs.wankuma.com/nagise/archive/2007/07/31/88042.aspx

2008年5月9日金曜日

Propertiesファイルが\u0000で汚される

JavaのPropertiesファイルが\u0000という文字で埋めつくされるという問題。コードを見る限り、問題なさそうだったが、マルチスレッド部分があやしいと思い、実験プログラムを作って走らせてみた。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.Properties;

public class Prop {
public static void main(String[] args) throws Exception {
Thread[] th = new Thread[10];
for (int i = 0 ; i &lt; 10 ; i++) {
th[i] = new Writer();
}
for (int i = 0 ; i &lt; 10 ; i++) {
th[i].start();
}
}
}

class Writer extends Thread {
static Properties prop = new Properties();

public Writer() {
}

public void run() {
for (int i = 0 ; i &lt; 100 ; i++) {
try {
write();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("end");
}
private void write() throws Exception {
FileInputStream in = new FileInputStream("test.properties");
prop.load(in);
in.close();

for (long i = 0 ; i &lt; 10000 ; i++) {
long date = new Date().getTime();
String existingValue = prop.getProperty("test" + i);
if (existingValue != null && existingValue.length() &gt; 0) {
long x = Long.parseLong(existingValue);
}
prop.setProperty("test" + i, Long.toString(date));
}
FileOutputStream out = new FileOutputStream("test.properties");
prop.store(out, "comment");
out.close();
}
}


実験は成功(?)。見事、test.propertiesファイルに\u0000という文字が入り、Propertiesファイルが壊れた。
PropertiesクラスはスレッドセーフなHashtableから継承されているものの、おそらくstoreとloadのところで不整合がおきたのだろう。ロックファイルを使うなり、synchronizeでがちがちにかためるなりして、ちゃんと整合性をとれる形にしないと、思わぬところでバグが混入してしまいますね。
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html
http://www.atmarkit.co.jp/fjava/javatips/024jspservlet015.html


今日の教訓
  • マルチスレッドプログラムは注意して書かないとバグが入ってしまう
  • Java標準のライブラリといえども油断禁物
  • ファイルの保存には要注意

2008年5月7日水曜日

Vistaで目覚ましタスクを登録

家にいるときはPCをつけっぱなしにしているので、Windowsのタスクを目覚まし代わりに使っています。こうすると、細かい設定もできますし、好きな音楽が目覚ましになるので寝起きが良いです。スリープからの復帰もできますので、かれこれ4,5年はこの方法を使っています。

今回、Vistaをインストールしたので、この目覚ましタスクも再登録しようとしたのですが、、、いやに時間がかかりました。

まず、タスクが見つからない。タスクマネージャというのがVistaにおけるタスクなのですが、これが結構奥深くにありますし、実行に管理者権限が必要なので、まるでユーザーに使わせる気がないようです。
次に、タスクの登録。これがよくわからん。XPまでは、悩むことなく単純に登録できたものが、VistaからMCベースになったためか、全然わからん。とりあえず、右に出ている操作の中から、「基本タスクの作成...」を選んだら見慣れたウィザードが出てきましたが、そこにいたるまでが大変。画面にいろいろごちゃごちゃと項目があるので、やりたいことを見つけるだけで一苦労です。ちなみに、「基本タスクの作成...」の下に、「タスクの作成...」というのがあるのですが、なぜ同じようなものが2つあるのでしょうか?

そして、タスク作成後、タスクが起動しない・・・どうも、1回は実行されているようなのですが、バックグラウンドで実行されているようで、Windowがまったく表示されません。つまり、いきなり音楽がなり始め、何が起きたかわからないまま終了してしまう。そんな状況です。眠りから覚めて、毎日1曲終わるまで聞き続けるのならこれでかまわないのかもしれませんが、うるさいと思って止めることもありますし、徹夜ですぐに止めたくなることもあると思います。

いろいろ調べてみると、NT Server系のタスクは、別ユーザーで実行されるらしく、Windowは表示しない仕様らしいです。どうしてもWindowを表示させたい場合は、"AT"コマンドでプログラムを登録しろとのこと。うーん、XPでは普通にできたことなのに。。。

しかたがないので、"AT /?"でヘルプを見ながらインタラクティブに動作させるために"/IT"オプションをつけてプログラムを登録すると、エラーが。なんでもATコマンドでのinteractiveモードはサポートされなくなったらしい。代わりにSCHTASKS.EXEコマンドを使用しろとのこと。なんか、公務員にたらい回しされてるみたいです。

SCHTASKSコマンドもヘルプで使い方を見てみると、これはタスクスケジューラのCUI版みたいです。ためしに、
&gt; SCHTASKS.EXE /QUERY
とすると、GUIで設定したタスクが表示されました。

さて、そうなると細かい設定はGUIの方でやって、問題のWindowを表示させるところだけをCUIのSCHTASKSコマンドを使えばよさそうです。早速、次のコマンドを使って"Alarm"タスク実行時にWindowを表示させるように設定しました。
&gt; SCHTASKS.EXE /Change /TN "Alarm" /IT
ものの見事に失敗しました。
うーん、なぜだ?

とここでふと、管理者権限が必要なのでは?という思いにたち、コマンドプロンプトを管理者権限で立ち上げ直して、同じコマンドを入力してみると、、、あっさり成功。だったら、そういってくれればいいのに。

最後に、タスクを実行してみると、無事Windowが表示されました。
長かった。

2008年5月6日火曜日

Intel 1000 PT Desktop Adapter

Vistaのndis.sysのブルー画面が連発するので、GWの超込んでいる秋葉原で、Intel PRO/1000 PT Desktop Adapterを買ってきました。

そして、早速GA-EP35-DS4に取り付けた結果、、、認識しない。なぜだ?
ドライバが入っていないだけなら、Windowsに文句を言われるはずだが、Windowsが認識していない以上、文句も何も言われない。ないものとして扱われている。
PCI Expressの接触不良かと思い、差しなおしたり、スロットの場所を変えたりしてみたが効果なし。Linuxを起動して確認してみても見えない。

ハードウェアの初期不良かとも思いましたが、電源投入直後にLEDは一瞬だけ光るから、いちおう動いてはいそうなんだけど。。。

困り果てていた頃、ちょうどあることを思い出した。P35のPCIeのレーン数は足りているのか?
というのも、GA-EP35-DS4には、PCIe x16スロットが2つ(一方はx4で動作)と、PCIe x1スロットが3つついているのだが、現在トリプルディスプレイ環境を構築するために、ビデオカードでPCIe x16スロットを両方使用している。となると、残りのPCIe x1スロットに割り当てられるレーンはあるのか?と。

そこで、マニュアルを詳しく見てみると、
3 x PCI Express x1 slots (share with the PCIE_16_2 slot)
つまり、PCIE_16_2 スロットを使っている場合、PCI Express x1スロットは使えないとのこと。これか・・・

PCIバス用を買ってこないといけないのか・・・また、Intel製が無難かなぁ。
しかし、この買ってきたやつはどうするかなー。将来のためにとっておくか、とっととヤフオクか・・・いちおう、購入NICなので箱ごととっておくかな・・・


とりあえず、Intel Desktop Adapter GTをぽちっとやっちまった。


ああ、こんなんだったらけちらずにX48チップセットを買うか、Intel製マザーを買うべきだったか。しかし、X48はDDR2でほとんどテストやってなさそうだし、Intel製のP35はPCIe x16が1つしかついてなかったからなぁ。

ほかのマザーボードメーカがReltekではなくIntel製NICをつければ全て解決するのに。政治的にできないのかな。Intel製NICがついていれば、多少高くても買う人は多いと思うけど(そういう人はIntel製マザーボードを買えばいいのか)。

Intel PRO/1000 PT Desktop Adapter 82572GI Gigabit Controller
Intel PRO/1000 GT Desktop Adapter 82541PI Gigabit Controller

Intel DX38BT 82566DC
Intel DX48BT2 82566DC
Intel DP35DP 82566DC

2008年5月5日月曜日

IIS 7.0 on Vistaでサーバーエラー

今までXP上で作っていたASP.NETを、VistaのIIS7.0にデプロイしてみたら、サーバーエラーで使えない。

エラーの内容は、
HTTP エラー 500.19 - Internal Server Error
ページに関連する構成データが無効であるため、要求されたページにアクセスできません。
エラー コード 0x80070021
構成エラー この構成セクションをこのパスで使用できません。この問題は、親レベルでセクションがロックされているときに発生します。ロック状態は既定で設定されているか (overrideModeDefault="Deny")、または overrideMode="Deny" もしくは従来の allowOverride="false" を含んだ場所タグによって明示的に設定されます。

構成ソース
149: &lt;add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;&lt;/modules&gt;
150: &lt;handlers&gt;
151: &lt;remove name="WebServiceHandlerFactory-Integrated"/&gt;
というもの。

いろいろ調べてみると、セキュリティ設定がIIS7.0で大幅に変わったことが原因らしい。IIS 7.0では、%windir%\system32\inetsrv\config\applicationHost.config でマシン全体のセキュリティ設定を定義し、各ASP.NETアプリケーションのweb.configで、マシン全体の設定を必要に応じて上書きする仕組みになっている。しかし、デフォルトの設定では、web.configで上書きが許可されていないため、エラーになってしまったようだ。

というわけで、applicationHost.configを書き直す。
エラー内容からすると、handler
&lt;configuration&gt;
&lt;configSections&gt;
&lt;sectionGroup name="system.webServer"&gt;
&lt;section name="handlers" overrideModeDefault="Deny" /&gt;

&lt;section name="handlers" overrideModeDefault="Allow" /&gt;
と書き直す。すると、今度はmodulesのところで同じエラーになったので、
&lt;section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" /&gt;

&lt;section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" /&gt;
と書き直す。

ちなみに、applicationHost.configを編集するためには管理者権限が必要で、エクスプローラから秀丸で開こうとしても開けませんでした。しかたがないので、コマンドプロンプトを右クリックし、管理者として実行をクリック。ディレクトリを移動し、
&gt; notepad applicationHost.config
で開きました。

なお、
こちらでは、直接書き換えずにlocationエレメントをoverrideMode=Allow付きで新たに作り、そこにoverrideしたいエレメントを追加するように指示している。いろいろ設定していくと、どれがAllowでどれがDisableかわからなくなるから、こうやってAllowのものをひとまとめにした方が管理しやすいのかもしれない。ただ開発マシンではあまり関係なさそう。


さて、applicationHost.configを書き換えて、ページをリロードしてみると(IISの再起動はいらない!)、別のエラーが
HTTP エラー 403.14 - Forbidden
Web サーバーは、このディレクトリの内容の一覧を表示しないように構成されています。
IIS7.0の設定を見てみると、「既定のドキュメント」にDefault.aspxがなかった。というわけでIISマネージャからDefault.aspxを追加。

これでOKと思いきや、また別のエラーが
HTTP エラー 404.3 - Not Found
拡張構成により、要求しているページは使用できません。ページがスクリプトの場合は、ハンドラを追加します。ファイルをダウンロードする場合は、MIME マップを追加します。
どうも、IISとASP.NETが関連づけされていないらしい。それでDefault.aspxも登録されていなかったのか。Visual Studioを先にインストールし、IISを後からインストールしたからだろうか。
さて、どうやって登録すればよいのかと思って、コントロールパネルの「Windowsの機能の有効化または無効化」からIISを見てみると、案の定ASP.NETのチェックが外れていた。デフォルトではセキュリティ上の理由から、最低限の機能しかインストールしない設定になっているらしい。
チェックを入れたところ、無事インストールも行われ、aspxファイルとの関連づけも行われた。

そして、再度アクセスしてみると、またエラー。
'Microsoft.Jet.OLEDB.4.0' プロバイダはローカルのコンピュータに登録されていません。
とのこと。
Driverをここからダウンロードしてみたが効果なし。
うーん、VisualStudioからデバッグモードで起動したときは、何の問題もなかったのだが。IISの設定に違いないのだが。

Googleで検索してみた結果、64bitが原因らしい。
http://d.hatena.ne.jp/kaorun/20060721/1153469992
どうやら、OLEDB Driverは64bitでは動かないらしい。これは困った。SQL Serverを使うしかないか、、、と思っていたところ、
http://blogs.wankuma.com/ognac/archive/2007/06/03/79269.aspx
のコメント欄で書いてある「32ビットアプリケーションの有効化」(アプリケーションプールのDefaultAppPool)を試してみたら、ついに成功。

長かった。


さて、あまりに動かないので、手元にあるThinkpad X61T(Vista Ultimate 32bit)で、試してみたところ、あっさり成功。applicationHost.configの書き換えもなし。いったい何なんだ?

クラッシュ再発

恐れていたことが起きました。
前回のエントリで書いたばっかりですが、またもやVistaがクラッシュしました。
しかし、今度は、iTunes使用中ではなく、VMWareの使用中にブルー画面になりました。

まず、これが前回のiTunesと同じと必ずしもいえないのですが、いずれにしろ不安定要素であることには違いないので、原因を探ります。今回は設定が反映されたためか、原因が違うためかはわかりませんが、前回までとは違い、いきなり再起動ではなくブルースクリーンが表示されました。
それによると、ndis.sysが原因のようです。すなわちNICがらみの問題だそうです。

また、再現方法も明確です。
VMWare上でゲストOSを立ち上げ、通信に付加をかけると(ファイルのダウンロードをすると)ほぼ100%発生しました。

こりゃ、オンボードLANが原因ですね。マザーボードはGA-EP35-DS4なので、オンボードLANのチップはRealtek 8111B chip。Realtekか・・・・

ここまでわかれば、後はGoogle先生に聞きまくります。

すると、2chにこんな情報が。
http://pc11.2ch.net/test/read.cgi/win/1202216223/251-351
Server2008をGIGABTYEのG31/G33マザーのシステムに入れて試しているが、ネットワーク

の転送が多くなるとNDIS.SYSの原因でブルースクリーンになる。

で、IntelのPCI-Express用サーバアダプタを入れて試すと、全くブルースクリーンにならない。

という事で、犯人はオンボードのRealtekのコントローラ用ドライバにしたいと思います。

最近のギガ蟹は昔と違って見直されている意見も聞きますが、俺の中では
やはり蟹だったか・・・
になりますた。

これか!
とりあえず、IntelのNICを買ってくるか。

しかし、今調べてみると、昔使っていたマザーのLANのMarvellも、Vistaとの相性がわるかったみたいだ。1年前の再起動もNICが原因だったのだろうか?ブルースクリーンを表示せず、いきなり再起動するから、原因調査ができないよ。この仕様ってどうなの?いや、初心者にブルースクリーンを見せるより、いきなり再起動したほうがよいのかもしれんが。

2008年5月3日土曜日

Vista + iTunesでクラッシュ(再起動)

新しいPCを新調し4日目、今までは快適に動いていましたが、今日ついにおそれていた自体が。iTunesで音楽を再生中、いきなり音がとぎれとぎれになったかと思うと、そのままブラックアウト。Vistaが丸ごと再起動。
実は1年前にも同じ症状に遭遇し、そのときはVistaが不安定という結論に達し、Windows XPを入れ直しました。しかし、SP1が出ても同じ症状が出るとは・・・まあ、Vistaの64bit版なので32bitより不安定なのかもしれませんが。

さて、問題は原因をさぐること。1年前からハードウェアもだいぶ変わってきているので、逆に変えていないところがかなりあやしいということになります。
また、XPではまったくおきなかったこと、OS毎落ちたこと、Webでは情報が見つからなかったこと、などを考えると、CD-R関係、Sound Driver、VistaのCD-R Driver、使っているDVD-ROMとの相性などが考えられます。しかし、どれも推測の域を出ません。


まずは、原因を特定するためにワトソン博士に頑張ってもらおう、、、と思ったらVistaからはなくなったみたいです。
うーん。とりあえず、クラッシュ時のダンプだけはとるようにしておきましょう。
ということで、[システムのプロパティ]から[起動と回復]を選びダンプを取得する設定に。
と、ここでシステムエラーの項目の中に「自動的に再起動する」というチェックボックスを発見。これのせいで再起動がかかっていたのか?ということでチェックを外すことに。

さて、とりあえずぱっと思いついたのは以下の項目
  1. UACを切っているからOSが落ちる
  2. Vista標準搭載のWriting機能が悪い
  3. B's Recorder GOLD 8 が悪い
  4. Pioneer DVR-A09 が悪い
とりあえず、3と4は対処が難しいので1と2をOffにしてしばらく様子を見てみることに。
1はコントロールパネルからデフォルトに戻すだけ、
2はhttp://plusd.itmedia.co.jp/pcuser/articles/0804/30/news078.htmlに書いてあるとおり、gpedit.mscから設定。
「ユーザーの構成」-「管理用テンプレート」-「Windowsコンポーネント」の「エクスプローラ」にある「CD焼き付け機能を削除するのプロパティ」で設定できる。

あとは、iTunesの設定でそれっぽいのがあればOffにしてみる。
  • iTunesの更新を自動的に確認する
  • 共有ライブラリを探す
  • Apple TVを検索
とりあえず、これらをOffにしてみました。

どうなることやら・・・

ScribeFire & Blogger でコードの投稿

仕事柄、コードの投稿が多くなりそうなので、そのためのメモ。

まず、普通にコピペするとこんな感じ

public class Test {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}

これじゃまずかろう。

とりあえず、コードの投稿はpreタグを使用する。
ScribeFireのWYSWYGで編集すると、変なタグに変換されて、コードの部分だけはHTMLを直接編集しないといけない。


次に、コードを見やすくする。これは単純にCSSで設定。
pre.src というクラスを作り、Bloggerのレイアウトの編集からHTMLに追記。

pre {
white-space: -moz-pre-wrap; /* Mozilla */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
}
pre.src {
border: 1px solid
}

実際にコードを書く際には<pre class="src"></pre>で囲めばよい。デザインをもっと凝るべきかもしれないが、とりあえず最初はこんなんで。
ちなみに、上のpre全部にかかるやつは改行するため。超長いコードや、小さいWindowではこれがないと、途中できれてしまうから。まあ、なるべく改行しないように、ソースコードの視認性を高めるできではあるのだが。
参考


最後に、Blogger側で、コードが変なところで改行しないように、テンプレートを変更。Windowを大きくしたときに、そのまま広がってほしいので、Minima Stretchを選択。これならば、コードがしっかり表示される。Windowを小さくしたときや、コードが長すぎる場合は相変わらず改行されてしまうが、まあ今までよりましだろう。

できあがりは、こんな感じ。

public class Test {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}

ScribeFireを使ってみる

Bloggerの投稿欄が狭い。狭すぎる。
XGA(1024*768)で使用している分には、あのくらいがちょうどよいのかもしれませんが、どうも狭すぎます。視認性が悪いので、このままではBlogが続かなくなりそうです。

というわけで調べてみましたら。FireFoxのAddOnでScribeFireというものを発見。なかなか良さそうなのでインストールして使ってみました。
https://addons.mozilla.org/ja/firefox/addon/1730
http://shira-blog.blogspot.com/2008/04/blogger-customfirefox-scribefire_12.html

設定はWizardに従うだけで簡単に行えました。

早速、このエントリーをScribeFireを使って書いてみましたが、なかなか良いですね。下書きをテキストエディタで書いて、それをコピペで投稿するとしても、このくらい広いとやりやすいですし、会社や出先で下書きを書くのもこれなら作業効率Upです。

WYSWYGの機能としても、Bloggerよりも全然使いやすい。何よりFireFox Addonということでパフォーマンスもよいです。HTMLのソースの切り替えやPreviewが速い!

うーん、これはよい。
あとは、標準ではないので不具合が起きないことを祈るのみです。

2008年5月1日木曜日

Java LoggingのCustom Log Handlerの作り方

調べたけど、なかなか見つからなかったのでメモ。
まあ、単純にいえば、java.util.logging.Handlerクラスのサブクラスを作り、必要なメソッドをオーバーライドすれば完成。
もっとも重要なのはpublishメソッドで、ここでどのようにログをとるかを記述する。
例えば専用のWebServiceを使ったり、特殊なRuntimeを呼び出したりしたい場合は、publishメソッドのなかでごにょごにょすればよい。

以下、簡単な実装例:
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;

public class CustomLogHandler extends Handler {
private static CustomLogHandler singleton = null;

public static synchronized CustomLogHandler getInstance() {
if (singleton == null) {
singleton = new InstallAnywhereLogHandler();
}
return singleton;
}

private InstallAnywhereLogHandler() {
// Do nothing
}

public void close() throws SecurityException {
// Do nothing
}

public void flush() {
// Do nothing
}

public void publish(LogRecord record) {
if (isLoggable(record)) {
System.out.println(record.getSourceClassName());
System.out.println(record.getSourceMethodName());
System.out.println(record.getMessage());
}
}
}


これを使うときは、
        CustomLogHandler handler = CustomLogHandler.getInstance();
logger.addHandler(handler);

てな感じでhandlerを追加すればよい。後は、通常と同じように
        logger.info("Message");

とでもやればよい。

参考
http://www.ibm.com/developerworks/jp/java/library/j-tiger08104/index.html

InstallAnywhere 2008でLogを取る方法

InstallAnywhere 2008でInstall中にログを取りたい場合、1つはjava標準のlogging APIを使うという方法がある。これは開発中やわかっている人に対しては便利なのだが、いかんせんユーザーに対しては不便きわまりない。というのもInstallAnywhereが独自のログファイルを生成してくれるため、ユーザーはそれしか見ない。つまり、いくらlogging APIを使ってユーザーにメッセージを伝えようとしても無駄であり、ユーザーにメッセージを伝えるにはInstallAnywhereのログを通してでないとダメと言うこと。

こんなわけで、InstallAnywhereが自動的に作成するLogにメッセージを追加する必要があるのだが、それにはcom.zerog.ia.api.pub.CustomErrorクラスを使えばよい。コードはこんな感じ:

CustomError error = (CustomError)proxy.getService(CustomError.class);
error.appendError("error message", CustomError.ERROR);
error.setLogDesciption("Description");
error.setRemedialText("Remedial Text");
error.log();
まず、proxyのgetServiceメソッドを使って、新しくCustomErrorクラスのインスタンスを作成する。このproxyはInstallerProxyやCustomCodePanelProxy、CustomCodeConsoleProxyで、CustomActionなどの引数で渡されてきているはず。

次に、取得したCustomErrorクラスのインスタンスに、ログのためのメッセージなどをセットする。詳しくはAPIドキュメントに書いてあるが、まあいろいろ設定できます。

最後に、log()メソッドを呼ぶことで、実際にログに書き込むように指示を行う。これを忘れると書き込まれないみたい。

ちなみに、上記のコードの場合、

Description
Status: FATAL ERROR
Additional Notes: FATAL ERROR - error message
というログになります。

CustomErrorの定数として、ERRORとFATAL_ERROR、それにWARNINGは用意されているが、SUCCESSに相当するものはないようだ。InstallAnywhereが勝手に作るログの中にはSUCCESSがあるのだが、これは自前のコードでは利用できないのだろうか?単純にTraceを取る目的には使用できないのかもしれない。あくまでエラー出力用か。まあ、単純にappendErrorを使わないでappendMessageにすればいいという話かもしれない。appendMessageならErrorを指定する必要がないから。


参考情報

http://apst.stsci.edu/apt/IA/InstallAnywhere_8.0_Enterprise/javadoc/overview-summary.html
http://apst.stsci.edu/apt/IA/InstallAnywhere_8.0_Enterprise/javadoc/com/zerog/ia/api/pub/CustomError.html