- PR -

エラーメッセージの文字化け

投稿者投稿内容
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2005-01-05 10:05
いつもお世話になっております。
Solaris上であるJavaのプログラムを実行すると例外が発生してエラーメッセージがコンソールに出力されるのですが日本語の部分が文字化けしてしまって読むことができません。
このエラーメッセージの内容をなんとか知りたいのですが読めるようにすることは可能でしょうか?
例外はjava.lang.UnsatisfiedLinkErrorが発生していて以下のようにファイルに落としてPC上のテキストエディタで表示してみたのですがやはり文字化けしてダメでした。

FileOutputStream fo=new FileOutputStream("java_err.txt");
PrintStream ps=new PrintStream(fo);
ps.println(ex.getMessage());

ちなみにSolarisにはWindowsクライアントPCからTeraTermというターミナルソフトでログイン、実行しています。javaのバージョンは1.4.2です。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-05 10:14
TeraTerm の文字セットを変更して試してみてはいかがでしょうか?または LANG を Cにして実行するとか、エラー出力をファイルへリダイレクトしておくとか。

なお、UnsatisfiedLinkError は多くの場合複数のクラスローダで同一のネイティブライブラリを呼び出そうとした場合に発生します。

ネイティブライブラリを読み込むクラス(System.loadLibrary()してるヤツ)をシステムクラスパスに通すと解消されたりしますよ。

[ メッセージ編集済み 編集者: インギ 編集日時 2005-01-05 10:14 ]
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2005-01-05 11:25
インギさん、早速の回答ありがとうございます。
LANGをCにしたら英語のメッセージに変わって読めるようになりました。

>ネイティブライブラリを読み込むクラス(System.loadLibrary()してるヤツ)をシステムクラスパスに通すと解消されたりしますよ。
>
システムクラスパスというのがイマイチよく分からないのですがここに置くのはjarファイルで、soのようなネイティブライブラリではないですよね?
soはLD_LIBRARY_PATHを通しておけばどこに置いてもかまわないですか?
あとシステムクラスパスに置いたjarは環境変数CLASSPATHを通しておかなくても良いのでしょうか?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-05 13:43
あ、混乱させてしまったかもしれません。
クラスローダの問題の他にもパスに通っている.so のバージョンがちがう、とかLD_LIBRARY_PATHに .so が配置されてない、とかでも発生すると思います。

>あとシステムクラスパスに置いたjarは環境変数CLASSPATHを通しておかなくても良いのでしょうか?
システムクラスパスって CLASSPATH 環境変数か -cp / -classpath で指定するパスのことです。

>soはLD_LIBRARY_PATHを通しておけばどこに置いてもかまわないですか?
はい。どんな環境変数に設定するかはOSによりますがSolarisであればそうですね。あともちろん適切な権限も必要です。

[ メッセージ編集済み 編集者: インギ 編集日時 2005-01-05 13:52 ]
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2005-01-05 15:09
>システムクラスパスって CLASSPATH 環境変数か -cp / -classpath で指定するパスのことです。
>
すみません、システムクラスローダとシステムクラスパスを混同していたかもしれません。
システムクラスパスとクラスパスは同意語ですか?
インギさんの以下の発言は単にクラスパスに通しなさいということでしょうか?

>ネイティブライブラリを読み込むクラス(System.loadLibrary()してるヤツ)をシステムクラスパスに通すと解消されたりしますよ。
>
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-06 04:56
>システムクラスパスとクラスパスは同意語ですか?
この場合概ね同義語です。
厳密にはJVM起動オプションとして -cpや-classpath で与えるのクラスパスにいくつか暗黙的に追加されるライブラリ(rt.jarとかi18n.jarとか)を含んだのがシステムクラスパスですね。

ただし、クラスパスってのはクラスを検索する対象のパスとしてもうすこし広く使われることがあります。例えばWebアプリケーションの WEB-INF/libやWEB-INF/classes 以下に配置されているライブラリ、クラスとかも「Webアプリケーション実行時に暗黙的にクラスパスに追加される」などというものですから「JVMの起動オプションとして明示的に指定するクラスパス」と区別するために「システムクラスパス」という言葉を使いました。

>インギさんの以下の発言は単にクラスパスに通しなさいということでしょうか?
はい。そうです。というのは私がよく見る事例として、Webアプリケーションで WEB-INF/lib 以下にネイティブライブラリを利用するクラスが含まれていて、Webアプリケーションの再デプロイ時にこのエラーが発生するというものがあるからです。
これは同一のネイティブライブラリを読み込むクラスローダは1JVM上で一つでないといけないというJVM の制約から発生します。これに該当するのであれば当該クラスをシステムクラスパスに含めることで解決します。

これに該当しない場合はLD_LIBRARY_PATH変数と.soの配置、権限、またネイティブライブラリのバージョンを確認しましょう。
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2005-01-06 13:32
すみません、頭が悪いものでまだよく分かりません。

>Webアプリケーションの再デプロイ時にこのエラーが発生するというものがあるからです。
>これは同一のネイティブライブラリを読み込むクラスローダは1JVM上で一つでないといけない>というJVM の制約から発生します。これに該当するのであれば当該クラスをシステムクラスパ>スに含めることで解決します。
>
つまり WEB-INF/libやWEB-INF/classes 以下に配置すると暗黙的にクラスパスに追加されるけどそれでは不十分で、自分で明示的に環境変数CLASSPATHにパスを含める必要があるという理解であっていますか?

この話題でインギさんの投稿がある過去ログを拝見させて頂いたのですが環境変数CLASSPATHにパスを通せばシステムクラスローダが読み込んでくれると考えてよろしいのでしょうか?

また、サーブレットからJNIを使うには、server_root/classesにJNIを使うクラスを置かなくてはならないという話を聞いたことがあるのですがなにかご存じないでしょうか?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-06 17:54
>つまり WEB-INF/libやWEB-INF/classes 以下に配置すると暗黙的にクラスパスに追加されるけどそれでは
>不十分で、自分で明示的に環境変数CLASSPATHにパスを含める必要があるという理解であっていますか?
不十分、というかCLASSPATH環境変数に含めたら WEB-INF 以下に配置する必要はありません。重複したクラスが配置されていると結構混乱します。
CLASSPATH環境変数に含めたならそのクラスは WEB-INF 以下には配置しないことをお勧めします。
#実際のところ配置してもしなくても関係ありませんが。

>この話題でインギさんの投稿がある過去ログを拝見させて頂いたのですが環境変数CLASSPATHにパスを通せ
>ばシステムクラスローダが読み込んでくれると考えてよろしいのでしょうか?
はい。その通りです。

>また、サーブレットからJNIを使うには、server_root/classesにJNIを使うクラスを置かなくてはならないと
>いう話を聞いたことがあるのですがなにかご存じないでしょうか?
server_root/classes ってどこですか?
なんかの製品特有の話でしょうか?
その製品で起動スクリプトで server_root/classes がクラスパスに含まれる仕組みになっているのであれば私が言っていることと同義だと思います。
まず試してみてはいかがでしょうか。

スキルアップ/キャリアアップ(JOB@IT)