When xep 0138 is used, a.k.a., cli/srv compression, the server periodically drops connections. Various folks have mentioned related problems in the support lists. logs/warn.log suggests an ArrayIndexOutOfBoundsException with mina.
org.apache.mina.filter.codec.ProtocolDecoderException: java.lang.ArrayIndexOutOfBoundsException (Hexdump: empty)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecF ilter.java:165)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Ab stractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilt erChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceive d(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.CompressionFilter.messageReceived(CompressionFilter.java :161)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Ab stractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilt erChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceive d(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java :239)
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(Execut orFilter.java:283)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java: 650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:613)
Caused by: java.lang.ArrayIndexOutOfBoundsException
It turns out that the problem has two pieces, one related to mina, and the other to openfire.
In org/jivesoftware/openfire/nio/XMLLightweightParser.java:read, readByte can be 0. In this case, readByte-1 is -1, which leads to an exception.
The mina code in org/apache/mina/filter/codec/CumulativeProtocolDecoder.java:decode leads to this problem. It’s possible that an attempt is made to decode a zero-byte buffer. A conditional check fixes the problem.
Here are the fixes for openfire 3.5.1 and mina 1.1.7. I hope they can be incorporated as soon as possible.
Regards,
Joe
svn:mime-type = application/octet-stream
Index: openfire_src/src/java/org/apache/mina/management/MINAStatCollector.java
===================================================================
--- openfire_src/src/java/org/apache/mina/management/MINAStatCollector.java (revision 1408)
+++ openfire_src/src/java/org/apache/mina/management/MINAStatCollector.java (revision 1412)
@@ -8,6 +8,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.ThreadPoolExecutor; /**
* Collects statistics of an {@link org.apache.mina.common.IoService}. It's polling all the sessions of a given
@@ -306,7 +307,7 @@
ExecutorFilter executorFilter =
(ExecutorFilter) session.getFilterChain().get(ExecutorThreadModel.class.getName());
if (executorFilter != null) {
- tmpQueuevedEvents += executorFilter.getEventQueueSize(session);
+ tmpQueuevedEvents += ((ThreadPoolExecutor) executorFilter.getExecutor()).getQueue().size();
} sessStat.lastByteRead = readBytes; Index: openfire_src/src/java/org/jivesoftware/openfire/nio/XMLLightweightParser.java
===================================================================
--- openfire_src/src/java/org/jivesoftware/openfire/nio/XMLLightweightParser.java (revision 1408)
+++ openfire_src/src/java/org/jivesoftware/openfire/nio/XMLLightweightParser.java (revision 1412)
@@ -154,6 +154,9 @@
CharBuffer charBuffer = encoder.decode(byteBuffer.buf());
char[] buf = charBuffer.array();
int readByte = charBuffer.remaining();
+ if (readByte == 0) {
+ return;
+ } // Verify if the last received byte is an incomplete double byte character
char lastChar = buf[readByte-1]; Index: mina-1.1.7/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java
===================================================================
--- mina-1.1.7/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java (revision 1407)
+++ mina-1.1.7/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java (revision 1412)
@@ -128,20 +128,12 @@
usingSessionBuffer = false;
} - for (;;) {
+ boolean decoded = true;
+ for (;buf.hasRemaining() && decoded;) {
int oldPos = buf.position();
- boolean decoded = doDecode(session, buf, out);
- if (decoded) {
- if (buf.position() == oldPos) {
- throw new IllegalStateException(
- "doDecode() can't return true when buffer is not consumed.");
- }
-
- if (!buf.hasRemaining()) {
- break;
- }
- } else {
- break;
+ decoded = doDecode(session, buf, out);
+ if (decoded && buf.position() == oldPos) {
+ throw new IllegalStateException("doDecode() can't return true when buffer is not consumed.");
}
}