21.2.1 アプリケーションサーバのバージョン共通の注意事項
アプリケーションサーバのバージョンで共通のDeveloper's Kit for Javaに関する注意事項について説明します。
(1) OS共通の場合
OSで共通の注意事項について説明します。
-
Java SEの旧バージョンとの互換性について
Java SE 6は,Java SE(J2SE)の旧バージョンと,一部の機能に互換性がありません。詳細は,該当ページ(http://www.oracle.com/technetwork/java/javase/compatibility-137541.html)を参照してください。
-
Java SE 6でのそのほかの変更点について
Java SE 6でのそのほかの拡張および変更点については,該当ページ(http://www.oracle.com/technetwork/java/javase/releasenotes-136954.html)を参照してください。
-
JVMPIとJVMDIについて
JVMPIとJVMDIを廃止しました。これらの代わりにJVM TIを利用してください。
-
GCメモリ情報を取得する機能について
GCメモリ情報を取得するJP.co.Hitachi.soft.jvm.MemoryInfoクラスは,Developer's Kit for Javaで利用できます。ほかの製品では利用できません。
-
URLClassLoaderでのクラスのローディングについて
URLClassLoader経由でjarファイルからクラスをローディングする場合,ローディング処理中にJavaVMの内部で作成されるオブジェクトが,JavaVM終了時まで削除されないことがあります。適宜,Javaアプリケーションを再起動してください。
-
Java2Dの使用について
Java2DのDirectDrawおよびDirect3Dの問題を回避するため,DirectDrawとDirect3Dを無効にする,sun.java2d.noddrawプロパティに「true」を指定してください。
-
メソッド長の上限について
JavaVMの仕様によって,1メソッドのバイトコードは,64キロバイト以内にする必要があります。
64キロバイトを超えると,クラスファイル生成時にエラーとなるか,またはクラスのロード時にjava.lang.LinkageError例外が発生します。
また,64キロバイト以内であっても,非常に複雑で行数が多い場合は,次のような弊害が発生することがあります。
-
GC処理の実行に非常に時間が掛かる。
-
JITコンパイルに非常に時間が掛かる。
-
JITコンパイルに非常に多くのメモリを消費する。
さらに,ローカル変数情報出力機能が有効な場合は,次の弊害も発生することがあります。
-
拡張スレッドダンプの出力に時間が掛かる。
-
スレッドスタックトレースの取得に時間が掛かる。
-
例外発生時の例外オブジェクト生成処理に時間が掛かる。
そのため,Javaソース上の1メソッドの行数は,コメントや空行を除いて,およそ500行以内にすることをお勧めします。
-
-
直列化バージョンUID(serialVersionUID)について
JDK 1.4以降では,直列化可能な入れ子クラスにクラスオブジェクト(例えば,Class c = Object.class;)への明示的な参照が含まれている場合,入れ子クラスとそのクラスを包含するクラスの両方で,デフォルトの直列化バージョンUIDの値が,JDK 1.4より前のバージョンと異なります。これは,JDK 1.4で実施されたjavacコマンドの変更によるものです。これらの条件をすべて満たす場合には,直列化可能クラスに直列化バージョンUID(serialVersionUID)を追加してください。
-
ファイルディスクリプタのクローズについて
java.lang.Runtime.exec(),およびjava.lang.ProcessBuilder.start()で起動した子プロセスは,Process.getInputStream,getErrorStream,またはgetOutputStreamのそれぞれのメソッドで取り出したストリームを通じてプロセス間通信をします。
親プロセスでは,これらのメソッドを使わない場合でも三つのファイルディスクリプタを消費することに注意してください。
ファイルディスクリプタをクローズするのは次の場合です。
-
Processオブジェクトのファイナライズが完了した場合
-
Process.destroy()を呼び出した場合
-
これらストリームに対して明示的にclose()メソッドを呼び出した場合
-
-
システムプロパティjava.library.pathについて
システムプロパティjava.library.pathには,ユーザのネイティブライブラリの検索パスを指定します。デフォルト値を次に示します。
- Windowsの場合
-
"<JDKインストールディレクトリ>\bin,<システムディレクトリ>,<Windowsディレクトリ>,%PATH%,カレントディレクトリ"
- AIXの場合
-
環境変数LD_LIBRARY_PATHの設定値,JDK下のネイティブライブラリのディレクトリ,"/usr/lib:/lib"
- Linuxの場合
-
JDK下のネイティブライブラリのディレクトリ,環境変数LD_LIBRARY_PATHの設定値,"/usr/lib64:/lib64:/lib:/usr/lib"
-
ポジティブDNSキャッシュの保持時間について
JDKは,DNSへのホスト名解決の問い合わせ結果をキャッシュする機能を持ちます。キャッシュ機能には,解決成功の結果を保持するポジティブキャッシュと,解決失敗の結果を保持するネガイティブキャッシュがあります。
このうち,セキュリティマネージャが無効な場合だけ,DNSへの問い合わせ結果のポジティブキャッシュのデフォルト保持期間が,「永久にキャッシュ」から「実装依存」へ変更になりました。JDK 5.0と同様の挙動にする場合は,セキュリティプロパティnetworkaddress.cache.ttlの値を「-1」にしてください。詳細は,該当ページ(http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html)を参照してください。
-
インストゥルメンテーション機能が出力するメッセージについて
インストゥルメンテーション機能の処理中にメモリ不足になった場合,次のメッセージが出力され,インストゥルメンテーション機能の処理が失敗することがあります。詳細は,該当ページ(http://docs.oracle.com/javase/jp/1.5.0/api/java/lang/instrument/package-summary.html)を参照してください。
- メッセージの内容
-
*** java.lang.instrument ASSERTION FAILED ***
-
java.net.Socket.connect()のタイムアウトについて
java.net.Socket.connect()でのソケットの接続が,OSに設定されているTCP通信のタイムアウト値によってタイムアウトすることがあります。TCP通信のタイムアウト値になると,java.net.Socket.connect()に指定したタイムアウト値よりも前でも,タイムアウト値を指定していないときでも,接続がタイムアウトします。
TCP通信のタイムアウト値でタイムアウトした場合,次の詳細メッセージを含むjava.net.ConnectException例外がスローされます。
- メッセージの内容
-
Connection timed out: connect [errno=10060, syscall=select]
TCP通信のタイムアウトについては,OSのドキュメントを参照してください。
-
クラスロードのタイミングについて
Javaでのクラスファイルのメモリへの読み込み(クラスロード処理)は,プログラムの実行中に,そのクラスが初めて必要となったタイミングで実行されます。そのため,ある処理の初回実行でクラスロードの回数が多くなると,2回目以降と比較して,処理時間が長くなることがあります。この場合,処理の実行に必要なクラスを事前にロードすることで,処理時間が改善します。
-
異なるOS間で発生する文字化けについて
文字コードのUnicodeへのマッピングは,OSによって異なることがあります。このため,次の場合に文字化けが発生することがあります。文字化けが発生する代表的な文字には,—,〜,‖,−,¢,£,¬があります。
-
UTF-8などのUnicodeのエンコーディングを使用して,異なるOS間で上記文字データを受け渡す場合
-
上記文字を含む文字列リテラルがあるソースプログラムから作成したクラスファイルを,異なるOS上でリコンパイルしないでそのまま実行する場合
-
-
Java APIで使用するファイルについて
Java APIで使用するポリシーファイルや,ログイン構成ファイルなどのコンフィグレーションファイルは,UTF-8エンコーディング方式でエンコーディングする必要があります。
-
JNI関数で文字列操作をする場合のUTF-8エンコーディングについて
JNIの場合,次の文字列操作をする関数で使用するエンコーディングは,標準UTF-8ではなく,Modified UTF-8です。
-
NewStringUTF
-
GetStringUTFLength
-
GetStringUTFChars
-
ReleaseStringUTFChars
-
GetStringUTFRegion
-
-
if文の判定でジャンプできる長さの上限について
JavaVMの仕様によって,if文の判定でジャンプできる長さは32キロバイトまでです。ジャンプ先が32キロバイトを超える場合は,java.lang.LinkageErrorとなります。
-
ファイルサイズの上限について
java.util.zip,java.util.jarパッケージでは,4ギガバイトを超えるJARファイルやZIPファイルはサポートしていません。
-
java.nio.channels.FileChannelクラスのmap,transferFrom,およびtransferToメソッドについて
mapメソッドでは,2ギガバイトを超えるファイルはサポートしていません。
また,transferFromおよびtransferToメソッドでのcount指定では,2ギガバイト以上の値はサポートしていません。
-
スレッドのスタックサイズについて
JNI関数AttachCurrentThread()などを使用して,ネイティブスレッドをJavaVMに接続する場合は,-Xssオプションの指定値よりも大きなスタックサイズのスレッドで接続してください。
-
JavaプロセスがSSL/TLS通信のクライアントとして動作する場合の注意点について
SSL/TLSを使った通信相手のプロトコルを変更した場合,通信に失敗するおそれがあります。
通信相手(サーバ)側で使用できるSSL/TLSプロトコルバージョンを変更したあと,クライアント側のJavaプロセスを再起動しないでSSL/TLSを使った通信をしようとした場合,クライアント側のJavaプロセスで例外が発生して通信に失敗するおそれがあります。
これは,既知の接続先に対して以前接続に成功したプロトコルの情報がクライアント側に残っていると,そのプロトコルバージョンでSSL/TLS通信を試みる,という挙動によるものです。
通信相手が使用できるSSL/TLSプロトコルバージョンを変更する場合は,クライアント側のJavaプロセスを再起動してください。
また,通信相手(サーバ)側で使用できるSSL/TLSプロトコルバージョンを変更したあと,クライアント側のJavaプロセスを再起動しないで通信が失敗した場合は,対象のJavaプロセスを再起動してください。
(2) Windowsの場合
Windowsでの注意事項について説明します。
-
AWTコンポーネントでのJIS X0213:2004の第三水準,第四水準文字の非サポートについて
AWTコンポーネントはJIS X0213:2004の第三水準,第四水準文字をサポートしていません。AWTコンポーネントが出力する情報で該当する文字の部分は文字化けします。Windows環境で該当する文字を扱う場合には,Swingコンポーネントを使用してください。
-
JavaVMログファイルのGC経過時間について
JavaVMログファイルのGC経過時間は,秒単位で小数点以下第7位(100ナノ秒)まで出力されます。
Windowsの場合,08-70より前では,小数点以下第7位(100ナノ秒)まで有効な数値が出力されていました。08-70以降では,小数点以下第6位(1マイクロ秒)まで有効な数値が出力され,小数点以下第7位(100ナノ秒)には常に0が出力されます。
-
JNIプログラム中で使用できないライブラリについて
JavaVM内で管理している情報が不正に更新されることがあるため,JNIプログラム中で次のライブラリは使用できません。
-
setjmp()
-
longjmp()
-
-
java.io.tmpdirプロパティについて
java.io.tmpdirプロパティには,書き込み権限があり,かつ存在するディレクトリを指定してください。java.io.tmpdirプロパティの初期値は,Windows APIのGetTempPath()関数で得られるディレクトリです。
また,Java RMIの動的クラスローディング機能やJava APIのjava.io.File.createTempFile()では,java.io.tmpdirプロパティで指定されたディレクトリに一時ファイルを作成します。これらの機能を正常に動作させるため,JavaVMプロセス起動中は一時ファイルの作成先を削除しないでください。
-
管理者特権が必要な独立プロセスの起動について
管理者特権のないユーザで起動したjavaアプリケーションから,java.lang.Runtime.exec(),またはjava.lang.ProcessBuilder.start()で,管理者特権のある独立プロセスを起動する場合は,次の手順で起動してください。
-
管理者特権として起動するコマンドにマニフェストを追加します。マニフェストの追加方法については,OSのドキュメントを参照してください。
-
Windowsのcmd.exeを介してプロセスを起動します。
例えば,sample.exeを起動する場合には次のようになります。
・Runtime.getRuntime().exec("cmd.exe", "/c", "sample.exe");
・new ProcessBuilder("cmd.exe", "/c", "sample.exe").start();
このjavaアプリケーションを起動すると,[ユーザー アカウント制御]ダイアログが表示されるので,[続行]をクリックしてアプリケーションを続行してください。
-
-
java.util.prefs.Preferences.systemNodeForPackageによるデータ共有について
管理者特権のないユーザが,java.util.prefs.Preferences.systemNodeForPackageを使用した場合,異なるユーザ間でのデータ共有機能は使用できません。
例えば,同一のキーを引数に指定した場合,異なるユーザ間では異なったデータが返ります。
-
デフォルトエンコーディングについて
アプリケーションサーバのデフォルトエンコーディングはwindows-31j(別名:MS932)です。
-
エンコーディング時に発生する文字化けについて
次に示す文字をjavaプログラムで扱う場合,エンコーディングにMS932,windows-31j,cswindows31jのどれかを指定してください。それ以外のエンコーディングを指定した場合,文字化けすることがあります。
(例)
このプログラムは,IBM拡張文字をeucjisでエンコーディングしているため,実行すると次のように文字化けします。
java encode_eucjis ???
文字化けを回避するためには,MS932,windows-31j,cswindows31jのどれかを指定してエンコーディングしてください。
-
JavaがサポートするUTF-8エンコーディングについて
JavaがサポートするUTF-8エンコーディングは,BOMなしのUTF-8です。Windowsのテキストエディタ(メモ帳)で「文字コード」に「UTF-8」を指定して保存したデータは,BOMありのUTF-8となるため,Javaでは扱えません。
(3) UNIX共通の場合
UNIXで共通の注意事項について説明します。
-
forkシステムコールについて
JNIやJVMTIで呼び出されるネイティブメソッド,またはネイティブコードで,fork()システムコール発行だけで現行プロセスのコピーの子プロセスを生成,または実行した場合,その親子プロセスの動作は保証できません。fork()システムコール発行による子プロセス生成後は,必ずexec()システムコールで新規プログラムをローディングしてから起動してください。また,Java環境下で子プロセスを生成する場合には,Javaクラスライブラリのjava.lang.Runtime.exec()メソッドを使用することをお勧めします。
-
シグナルについて
JNIやJVMTIで呼び出されるネイティブメソッド,またはネイティブコードで,次のシグナルに対してシグナルハンドラを登録した場合,動作は保証しません。
SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGFPE,SIGBUS,SIGSEGV,SIGPIPE,SIGTERM,SIGUSR2,SIGCHLD,SIGXCPU,SIGXFSZ,(_SIGRTMAX-2)番のシグナル
-
システムライブラリ関数やシステムコール呼び出し中のシグナル受信について
システムライブラリ関数やシステムコール呼び出し中に,次のシグナルを受信することがあります。
SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGFPE,SIGBUS,SIGSEGV,SIGPIPE,SIGTERM,SIGUSR2,SIGCHLD,SIGXCPU,SIGXFSZ,(_SIGRTMAX-2)番のシグナル
システムライブラリ関数やシステムコールを呼び出す場合,該当する関数の処理が,これらのシグナル受信によって中断されて,エラーリターン(errno値にEINTRが設定されるなど)することがあります。この場合は,適切な処置(例えば,再実行など)を実施してください。
-
JNIプログラム中で使用できないライブラリについて
JavaVM内で管理している情報が更新されて不正な情報となる場合があるため,JNIプログラム中で次のライブラリは使用できません。
-
setjmp()
-
longjmp()
-
_setjmp()
-
_longjmp()
-
sigsetjmp()
-
siglongjmp()
-
-
Windowsとの文字データの受け渡しについて
Windowsとの文字データの受け渡しをする場合には,エンコーディングにMS932,windows-31j,cswindows31jのどれかを指定してください。
Shift_JISやSJISを指定すると,次の文字が不正な文字コードに変換されます。
-
生成できるスレッド数の上限値について
システム全体で生成できるスレッド数の上限は,/proc/sys/kernel/threads-maxです。また,1ユーザ当たりの生成できるスレッド数の上限は,/etc/security/limits.confのnprocの値(ulimit -uと同じ)となります。システムに応じて,これらの値を調整してください。
-
通知待ちのモニタ数について
JVMTIインタフェースを使用して取得した,通知待ちのモニタ情報が不正となる場合があります。
(4) AIXの場合
AIXでの注意事項について説明します。
-
Runtime.execの例外メッセージについて
Runtime.execで例外が発生した場合,エラーメッセージが文字化けすることがあります。
-
java.security.SecureRandomクラスについて
SecureRandomクラスが使用するOSの乱数生成器のデフォルトは/dev/urandomファイルです。java.security.egdプロパティにfile:/dev/randomを指定すると,/dev/randomファイルを使用できます。ただし,/dev/randomファイルを使用した場合,OSの乱数生成速度には限度があります。このため,SecureRandomクラスが/dev/randomファイルから乱数を取得する,次の処理を短い時間間隔で実施すると,OSによる乱数生成完了まで処理が完了しないので注意してください。
-
SecureRandomクラスのgenerateSeed()メソッド呼び出し時
-
SecureRandomクラスのgetSeed()メソッド呼び出し時
java.security.egdプロパティについては,該当ページ(http://docs.oracle.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html)を参照してください。
-
-
java.awt.printによる印刷サポートについて
Developer's Kit for Javaのjava.awt.printパッケージ印刷APIがサポートするAIX印刷サブシステムは,System V印刷サブシステムです。印刷APIを使用する場合は,次の方法でSystem V印刷サブシステムを設定してください。
-
smit printerコマンドを実行します。
-
[印刷スプーリング]−[現在の印刷サブシステムの変更/表示]−[現在の印刷サブシステム]を選択し,TabキーでSystemVに変更します。
-
-
環境変数LANGについて
環境変数LANGに次の値以外の値を指定している場合,java.nio.channelsパッケージで出力される例外メッセージが文字化けすることがあります。
-
C
-
POSIX
-
-
java.io.tmpdirプロパティについて
java.io.tmpdirプロパティには,書き込み権限があり,かつ存在するディレクトリを指定してください。java.io.tmpdirプロパティの初期値は/tmpです。
また,Java RMIの動的クラスローディング機能やJava APIのjava.io.File.createTempFile()では,java.io.tmpdirプロパティで指定されたディレクトリに一時ファイルを作成します。これらの機能を正常に動作させるため,JavaVMプロセス起動中は一時ファイルの作成先を削除しないでください。
-
デフォルトエンコーディングについて
アプリケーションサーバのデフォルトエンコーディングを次に示します。
LANGがCまたはPOSIXのとき:ISO8859_1
LANGがja_JP,ja_JP.IBM-eucJPのどちらかのとき:Cp33722C
LANGがJa_JP,Ja_JP.IBM-943のどちらかのとき:Cp943C
LANGがJa_JP.IBM-932のとき:Cp942C
LANGがJA_JP,JA_JP.UTF-8のどちらかのとき:UTF8
(5) Linuxの場合
Linuxでの注意事項について説明します。
-
半角カタカナについて
JIS X 201で制定されている文字のうち,半角カタカナはJavaSEのAPIを使用したGUIの実装では利用できません。
-
java.security.SecureRandomクラスについて
/dev/randomファイルがあるプラットフォームでは,SecureRandomクラスの一部のAPIで/dev/randomファイルからOSが生成した乱数を取得します。/dev/randomファイルから乱数を取得するのは,次の条件がすべて重なる場合です。
-
java.security.egdプロパティまたはjava.securityファイル中のsecurerandom.sourceにfile:/dev/random/を指定する
-
SecureRandomクラスのgenerateSeed()メソッドまたはgetSeed()メソッドを呼び出す
OSの乱数生成速度には限度があります。このため,短い間隔で乱数の取得処理を実行すると,OSによる乱数生成完了まで処理が完了しないので注意してください。
-
-
java.io.tmpdirプロパティについて
java.io.tmpdirプロパティには,書き込み権限があり,かつ存在するディレクトリを指定してください。java.io.tmpdirプロパティの初期値は/tmpです。
また,Java RMIの動的クラスローディング機能やJava APIのjava.io.File.createTempFile()では,java.io.tmpdirプロパティで指定されたディレクトリに一時ファイルを作成します。これらの機能を正常に動作させるため,JavaVMプロセス起動中は一時ファイルの作成先を削除しないでください。
-
デフォルトエンコーディングについて
アプリケーションサーバのデフォルトエンコーディングを次に示します。
LANGがCまたはPOSIXのとき:US-ASCII(別名ASCII)
LANGがjp_JP,jp_JP.eucJP,ja_JP.ujis,japanese,japanese.eucのどれかのとき:x-euc-jp-linux(別名EUC_JP_LINUX)
LANGがja_JP.utf8のとき:UTF-8(別名UTF8)