java - 有没有人在使用 Java-Prolog 连接器时得到“java.net.SocketException: Connection reset”
问题描述
我想知道是否有人使用过 Java-Prolog 连接器(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)
解决方案
即使使用最新版本的 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,并且可能由于异常而保留在那里。
推荐阅读
- c# - Parameters.Addwithvalue 带空格
- json - 链接 JSON 时 Discord.py 中的问题
- python - 如何在 Python 中循环该函数,以便我的脚本一直运行?
- linux - ld:致命错误:无法使用--plugin:ld 是在没有插件支持的情况下编译的
- python - 以字典格式打印循环输出
- android - Android Webview:使用adblock plus时隐藏网站的一些元素
- scalability - 访问公共资源的水平扩展应用程序
- excel - vba 小时和日期范围
- python - 您可以从 python GUI 库访问帧缓冲区吗?
- reactjs - 没有随机键,反应复选框不会重置?