ロビー。1年くらい前から出ている,ロビーから落とされる現象を調査しているが,未だ原因分からず。とりあえずここにコードを載せてみる。いろいろ省略してるけど,イメージ的にはこんな感じ。ロビーのユーザ名とパスワードを管理するクラス。
public class LobbyTable
{
Map _users = new HashMap();
public LobbyTable()
{
// ファイルからユーザ名とパスワードを読み込んで_usersを初期化。
// 実装は省略
load();
}
public synchronized boolean login(String name, String password)
{
if(_users.get(name) == null)
{
_users.put(name, password);
// ファイルにユーザ名とパスワードを書き込む
// 実装は省略
save();
}
else
{
if(password.equals((String)_users.get(name)))
{
return true;
}
else
{
return false;
}
}
}
public synchronized void changePassword(String name, String password)
{
_users.put(name, password);
// ファイルにユーザ名とパスワードを書き込む
// 実装は省略
save();
}
}
で,発生するエラーが以下。
java.lang.NullPointerException
at Lobby.LobbyTable.changePassword (LobbyTable.java:91)
…
HashMap.putの引数は2つともNULL可なのでnameとpasswordは関係ない。実際デバッグコードを入れてもNULLにはなっていない。java.util.HashMapのソースコードを見ても特にNullPointerExceptionが発生しそうなところはない。残るのは_usersがNULLの可能性だけだが…。同期処理で失敗して,っていうのが考えられそうだが,それだとsynchronizedMapを使えば解決するのかもしれない。でも原因が分からないまま変えるのも気持ち悪い。
発生確率はかなり低め。ロビーが混んでるときに起こりやすいかも知れない。Javaのすごい人からのツッコミを期待して…。