Редактировать: Мне удалось исправить это, изменив val
на lazy val
в классе MessageParser.Я забыл, что ранее я тестировал его, используя def
вместо val.
Может кто-нибудь прояснить, почему это изменение исправляет это?
Итак, я сейчас пишу IRC-сервер.Я решил использовать библиотеку Scala Combinator Parser, чтобы помочь мне разобрать сообщения.Мне удалось правильно проанализировать сообщение с помощью тестовой программы, но когда я попытался встроить свой синтаксический анализатор в эхо-сервер, который я уже написал, я получаю следующее сообщение об ошибке при установлении соединения с моим сервером:
Connected to the target VM, address: '127.0.0.1:55567', transport: 'socket'
Exception in thread "main" java.lang.ExceptionInInitializerError
at IRCServer.main(IRCServer.scala)
Caused by: java.lang.NullPointerException
at messages.MessageParser.<init>(MessageParser.scala:11)
at net.Connection.<init>(Connection.scala:14)
at net.Server.start(Server.scala:14)
at IRCServer$.<init>(IRCServer.scala:12)
at IRCServer$.<clinit>(IRCServer.scala)
... 1 more
Disconnected from the target VM, address: '127.0.0.1:55567', transport: 'socket'
Класс Connection обрабатывает сокет слушателя, созданный из ServerSocket
class Connection(socket: Socket) extends Thread {
private val out = new PrintStream(socket.getOutputStream)
private val in = new BufferedReader(new InputStreamReader(socket.getInputStream))
private val parser = new MessageParser
override def run(): Unit = {
var line = ""
while({(line = in.readLine); line != null}) {
Console.println("received: " + line)
parser.parseLine(line.trim)
out.println("out: " + line)
}
}
}
И вот мой MessageParser:
class MessageParser extends JavaTokenParsers {
def parseLine(line :CharSequence) = {
parseAll(message, line)
}
val message: Parser[Any] = opt(":"~prefix)~command~opt(params) ^^ (x=> {println("message: "+x)})
val prefix: Parser[Any] = nick~"!"~user~"@"~host | servername ^^ (x=> {println("prefix: " +x)})
val nick: Parser[Any] = letter~rep(letter | wholeNumber | special) ^^ (x=> {println("nick: " +x)})
val special: Parser[Any] = "-" | "[" | "]" | "\\" | "`" | "^" | "{" | "}" ^^ (x=> {println("special: " +x)})
val user: Parser[Any] = """[^\s@]+""".r ^^ (x=> {println("user: " +x)})
val host: Parser[Any] = """[\w\.]+\w+""".r ^^ (x=> {println("host: " +x)})
val servername: Parser[Any] = host ^^ (x=> {println("servername: " +x)})
val command: Parser[Any] = """([A-Za-z]+)|([0-9]{3})""".r ^^ (x=> {println("command: " +x)})
val params: Parser[Any] = rep(param)~opt(":"~tail) ^^ (x=> {println("params: " +x)})
val param: Parser[Any] = """[^:][\S]*""".r
val tail: Parser[Any] = """.*$""".r ^^ (x=> {println("tail: " +x)})
val letter: Parser[Any] = """[A-Za-z]""".r ^^ (x=> {println("letter: " +x)})
}
Я не совсем уверен, что может быть причинойэтот.Надеюсь, я просто слеп к чему-то маленькому.