ロビー。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のすごい人からのツッコミを期待して…。