and also call notifyConnectionError() on exception thrown by
openStream().
In hindsight I wonder why openStream() was ever called in the writer
thread, as it only caused unnecessary synchronization overhead, as can
be seen by the initialOpenStreamSend synchronization point.
XEP-0060 prohibits publishing a request that contains an item to a node that
is both 'notification-only' and 'transient' (section 7.1.3.6)
In commit 8ed872ca63 the existing pubsub publication
test was modified (to resolve a different issue) to operate on a node that's both
'notification-only' and 'transient'. This resulted in a test that should return
an error, even though the test implementation didn't expect one.
This commit explicitly verifies that publishing an item to such a node causes
an error to be returned. A new test is added that verifies that publishing an
event notification does succeed.
The Smack Integration tests can use an admin account to provision
accounts that are used by the tests. This admin account uses an XMPP
connection to interact with the server-under-test.
When the tests are over, this account should be disconnected
explicitly, to prevent stream management from keeping it alive longer
than it needs to.
This makes the system select the "best" available provider.
Also the 'BC' provider in newer Android version does not longer
implement certain Ciphers, which causes an NoSuchAlgorithmException if
the Cipher is requested explicitly by the 'BC' provider:
E/XmppService: XmppServiceConnection - Error while sending pending messages
org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException: java.security.NoSuchAlgorithmException: The BC provider no longer provides an implementation for Cipher.AES/GCM/NoPadding. Please see https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html for more details.
at org.jivesoftware.smackx.omemo.OmemoService.encrypt(OmemoService.java:375)
at org.jivesoftware.smackx.omemo.OmemoService.createOmemoMessage(OmemoService.java:537)
at org.jivesoftware.smackx.omemo.OmemoManager.encrypt(OmemoManager.java:341)
at org.jivesoftware.smackx.omemo.OmemoManager.encrypt(OmemoManager.java:314)
at es.iecisa.xmppservice.XmppServiceConnection.lambda$sendMessage$0(XmppServiceConnection.java:516)
at es.iecisa.xmppservice.-$$Lambda$XmppServiceConnection$aBU_80chagvypMTSd-aSm7pRQRY.run(Unknown Source:4)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.security.NoSuchAlgorithmException: The BC provider no longer provides an implementation for Cipher.AES/GCM/NoPadding. Please see https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html for more details.
at sun.security.jca.Providers.checkBouncyCastleDeprecation(Providers.java:563)
at sun.security.jca.Providers.checkBouncyCastleDeprecation(Providers.java:346)
at javax.crypto.Cipher.createCipher(Cipher.java:722)
at javax.crypto.Cipher.getInstance(Cipher.java:717)
at javax.crypto.Cipher.getInstance(Cipher.java:674)
at org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder.setMessage(OmemoMessageBuilder.java:169)
at org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder.<init>(OmemoMessageBuilder.java:116)
at org.jivesoftware.smackx.omemo.OmemoService.encrypt(OmemoService.java:372)
at org.jivesoftware.smackx.omemo.OmemoService.createOmemoMessage(OmemoService.java:537)
at org.jivesoftware.smackx.omemo.OmemoManager.encrypt(OmemoManager.java:341)
at org.jivesoftware.smackx.omemo.OmemoManager.encrypt(OmemoManager.java:314)
at es.iecisa.xmppservice.XmppServiceConnection.lambda$sendMessage$0(XmppServiceConnection.java:516)
at es.iecisa.xmppservice.-$$Lambda$XmppServiceConnection$aBU_80chagvypMTSd-aSm7pRQRY.run(Unknown Source:4)
at java.lang.Thread.run(Thread.java:764)
The NPE is caused by an inbound presence stanza without the 'from'
attribute set. The stacktrace of the NPE is:
FATAL EXCEPTION: Smack Cached Executor
Process: de.fhg.ivi.senetz.mobile.android.mbk.debug, PID: 13365
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:944)
at org.jivesoftware.smack.roster.Roster.getPresencesInternal(Roster.java:374)
at org.jivesoftware.smack.roster.Roster.getOrCreatePresencesInternal(Roster.java:388)
at org.jivesoftware.smack.roster.Roster.access$1100(Roster.java:94)
at org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run(Roster.java:1519)
at org.jivesoftware.smack.AsyncButOrdered$Handler.run(AsyncButOrdered.java:121)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Thanks to Marcel Heckel for reporting this.
Fixes SMACK-861.
In case an exception happens in connect()/login() the
'disconnectedButResumable' boolean may (still) be set. Which causes
only one of the reader and writer threads to exit, typically the
reader thread, because shutdown() will bail out very early. This
leaves a dangling (writer) thread causing memory leaks and deadlocks
on a subsequent connect()/login().
in case length is zero. Also do throw a NegativeArraySizeException if
length is negative instead of returning null.
This fixes the following sporadic test issue:
org.jivesoftware.smackx.ox.PainlessOpenPgpProviderTest > encryptDecryptTest FAILED
java.lang.AssertionError
at org.jivesoftware.smack.util.XmlStringBuilder.escape(XmlStringBuilder.java:425)
at org.jivesoftware.smackx.ox.element.EncryptedOpenPgpContentElement.addCommonXml(EncryptedOpenPgpContentElement.java:65)
at org.jivesoftware.smackx.ox.element.CryptElement.toXML(CryptElement.java:51)
at org.jivesoftware.smackx.ox.element.CryptElement.toXML(CryptElement.java:31)
at org.jivesoftware.smack.packet.Element.toXML(Element.java:41)
at org.jivesoftware.smackx.ox.element.OpenPgpContentElement.toInputStream(OpenPgpContentElement.java:186)
at org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider.encrypt(PainlessOpenPgpProvider.java:136)
at org.jivesoftware.smackx.ox.PainlessOpenPgpProviderTest.encryptDecryptTest(PainlessOpenPgpProviderTest.java:155)
because EncryptedOpenPgpContentElement rpad field was sometimes
'null' in case the random function returned '0' as length.