Bump Gradle from 6.8.3 to 8.10.2 and increase the minimum required
Java version from 8 to 11 (SMACK-953).
The switch from Java 8 to 11 caused some Bytecode portability issues
regarding NIO Buffers. Java changed with version 9 the return type of
some subclasses of Buffer to return the specific Buffer type instead
of the Buffer superclass [JDK-4774077]. For example, ByteBuffer.filp()
previously returned Buffer, while it does return ByteBuffer now.
This sensible change was not reflected by the Android API [1], which
means that AnimalSniffer rightfully started to complain that there is
no method "ByteBuffer ByteBuffer.flip()" in Android, there is only
"Buffer ByteBuffer.flip()", and those are incompatible methods on
Java's Bytecode layer.
As workaround, this changes
return charBuffer.flip().toString();
to
((java.nio.Buffer) charBuffer).flip();
return charBuffer.toString();
to restore the Bytecode portability between Android and Java.
Errorprone also got new checks, of which JavaUtilDate and JdkObsolete
are wroth mentioning.
JavaUtilData basically strongly recommends to use Java's newer time
API over java.util.Date. But since Smack was Java 8 until now,
j.u.Date is widely used.
Similar JdkObsolete mentions obsolete JDK APIs, like data structures
like Vector and Stack. But mostly LinkedList, which should usually be
replaced by ArrayList. And this is what this commit largely does.
JDK-4774077: https://bugs.openjdk.org/browse/JDK-4774077
1: https://issuetracker.google.com/issues/369219141
While markdown is easier to write, Smack's markdown documentation was
never tightly coupled with the source. For example, the markdown
documentation never provided links to the actual Java classes and
methods. This poses the risk that the documentation and the code
diverge over time. Furthermore, javadoc is constantly improving (for
example @snippet annotations) and I expect that one will be able to
write javadoc in markdown.
Fixes SMACK-928.
Refactored using
find . -type f -name "*.java" |\
xargs sed -i -E |\
's/\.createStanzaCollectorAndSend\((\w+)\)\.nextResultOrThrow\(\);/.sendIqRequestAndWaitForResponse(\1);/'
and some manual refactoring.
This also resulted in a refactoring of the Providers and parsing
Exceptions. NumberFormatException and ParseException can now be thrown
directly, the wrapping in a SmackParsingException is down at a higher
layer, i.e. in AbstractProvider.
- Reduce the amount of types that are subtypes of NamedElement. See
javadoc of NamedElement for rationale.
- Work more with XmlEnvironment in XmlStringBuilder.
- Some minor changes to XmlStringBuilder API.
Introducing Smack's own XmlPullParser interface which tries to stay as
compatible as possible to XPP3. The interface is used to either wrap
StAX's XMLStreamReader if Smack is used on Java SE, and XPP3's
XmlPullParser if Smack is used on on Android.
Fixes SMACK-591.
Also introduce JUnit 5 and non-strict javadoc projects.
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.
and deprecate createEntry().
createEntry() would also send a subscription request which may is
suprising given that you can also create an roster item without having
to send a subscription request out.
This also fixes a bug in
LowLevelRosterIntegrationTest.testPresenceEventListenersOffline()
where createEntry() was used, which would also trigger a presence
subscription request which in turn made the test fail if the
SubscribeListener of ensureSubscribedTo() was not yet set
up. So the test would fail depending on the timing.
Fix for SMACK-841
Since Smack 4.2.4, the getPresencesInternal method in the Roster class
can return a LruCache object, which is a LinkedHashMap with access
order. This means that any access using get or getOrDefault will be a
modification of the Map. If you loop over the keySet of the Map and
there are more than one, the second call to get will throw a
ConcurrentModificationException!
Since the keys are only used here to obtain the corresponding
values, the simplest solution is to just loop over the values instead.