Trouble 6: Linux/UNIX固有と思われる問題
<Q6-1>GUIのないプログラムなのにコンソールから実行するとAWT関連の例外が発生して実行できません。
| <発生環境> |
| OS |
RedHatLinux6.1/6.2 Solaris7 |
| JDK |
JDK1.3 |
| Vender |
Sun/IBM |
- <A6-1>
- javax.swing.Timerを使用していたことが原因です。java.util.Timerへ切り替えることで解決できます。これ以外に実行環境の設定(X-Windowの設定)を変更して対処することもできます。
<Q6-2>クラスファイルは完全なのにClassFormatErrorが発生してしまいます。
| <発生環境> |
| OS |
RedHatLinux6.2 SMP |
| JDK |
JDK1.3 |
| Vender |
Sun |
- <A6-2>
- 未解決:RedHatLinux6.2のSMPカーネルのみで起こる現象のようです。
<Q6-3>JavaをインストールしたがJavaのバージョンが変わりません。
| <発生環境> |
| OS |
Solaris |
| JDK |
ALL |
| Vender |
Sun |
- <A6-3>
- /usr/bin/javaはシンボリックリンクであるため、インストールしただけでは書き換わりません。そのため、シンボリックリンクを切り替える必要があります。
しかし、安易に/usr/bin/javaのシンボリックリンクを切り替えるとjavac等も同様に切り替える必要があるため、効率が悪いです。/usr/javaもシンボリックリンクのため、これを切り替えればjavaもjavacも切り替わります。/usr/javaを削除し、/usrで”ln -s ./j2se java”とするのがよいでしょう。
<Q6-4>VMのcoreをdbxで確認したいがdbxでELFイメージでないと言われ確認できません。
| <発生環境> |
| OS |
Solaris |
| JDK |
ALL |
| Vender |
Sun |
- <A6-4>
- /usr/bin/javaはシンボリックリンクであり、/usr/java/bin/javaもシンボリックリンクです。実際は以下のとおりとなっています。
/usr/bin/java → /usr/java/bin/java → /usr/java/jre/bin/.java_wrapper
.java_wrapperはシェルであり、以下の実体をVMとして起動しています。
/usr/java/jre/bin/sparc/native_threads/java
そのため、dbxを起動する際は以下のとおりに起動すれば情報が取得できます。
dbx
/usr/java/jre/bin/sparc/native_threads/java core
<Q6-5>Solarisにおいて、LANG=ja環境でスタックトレースを出力すると文字化けします。
以下のように出力されました。
java.net.ConnectException: →?陟命乖??霓??陟臓
鳧ava.net.ConnectException: →?陟命乖??霓??陟臓
鱇t java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:295)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:161)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:148)
at java.net.Socket.connect(Socket.java:425)
at java.net.Socket.connect(Socket.java:375)
at java.net.Socket.<init>(Socket.java:290)
at java.net.Socket.<init>(Socket.java:118)
at test.net.ExceptionTest.main(ExceptionTest.java:9)
| <発生環境> |
| OS |
Solaris8 |
| JDK |
JDK1.3.1_06/1.4.0_01 |
| Vender |
Sun |
<Q6-6>JDK1.4.1_01をインストールしたSolaris8でプログラムを実行したところ、正常に起動しませんでした。
コンソールに以下のエラーが出ました。
NoClassDefFoundError: sun.io.CharToByteJIS0208
(以下略)
| <発生環境> |
| OS |
Solaris8 |
| JDK |
JDK1.4.1 |
| Vender |
Sun |
- <A6-6>
- Solaris8に標準でインストールされているJDK(バージョンは1.3)にJDK1.4.1を上書きしてしまった為です。両バージョンとも、インストールディレクトリが/usr/j2seなので、JDK1.4.1を上書きインストール時するとJDK1.3のファイルが残り、この問題が発生します。
/usr/j2seディレクトリを削除し、再度JDK1.4.1をインストールすることで解決できます。インストール手順の詳細はJava 2 SDK インストールガイドを参照してください。
<Q6-7>特定のLinux上でプログラムを動かしているとHotSpot Virtual Machine Errorが発生します。
WindowsやLinux上で通常動作しているネットワークプログラムを特定のLinuxで動作させると
しばらくするとHotSpot Virtual Machine Errorが発生することがあります。
| <発生環境> |
| OS |
Redhat Enterprise Linux 4 |
| JDK |
JDK 1.5.0 |
<Q6-8>長期稼動しているJavaプロセスでjstatが動かなくなります。
稼働中のJavaのプロセス情報を確認するため定期的にjstatを実行しています。
長期間稼動中にjstatが"(pid) not found"と表示し、実行に失敗するようになりました。
jpsも該当のPIDを一覧化してくれません。
| <発生環境> |
| OS |
Linux, (Solaris) |
| JDK |
Java SE 5.0以降 |
- <A6-8>
- jstatやjpsは、Javaプロセスが立ち上げ時に作成するhsperfdataというファイルを参照して、
Javaプロセスの存在や、Javaプロセスの情報を取得します。
このhsperfdataファイルは、Linux/Solarisでは
/tmp/hsperfdata_(ユーザ名) 以下
に保存されます。
Linuxの一部ディストリビューションでは、/tmp 以下のファイル使用量を抑えるために、
一定条件を満たすファイルを自動的に削除するように設定されています。
hsperfdataファイルがこの削除条件に該当してしまうと、
自動的に削除されてしまい、jstatやjpsはJavaプロセスを認識できなくなります。
Solarisでも同様の問題がおきる可能性があります。
Linux/Solarisでは2008/07/01時点で、/tmp 以外の場所に変更する方法はありません。
問題を回避するには以下の2つの方法があります。
・/tmpファイル以下の自動削除の仕組みを止める。
・hsperfdataファイルが削除対象にならないようにする。
(常にhsperfdataファイルを参照するスクリプトを動かすなど)
/tmp ディレクトリの管理方法はディストリビューションによって異なるため、
使用されているディストリビューションのマニュアルを参照してください。
この記事の詳細な情報をJTSメールマガジンにて配信しています。
情報を取得したい方は、メールマガジンのバックナンバーを参照して下さい。
注意:本文書の内容に誤りがあり、またこの文書によって不利益を被っても、
エスエムジー株式会社は一切関知いたしません。