このページで解決しない高度なJavaのシステム障害はJaTSにお任せください

Trouble 13: 例外が発生します



<Q13-1>DateFormat.getDateInstance()で取得したインスタンスで日付文字列をパースしたところ、ParseExceptionが発生します。

しかし、地域(またはLANG)の設定によっては発生しないこともあります。

<発生環境>
OS Any
JDK Any
Vender Any
<A13-1>
ロケールの設定が異なると、日付文字列のパースに失敗する可能性があります。
状況によって、以下のようにする必要があると考えられます。

(特定のロケールに依存した文字列をパースする場合)
DateFormat.getDateInstance(int, Locale) など、Localeを引数に持つメソッドを使用してロケールを明示的に指定する。

(特定のフォーマットに従った文字列をパースする場合)
DateFormatのサブクラスであるSimpleDateFormatクラスに対し、フォーマット文字列を明示的に指定して使用する。ミリ秒などを含む文字列をパースする場合などが該当します。

Localeクラス、SimpleDateFormatクラスの詳細はAPIリファレンスを参照してください。
(フォーマット文字列の詳細はSimpleDateFormatクラスの説明として記述されています)
Page Top

<Q13-2>RMI通信時に、jarファイルの中に該当クラスが含まれているにもかかわらず、クラスローディングに失敗し、java.rmi.UnmarshalExceptionが発生してしまいます。

RMI通信時に、jarファイルの中に該当クラスが含まれているにもかかわらず、クラスローディングに失敗し、java.rmi.UnmarshalExceptionが発生してしまいます。

<発生環境>
OS RedHatLinux6.2 SMP
JDK JDK1.3.0
Vender Sun
<A13-2>
適切な解決策は不明です。
クラスパス上に、展開したclassファイルを置いたところ、ローディングできました。
プラットフォーム、JDKのバージョンは異なりますが、酷似した問題が、BugParade:4250650に存在しています。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4250650
Page Top

<Q13-3>JDK1.3で動作していたプログラムをJDK1.4で実行したところ、Naming.bind()で例外が発生しました。

以下の例外が発生しました。

java.net.MalformedURLException: invalid URL string: 
rmi://192.0.0.1:21000/Some Host
    at java.rmi.Naming.parseURL(Naming.java:266)
    at java.rmi.Naming.bind(Naming.java:104)

    - 中略 -
Caused by: java.net.URISyntaxException: 
    Illegal character in path at index 26: 
    rmi://192.0.0.1:21000/Some Host
    at java.net.URI$Parser.fail(URI.java:2701)

    - 後略 -

<発生環境>
OS Solaris8
JDK JDK1.4
Vender Sun
<A13-3>
URLに空白を含んでいる為です。

JDK1.3.1までは、エスケープされていない空白を含んだURLをjava.net.URLクラスは許していました。
しかし、JDK1.4から空白を含んだURLに対して、Namingクラスが例外をスローするように修正されました。
(エスケープしていない空白文字はRFC2396に違反します。)

問題の詳細は、BugParade:4641504を参照してください。

参考URL:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4641504
Page Top

<Q13-4>メモリが不足していないのに、OutOfMemoryErrorが発生します。

アプリケーションでOutOfMemoryErrorが発生しています。
jstatやhprofでメモリの使用状況を確認しましたが、特にメモリリークはしていない様です。
ソースコードにも、メモリリークを引き起こすような問題は見付かりません。

<発生環境>
OS Any
JDK 5.0 Update6
Vender Sun
<A13-4>
J2SE 5.0での仕様変更が原因である可能性があります。
J2SE 5.0では、ガベージコレクタのデフォルトが、パラレルコレクタに変更されています。

パラレルコレクタでは、一定量のヒープのコレクションに一定時間以上かかると、実際にはヒープが十分に残っていても、OutOfMemoryErrorをスローします。

※一定量、一定時間の指定には、Javaの起動オプションに以下を指定します。
-XX:GCTimeLimit=<一定時間> -XX:GCHeapFreeLimit=<一定量>

パラレルコレクタではなく、シリアルコレクタを使用することが対処方法となります。
(Javaの起動オプションに-XX:+UseSerialGCを指定する。)

GCTimeLimitを指定する方法も考えられますが、適切な値を検討する必要があります。

# 何らかの理由でパラレルコレクタを使用する必要がある場合、
# -XX:-UseGCTimeLimitを指定すると、この原因によるOutOfMemoryを回避する
# 事ができます。
# ただし、この方法は正式にはドキュメント化されていないため、リスクを
# 考慮して使用する必要があります。

参照URL:
http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/vm/gc-ergonomics.html
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5024647
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4976274
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6190472
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6185487
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6287810
Page Top

<Q13-5>Sunが公開しているftpクラスで複数ファイルを転送しようとすると例外が発生します。


<発生環境>
OS Linux
JDK JDK1.3
Vender Sun
<A13-5>
Sunの公開しているftpクラスが、ファイル転送後にsocketをクローズしていないのが原因です。logoff(bye)をすればsocketはクローズされるため、不具合ではなく、仕様である可能性もあります。
なお、このftpクラスはSunが参考のために公開していたクラスのため、Sunのサポート対象外となっています。
現在、この不具合(?)が直っているかどうかは不明です。
Page Top

<Q13-6>MappedByteBufferを使用していると、メモリが足りなくなります。

ファイルへの高速アクセスのために、java.nio.MappedByteBufferを使用してアプリケーションを作成しています。

必要な時にMappedByteBufferを初期化し、不要になった時点でcloseしていますが、実行中に以下の例外が発生してしまいます。

java.io.IOException: このコマンドを実行するのに十分な記憶域がありません。
   at sun.nio.ch.FileChannelImpl.map0(Native Method)
   at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:742)
   at mappedbytebuffer.TestMemoryMapping.main(TestMemoryMapping.java:22)
どんな原因が考えられますか?

<発生環境>
OS Windows XP SP2
JDK 5.0 Update4
Vender Sun
<A13-6>
MappedByteBufferを使用すると、JavaVMプロセスのアドレス空間中に連続したメモリ領域を確保します。
このメモリの確保に失敗すると、Qの例外が発生します。

MappedByteBufferは、ガベージコレクトされるまで確保したメモリ領域を解放しない仕様になっています。
つまり、仮にバッファをcloseしたとしても、その時点ではメモリ領域の解放は行われません。
ガベージコレクトが実行されればメモリ領域は解放されますが、MappedByteBufferの使用するメモリ領域は通常のJavaオブジェクトとは別の所に確保されるので、ガベージコレクトの契機にはならない場合があります。

その結果、Javaオブジェクトを保存するメモリ領域(heap)は十分でも、MappedByteBufferの使用するメモリ領域が不十分になり、Qの例外が発生することがあります。

MappedByteBufferを使用するのは、システム終了までリソースを解放しなくても良い場合に限るべきです。
例えば、システムで使用する大量のデータを、リングバッファとして保持する場合に使用するなどはMappedByteBufferの好例でしょう。
Page Top

<Q13-7>Tomcat5上でcommons-loggingを使ったウェブアプリケーションのデプロイが例外発生して失敗してしまいます。

Tomcat5上でcommons-loggingを使ったウェブアプリケーションを読み込むとNullPointerExceptionが発生してデプロイ終了してしまう場合があります。

<発生環境>
JDK 1.5.0
Tomcat 5.5
<A13-7>
これはcommons-loggingのVersion 1.1を利用している場合に発生する問題です。
commons-loggingのClass Loaderの問題で発生します。

これを回避するためには、commons.loggingのVersionを1.0.4に変更する必要があります。

参考URL:
https://issues.apache.org/bugzilla/show_bug.cgi?id=39631

参考)

以下のエラーメッセージは、commons.loggingとLog4jをTomcatで利用した場合の
スタックトーレスの出力例です。

java.lang.NullPointerException
  at org.apache.log4j.Category.isEnabledFor(Category.java:746)
  at org.apache.commons.logging.impl.Log4JLogger.isTraceEnabled
  (Log4JLogger.java:327)
  at org.apache.catalina.startup.TldConfig.tldScanResourcePaths
  (TldConfig.java:581)
==== 以下省略 ==== 

Page Top

注意:本文書の内容に誤りがあり、またこの文書によって不利益を被っても、
Acroquest Technology 株式会社は一切関知いたしません。

  • 現象別Index
  • 原因別Index

Find Bugsバグ詳細

Find Bugs Bug Descriptions日本語版

RSSで更新情報を取得する

RSSとは、ホームページの更新情報を配信する為のフォーマットです。
RSSを利用すると、登録したページの情報が更新された場合に、更新情報を自動的に受け取る事ができます。

詳細

弊社小森が執筆致しました

Javaでオブジェクト指向開発

Javaプログラミング言語習得において、新人プログラマーの最初の障害は「オブジェクト指向の壁」です。
本書は、Javaのソフトウェア開発を中心に事業を発展させてきたAcroquest社の新人教育セミナーを加筆・書籍化したもので、大卒の新人に対して、ゼロからJava言語を教えてきた実績をフィードバックしています。

メールマガジン配信中

Javaトラブルシューティングのメルマガをはじめました!是非ご購読ください

詳細