Java 从运行在Tomcat中的webapp写入套接字时出现NullPointerException
我在写套接字时遇到了一个奇怪的问题。该应用程序是一个在Tomcat 5.5下运行的Web应用程序。 所讨论的功能是从servlet接收请求,进行一些处理,然后通过SSLSocket将该请求发送到外部系统 这是我的MessageProcessor类:Java 从运行在Tomcat中的webapp写入套接字时出现NullPointerException,java,sockets,tomcat,ssl,concurrency,Java,Sockets,Tomcat,Ssl,Concurrency,我在写套接字时遇到了一个奇怪的问题。该应用程序是一个在Tomcat 5.5下运行的Web应用程序。 所讨论的功能是从servlet接收请求,进行一些处理,然后通过SSLSocket将该请求发送到外部系统 这是我的MessageProcessor类: public class MessageProcessor { private final int socketTimeout; private final int threadTimeout; private final
public class MessageProcessor {
private final int socketTimeout;
private final int threadTimeout;
private final ExecutorService executor = Executors.newCachedThreadPool();
private static class Holder {
static MessageProcessor instance = new MessageProcessor();
}
public static MessageProcessor instance() {
return Holder.instance;
}
static {
instance();
}
private MessageProcessor() {
socketTimeout = /*get from property*/
threadTimeout = /*get from property*/
//Setting Java SSL details
System.setProperty("javax.net.ssl.trustStore") /*from property*/;
System.setProperty("javax.net.ssl.trustStorePassword") /*from property*/;
socketFactory = SSLSocketFactory.getDefault();
}
public String submit(String msg) {
Worker worker = new Worker(msg);
try {
return executor.submit(worker).get(threadTimeout,
TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrade();
}
return "";
}
public String submitDirect(String msg) throws Exception {
Worker worker = new Worker(msg);
return worker.call();
}
class Worker implements Callable<String> {
private String message;
public Worker(String requestMsg) {
this.message = requestMsg;
}
public String call() throws Exception {
socket = socketFactory.createSocket();
StringBuilder responseSb = new StringBuilder();
StringBuilder frameMarkerSb = new StringBuilder();
BufferedWriter socketWriter = null;
BufferedReader socketReader = null;
try {
socketWriter =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
socketWriter.write(message);
socketWriter.flush();
socketReader =
new BufferedReader(new InputStreamReader(socket.getInputStream(),
"UTF-8"));
/* do something else */
/* receive response */
} catch (InterruptedIOException e) {
//Error handling
} catch (Exception e) {
//Error handling
} finally {
socketWriter.close();
socketReader.close();
socket.close();
}
return response;
}
}
}
问题在于submit()。在submit()中,任务被提交到缓存的线程池,并引发此异常。在socketWriter.flush()上引发异常 如果我使用submitDirect(),则直接调用call()方法,而不提交到线程池,并且工作正常 在JUnit中测试该类时没有问题。这只发生在Tomcat中 如果有人能解释一下,我将非常感激。对不起,如果我在这里放了很多代码。这让我发疯了
public String submitDirect(String pdcRequestStr) throws Exception {
Worker worker = new Worker(msg);
return worker.call();
}
将new Worker(msg)更改为new Worker(pdc requeststr)我想我已经找到了问题的原因,该问题看起来来自这一行:
socketFactory = SSLSocketFactory.getDefault();
将SocketFactory放入线程局部变量后,它可以正常工作
socketFactory = new ThreadLocal<SocketFactory>(){;
protected SocketFactory initialValue() {
return SSLSocketFactory.getDefault();
}
};
socketFactory=newthreadlocal(){;
受保护的SocketFactory初始值(){
返回SSLSocketFactory.getDefault();
}
};
所以我的结论是SSLSocketFactory不是线程安全的。不过,我还没有找到任何官方文档来支持这一点。这是我的错别字。由于业务敏感性,在此处过帐之前已重命名变量。“在socketWriter.flush()处引发异常”。不是根据你发布的堆栈跟踪。还有更多吗?发布了完整的堆栈跟踪。当我使用调试器逐步检查代码时,它在socketWriter.flush()处失败。但是,堆栈跟踪仅与此类似
socketFactory = SSLSocketFactory.getDefault();
socketFactory = new ThreadLocal<SocketFactory>(){;
protected SocketFactory initialValue() {
return SSLSocketFactory.getDefault();
}
};