【问题标题】:Has anybody got "java.net.SocketException: Connection reset" when using Java-Prolog Connector有没有人在使用 Java-Prolog 连接器时得到“java.net.SocketException: Connection reset”
【发布时间】:2021-06-20 17:30:00
【问题描述】:

不知道有没有人用过Java-Prolog Connector (https://sewiki.iai.uni-bonn.de/research/pdt/connector/start) 之前遇到过“java.net.SocketException: Connection reset”。

我的代码是这样的

PrologProcess process = Connector.newPrologProcess();
while(condition) {
    process.restart();
    PrologSession session = process.getSession();
    session.queryOnce(assertz(...));
    String query = ...;
    Map<String, Object> query_result = session.queryOnce(query);
    session.dispose();
}

所以我基本上想要做的是迭代地构建会话并在条件成立时获取查询结果。但是,它并不总是有效,并且似乎如果迭代次数过多,我可能会收到“java.net.SocketException:连接重置”并且无法获取会话。有没有人使用相同的工具并遇到相同的问题?谢谢!

下面是详细的异常信息:

org.cs3.prolog.connector.process.PrologProcessException: Failed to obtain session
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess.getSession(AbstractPrologProcess.java:371)
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess.getSession(AbstractPrologProcess.java:346)
    at com.example.demo.Search.is_done(Search.java:5363)
    at com.example.demo.Search.main(Search.java:1156)
Caused by: org.cs3.prolog.connector.process.PrologProcessException: java.io.IOException: EndOfStream read while waiting for OK
    at org.cs3.prolog.connector.internal.lifecycle.AbstractState.error(AbstractState.java:117)
    at org.cs3.prolog.connector.internal.lifecycle.LifeCycle$3.run(LifeCycle.java:226)
    at org.cs3.prolog.connector.internal.lifecycle.LifeCycle$DispatcherThread.run(LifeCycle.java:59)
Caused by: java.io.IOException: EndOfStream read while waiting for OK
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.readUntil(SocketClient.java:185)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.readUntil(SocketClient.java:142)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.reset(SocketClient.java:105)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.<init>(SocketClient.java:60)
    at org.cs3.prolog.connector.internal.process.socket.SocketPrologProcess.getSession_impl(SocketPrologProcess.java:163)
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess.getSession_internal(AbstractPrologProcess.java:379)
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess.getSession(AbstractPrologProcess.java:369)
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess.getSession(AbstractPrologProcess.java:346)
    at com.example.demo.Search.is_done(Search.java:5363)
    at com.example.demo.Search.main(Search.java:1156)

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:209)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at org.cs3.prolog.connector.internal.process.socket.InputStreamProxy.read(InputStreamProxy.java:79)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.readUntil(SocketClient.java:174)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.readUntil(SocketClient.java:142)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.reset(SocketClient.java:105)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.<init>(SocketClient.java:60)
    at org.cs3.prolog.connector.internal.process.socket.SocketClient.<init>(SocketClient.java:53)
    at org.cs3.prolog.connector.internal.process.socket.SocketServerStartAndStopStrategy.getSocketClient(SocketServerStartAndStopStrategy.java:355)
    at org.cs3.prolog.connector.internal.process.socket.SocketServerStartAndStopStrategy.stopSocketServer(SocketServerStartAndStopStrategy.java:335)
    at org.cs3.prolog.connector.internal.process.socket.SocketServerStartAndStopStrategy.stopServer(SocketServerStartAndStopStrategy.java:326)
    at org.cs3.prolog.connector.internal.process.AbstractPrologProcess$MyLifeCycle.stopServer(AbstractPrologProcess.java:234)
    at org.cs3.prolog.connector.internal.lifecycle.ErrorState$1.run(ErrorState.java:48)
    at org.cs3.prolog.connector.internal.lifecycle.LifeCycle$DispatcherThread.run(LifeCycle.java:59)

【问题讨论】:

  • 似乎 Prolog 服务器在发送“OK”之前切断了连接。有没有服务端的日志文件?
  • 您好,感谢您的回答,但抱歉,我是 swipl-win 的新手,您能告诉我在哪里可以找到日志文件吗?
  • 我真的不知道。我注意到您似乎使用的是 2015 年的旧代码,因为您的输出中显示的异常消息在 2015 年 6 月 9 日发生了变化。也许更新到更高版本的 Java 库可能会有所帮助。

标签: java prolog


【解决方案1】:

似乎即使使用最新版本的 Java 库,问题仍然存在。正如@David Tonhofer 建议的那样,这个问题似乎是由于套接字连接出了问题。虽然我仍然找不到完全解决这个问题的方法,但我在这里提出了一个有点幼稚和直接的解决方案,以防有人遇到同样的问题。

下面是示例代码:

{
    ...
    PrologProcess process = Connector.newPrologProcess();
    while(condition) {
        myFunction(process,...);
    }
    Runtime.getRuntime().exec("taskkill /IM swipl-win.exe /F");
    ...
}

private static int myFunction(PrologProcess process) {    
    try {
        process.restart();
        PrologSession session = process.getSession();
        try {
            session.queryOnce(assertz(...));
            String query = ...;
            Map<String, Object> query_result = session.queryOnce(query);
            session.dispose();
            ...
        }
        catch(Exception) {
            ...
        }
    }
    try {
        process = Connector.newPrologProcess();
        return myFunction(process);
    }
}

所以这个想法是每当“获取会话失败”异常发生时使用递归创建一个新的Prolog进程,并在程序结束时使用“Runtime.getRuntime().exec(”taskkill /IM swipl- win.exe /F");"杀死在此过程中创建的所有 swipl-win.exe,并可能因异常而保留在那里。

【讨论】:

    猜你喜欢
    • 2011-06-06
    • 2015-06-29
    • 2014-05-12
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多