ryhmrt’s blog

意識低い系プログラマの雑記

JCIFSで複数NICが刺さっているサーバに繋がらないことがある

Javaで作ったシステムからWindowsの共有ファイルを読み書きするために、JCIFSってライブラリを使っているのだけれど、昔こいつでハマッたときのメモを発掘した。

実はつい先日も同じ現象に遭遇したのである。

頑張って調べてたなぁ、昔の自分。

JCIFSは、コンピュータ名からIPアドレスを解決する際に、ブロードキャストでPC名の問い合わせをするのだけれど、その際に嫌なことが起こっていた。

ブロードキャストで名前を問い合わせた際に、相手が複数のネットワークインターフェースを持っていると、レスポンスとして複数のアドレスが帰っているようなのだが、JCIFSはその中で最後に記述してあるものを使っている模様。

通信をしようとしているPCにはNICが2枚刺さっていたのだけれども、問題が発生した環境では、接続元のコンピュータからアクセスできないIPアドレスに繋げようとしていたようだ。

設定で解決する

JCIFSは名前解決に何を使うかの優先順位を決定するのに、jcifs.resolveOrderってプロパティを参照している。

デフォルトで「LMHOSTS,BCAST,DNS」(WINSがあれば「LMHOSTS,WINS,BCAST,DNS」)になっているので、これをDNS優先に設定してみた。(今回の環境にはDNSサーバが存在するので)

ライブラリの変更で解決する

※ 2009年1月時点のコードに対する対応策

jcifs.netbios.NameServiceClientクラスの getByName( Name name, InetAddress addr )メソッド が怪しい。

メソッドの冒頭のループ中にある、以下の返却処理を変更。

int last = response.addrEntry.length - 1;
response.addrEntry[last].hostName.srcHashCode = addr.hashCode();
return response.addrEntry[last];

以下のように書き換えてみた。

for (int j = 0; j < response.addrEntry.length; j++) {
    try {
        if (response.addrEntry[j].getInetAddress().isReachable(1000)) {
            response.addrEntry[j].hostName.srcHashCode = addr.hashCode();
            if (LogStream.level > 3)
                log.println(response.addrEntry[j].getInetAddress() + " is reachable.");
            return response.addrEntry[j];
        }
        if (LogStream.level > 3)
            log.println(response.addrEntry[j].getInetAddress() + " is not reachable.");
    } catch (IOException e) {
        if (LogStream.level > 3)
            e.printStackTrace(log);
    }
}
break;

何となくうまくいっている気がする。

でも、SMBプロトコルに関してろくな知識はないし、JCIFSのコードも把握しきっていないので、なんか勘違いしている可能性は捨てきれない。

InetAddress.isReachable()を使っているので、J2SE5.0以降でないと動かないのも悩ましいところ。 1.4じゃPureJavaでICMPを打つことができない。

でも、どうしても必要だったらJNI経由って手がある。 Linuxの例Windowsの例 を見つけた。

ActivePerlライセンス条約

昔、ActiveStateのサイトに載っていたライセンス条約を日本語訳したものを発掘しました。

ActivePerlはPARとかでバイナリを配布するが許されてるとかどっかに書いてあったのを見て、気になって翻訳したのでした。

箇条書きになっているライセンス条項の4番目がそれっぽかったです。

改めて見ると、OSSの懐の広さを感じるライセンスだなぁ。(私の理解が正しければ)

以下の文章はActiveStateのサイトに記載されていたライセンス条約(2008/05/19時点)を個人的に翻訳したものです。この翻訳文には効力は無いので、ライセンスの確認には必ず原文を参照してください。ちなみに、当方英語には全く自信がありません。


ActivePerlライセンス条約 (ActivePerl License Agreement)

ActivePerlはActivePerlライセンス条約により保護されます。

ActivePerl is covered by the ActiveState Community License.

注意 (Please note):

もしあなたがActivePerlの再配布を行う場合は異なるライセンスが必要です。 詳しい情報はActivePerl OEM ライセンスを参照するか、直接お問い合わせください

If you plan to redistribute ActivePerl you will need a different license. For more information please visit ActivePerl OEM Licensing or contact us directly.


ActiveStateコミュニティライセンス (ActiveState Community License)

前文 (Preamble):

本ライセンスは対象パッケージの複製、変更、配布、ならびに再配布における規約を規定します。 本ライセンスの趣旨は ActiveState Software Inc. ("ActiveState") が対象パッケージの開発と配布における管理権を保持することにあり、ユーザは許可される範囲で様々な用途にパッケージを使用することができます。
あなたには本ライセンスとは無関係にActiveStateと直接協定を結ぶことが常に許可されます。 本ライセンスの規定が許可しないパッケージの作成を行おうとする場合や、あなたが計画している特定のパッケージの使用法について明らかにしたい場合は、本ライセンスの確認や異なるライセンスの締結を要求するために sales@activestate.com にお問い合わせください。

This license establishes the terms under which the Package may be copied, modified, distributed and/or redistributed. The intent is that ActiveState Software Inc. ("ActiveState") maintains control over the development and distribution of the Package, while allowing the users of the Package to use the Package in a variety of ways. You are always permitted to make arrangements wholly outside of this license directly with ActiveState. If the terms of this license do not permit the full use that you propose to make of the Package or if you require clarification regarding your particular intended use of the Package, You should contact sales@activestate.com in order to seek clarification or to request a different licensing arrangement.

定義 (Definitions):

"ActiveState" は、このパッケージの著作権を有する ActiveState Software Inc. を指します。

"ActiveState" refers to ActiveState Software Inc., the copyright holder of the Package.

「パッケージ(原文:Package)」はActiveStateからリリースされた、ソースコード、実行可能なバイナリ、イメージ、スクリプトを含む(ただしそれに限定しない)ファイル(またはその派生物)の集合、あるいは個々のファイルを指します。

"Package" refers to those files, including, but not limited to, source code, binary executables, images, and scripts, which are distributed by ActiveState, and derivatives of that collection and/or those files.

「あなた」及び「あなたの」という表現はこのパッケージを複製、配布、または変更する人物を指します。

"You" and "your" means any person who copies, distributes, or modifies the Package.

  1. あなたはこのパッケージを無償で商用、または非商用に利用することができます。

    You may use this Package for commercial or non-commercial purposes without charge.

  2. あなたはこのパッケージの完全な(そのままの)複製を作成し受け渡すことを、個人的な利用、あるいはあなたの組織内での利用のために、原本の有する全ての所有権及び関連する放棄宣言の複製を含めることで許可されます。 あなたは前述されたActiveStateからの明文化された許可なしに、このパッケージ(またはこのパッケージに基づく)複製を配布すること、また「あなたの」行為によりこのパッケージの複製が配布されることを、あなたの組織の外の人物に施すことを許可しません。(ただし、彼らを本来の配布元に導くことは奨励されます)

    You may make and give away verbatim copies of this Package for personal use, or for use within your organization, provided that you duplicate all of the original copyright notices and associated disclaimers. You may not distribute copies of this Package, or copies of packages derived from this Package, or cause by Your actions copies of this Package to be distributed, to others outside your organization without specific prior written permission from ActiveState (although you are encouraged to direct them to sources from which they may obtain it for themselves).

  3. あなたはActiveStateから提供される不具合修正、機種依存修正などの変更を適用することができます。 これらにより修正されたパッケージについても本ライセンスの保護下に置かれます。

    You may apply bug fixes, portability fixes, and other modifications derived from ActiveState. A Package modified in such a way shall still be covered by the terms of this license.

  4. このライセンスはまた、PAR、PerlApp、Perl2Exeといったラッピングツールにより、アプリケーションの一部としてこのパッケージの一部が組み込まれて配布されることを許可します。
    ただし、このライセンスはあなたに (a) 完全なパッケージの再配布、(b) この一部を利用して言語の配布物を作成すること、(c) PerlScript、Perl for ISAPI、 PerlEx のいずれかの部品をあなたのアプリケーションと共に配布すること、を許可しません。

    The license also allows You to redistribute parts of the Package as part of an application generated by wrapping tools such as PAR, PerlApp or Perl2Exe. However, this License does not allow You to (a) redistribute the Package as a whole, (b) use its parts to create a language distribution, or (c) redistribute the PerlScript, Perl for ISAPI or PerlEx components with Your application.

  5. ActiveStateの名称及び商標は、前述されたActiveStateからの明文化された許可なしに、このパッケージから派生したパッケージの推奨、あるいは宣伝のために使ってはいけません。

    ActiveState's name and trademarks may not be used to endorse or promote packages derived from this Package without specific prior written permission from ActiveState.

  6. このパッケージは「ありのまま」の形で、あらゆる場面において(あらゆる制約無しに)、商品性、特定の目的に対する適合性に関した暗示的保障を含む、明示あるいは黙示された保障無しに提供されます。

    THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

ドメインが異なるページ間においてJavaScriptでデータをやりとりする

セキュリティ制限により、ドメインが異なるページ間ではJavaScriptでデータのやりとりをすることは(素直なやりかたでは)できない。

なんとか回避策はないものかと、昔試行錯誤してみたメモが掘り起こされたので掲載。

一言で言えば、URLパラメータでごにょごにょするというもの。

呼び出し元のページでは、callback関数を定義しておく

window.callback = function(msg){
  alert(msg);
};

で、他のドメインのページを開く

window.open(他のドメインのURL);

開いた先では、直接コールバックをせずに、パラメータ付きで元のドメインのあるページを開く

location.href = あるページのURL + '?' + escape(渡す値);

で、その遷移先のページでコールバック関数を呼んでやる

opener.callback(unescape(location.search.slice(1)));
window.close();

めんどくさい

ViユーザにもEmacsユーザにもなれなかったMac使いの小技

viとかemacsとか使ってる人はコマンドラインからエディタを立ち上げられて羨ましいと思っていたそこの貴方に。

# .zshrcとかに
alias edit='open -a BBEdit'

openコマンドというものがありまして、引数で指定したファイルをFinderでダブルクリックした時のように開いてくれるのですが、-aオプションで使用するアプリを指定することができます。

openコマンドはよく使っていたけれど、少し前に-aオプションのことを知ったのでした。

金なし、コネなし、フィリピン暮らし! 改訂版

最近読んでいる本は 「金なし、コネなし、フィリピン暮らし!改訂版」(イカロス出版/志賀和民著)

今度フィリピンで仕事をすることになっているので、この書籍から情報を仕入れています。

タイトルはけっこうふざけていますが、内容はしっかりしているように感じます。

現地に行ってからでないと、この本の内容が有用かどうかは判別できませんが。

Gitのリポジトリ眺めるのに便利なSourceTree

AppStoreをぼんやりと眺めていたら、SourceTreeというアプリが目に止まりました。 GitやMercurial、更にはSubversion(※)のリポジトリGUIから操作できるという代物。

Subversionはgit-svn経由

http://www.sourcetreeapp.com/

開発元を見たら、Bitbucketを傘下に収めたAtlassianの名前がありました。 しかしGitHub対応を謳っているので、GitHubでも安心して使えます。太っ腹。 というか、普通にGitクライアントなので当たり前ですね。

個人的には、コミットなどの操作はコマンドラインから行った方が便利だと思いますが、 履歴を眺めるには良いツールだと思います。特に履歴が入り組んでしまった時など。