JBoss运行期故障
InputStream inputStream = socketWrapper.getInputStream();if(performVersioning){ version = readVersion(inputStream); if(version == -1) throw new EOFException();}这里就是扔出EOFException的元凶,当readVersion(inputStream)?返回-1的时候,就认为运行环境不对了。
private int readVersion(InputStream inputStream) throws IOException{ if(trace) log.trace("blocking to read version from input stream"); int version = inputStream.read(); if(trace) log.trace("read version " + version + " from input stream"); return version;}这里仅仅是一个简单的读操作,也就是从InputStream里面读不到流。而InputStream是从SocketWrapper? 中直接通过SocketWrapper.getInputStream()来获取的。那这SocketWrapper又是如何创建的呢?
socketWrapper = createServerSocketWrapper(socket, timeout, invoker.getLocator().getParameters());ServerThread.createServerSocketWrapper(Socket socket, int timeout, Map metadata)代码段:
if(serverSocketClass == null) serverSocketClass = ClassLoaderUtility.loadClass(serverSocketClassName, getClass());try{ serverSocketConstructor = serverSocketClass.getConstructor(new Class[] { java.net.Socket.class, java.util.Map.class, java.lang.Integer.class });}catch(NoSuchMethodException e){ serverSocketConstructor = serverSocketClass.getConstructor(new Class[] { java.net.Socket.class });}ServerSocketWrapper的这两个构造方法都定义在父类ClientSocketWrapper中:
public ClientSocketWrapper(Socket socket) throws IOException{ super(socket); createStreams(socket, null);}public ClientSocketWrapper(Socket socket, Map metadata, Integer timeout) throws Exception{ super(socket, timeout); createStreams(socket, metadata);}这个InputStream就是从createStreams所创建的。
private InputStream in;in = createInputStream(serializationType, socket, unmarshaller);继续往下看ClientSocketWrapper.createInputStream(String serializationType, Socket socket, UnMarshaller unmarshaller):
InputStream is = socket.getInputStream();if(unmarshaller instanceof PreferredStreamUnMarshaller){ PreferredStreamUnMarshaller psum = (PreferredStreamUnMarshaller)unmarshaller; is = psum.getMarshallingStream(is);}return is;到这里大家应该都明白了这InputStream是如何创建的了,那么为啥这InputStream.read()返回-1呢,? 这就? 要 研究这个一直出现在代码中的Socket了,Socket是在ServerThread的构造方法中传递过来的, 实际上这个Socket就是JBoss到tomcat的一个连接。那么既然Socket初始化能成功,说明连接没有问题, 就只能从Socket返回的流上面来查找问题。那是否是Tomcat宕机了,从Socket无法返回流,而Socket连接却是正常的。打开Tomcat的 logs,确实,Tomcat宕机了,再对比Tomcat宕机时间和JBoss出现Exception的时间,前后一致,原来如此。只要Tomcat不宕机,JBoss就不会出这个Exception。