Smack 4 with Apache Vysper

  • Version: 4.1.9 (4.1.8-4-gaf6e80d 2016-11-19)

I’m attempting to setup Smack that connects to Apache Vysper’s XMPP server. Smack seems to be sending an incorrect XML content? There’s a bit of a boilerplate, so I provided a sample project that reproduces the issue.

Below is the relevant stacktrace:

2018-07-15 00:37:05 INFO  XmppIoHandlerAdapter:110 - new session from /127.0.0.1:64414 has been opened
12:37:05 AM SENT (0): <stream:stream xmlns='jabber:client' to='localhost' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='user1@localhost' xml:lang='en'>
2018-07-15 00:37:05 WARN  XmppIoHandlerAdapter:140 - error caught on transportation layer: {}
org.apache.mina.filter.codec.ProtocolDecoderException: org.xml.sax.SAXException: Input length = 1
java.nio.charset.MalformedInputException: Input length = 1 (Hexdump: 16 03 03 00 C5 01 00 00 C1 03 03 5B 4A 26 B1 4E 11 C2 0C 97 F4 D9 48 A8 E8 00 7E A0 D8 A1 AB 89 88 F3 44 BF 6F 7B 99 F3 22 43 AD 00 00 3A C0 23 C0 27 00 3C C0 25 C0 29 00 67 00 40 C0 09 C0 13 00 2F C0 04 C0 0E 00 33 00 32 C0 2B C0 2F 00 9C C0 2D C0 31 00 9E 00 A2 C0 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 00 FF 01 00 00 5E 00 0A 00 34 00 32 00 17 00 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 0B 00 02 01 00 00 0D 00 1C 00 1A 06 03 06 01 05 03 05 01 04 03 04 01 04 02 03 03 03 01 03 02 02 03 02 01 02 02)
	at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:251)
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:46)
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:796)
	at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:119)
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:426)
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:693)
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:646)
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:635)
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:67)
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1079)
	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.xml.sax.SAXException: Input length = 1
java.nio.charset.MalformedInputException: Input length = 1
	at org.apache.vysper.xml.sax.impl.XMLTokenizer.emit(XMLTokenizer.java:159)
	at org.apache.vysper.xml.sax.impl.XMLTokenizer.parse(XMLTokenizer.java:111)
	at org.apache.vysper.xml.sax.impl.XMLParser.parse(XMLParser.java:121)
	at org.apache.vysper.xml.sax.impl.DefaultNonBlockingXMLReader.parse(DefaultNonBlockingXMLReader.java:185)
	at org.apache.vysper.xml.decoder.XMPPDecoder.doDecode(XMPPDecoder.java:96)
	at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:178)
	at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:241)
	... 15 more
Caused by: java.nio.charset.MalformedInputException: Input length = 1
	at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
	at org.apache.mina.core.buffer.AbstractIoBuffer.getString(AbstractIoBuffer.java:1442)
	at org.apache.vysper.xml.sax.impl.XMLTokenizer.emit(XMLTokenizer.java:156)
	... 21 more
2018-07-15 00:37:05 INFO  MinaBackedSessionContext:110 - session will be closed now

The XMPP Server seems to be expecting an XML payload(?) But Smack is sending a different content. I’m not entirely sure as to whether the fault is in the server setup, or the client one.

Although I don’t like the finger-pointing game, I’d kindly direct you to the Vysper developer community. Also note that the Vysper project seems to be basically dead: The last commit was 7 years ago.

Shucks, you’re right. I tried the same setup with an actual XMPP server, Hipchat, and it works.

Do you have something else to recommend though for setting up tests that Smack can use to communicate?

I’m not entirely sure if I understand what exactly you mean by that. Smack comes with integration tests that you can run against any XMPP server. This could be a ejabberd in a docker or a locally installed prosody.

or openfire!

Right! So the test I was hoping to setup is a single TestNG test class (Java), where an XMPP server is started (would’ve been Vysper, if it worked), where a feature I’m working on (which uses Smack under the covers) is going to communicate with.

Pretty much exactly like the example code I linked in the original post. While Smack works perfectly when used with an actual server, running a full blown one on my use case during a test would be overkill.

Worst case, I’d probably indeed go to the dockerized XMPP server route (possibly via testcontainers.org)

An alternative to vysper (or another way to write the test I described) is a lot better.

Thoughts?

Yep, being able to instantiate a more-or-less full-blown XMPP server directl from Java is how Vysper also gained my attention.

You could look into Tigase.

Hi, I am not sure, if it will work, but you could try Openfire as dependency:

<dependency>
    <groupId>org.igniterealtime.openfire</groupId>
    <artifactId>xmppserver</artifactId>
    <version>4.2.0</version>
</dependency>

Then try to instantiate the class ServerStarter from your test suite.

However, you would need to configure Openfire from your tests as well, e.g. add test users etc.