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.
XmlPullParser.getName() only returns a result if the current parser
event is START_ELEMENT or END_ELEMENT. If this is not the case, then
the method may throw (if StAX is used).
ExtensionElement is now a marker interface that requires all
implementation non-abstract classes to carry a static final QNAME
field (of type QName). This is verified by a new unit test.
Also FullyQualifiedElement is renamed to simply XmlElement. XmlElement
is used over ExtensionElement when implementing classes do not
statically know the qualified name of the XML elements they
represent. In general, XmlElement should be used sparingly, and every
XML element should be modeled by its own Java class (implementing
ExtensionElement).
OmemoAesCipher is the sole point where OMEMO related AES operations
are performed. This allows OmemoAesCipher to check in a static block
if AES is available. If AES is not available it throws a (hopefully)
helpfull exception message.
Typically AES is not available on Android if no security provider
providing AES, like Bouncy Castle, has been explicitly configured.
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.
CI runs fail using OracleJDK8 with
/home/travis/build/igniterealtime/Smack/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement_VAxolotl.java:30:
warning - Tag @see: missing final '>':
"<ahref="https://xmpp.org/extensions/xep-0384.html#usecases-announcing">XEP-0384:
OMEMO Encryption (Example 3)</a>."
Other JDKs do not report such an error.
Returning a generic would allow for
List<ExtensionElement> list = stanza.getExtension("foo", "bar");
to compile (Note the we are calling getExtension(), not
getExtension*s*()).
Users are encouraged to use the type safe getExtension(Class<? extends
ExtensionElement) variant instead.
Fixes SMACK-825.
By not directly depending on Bouncycastle (BC), we avoid conflicts between
different bouncycastle versions. It is also part of the developers job
to take care that all required security primitives are available. If
they are provide by BC or some other security provider should not be
up to Smack to decide.
We now only add BC as test dependency to satisfy this requirement when
the unit tests are executed.
and FileTestUtil in favor of commons-io. This is required because
Eclipse won't put src/test code into the classpath of src/main
code (even though gradle was configured with an according
dependency).
- 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.
by using PubSubManager.tryToPublishAndPossibleAutoCreate().
This also swaps the parameters of the method.
Thanks to Guus der Kinderen for suggesting this.
Those exception are caused by I/O operations in the OmemoStore, which
is now declaring that it throws those (since it is not uncommon for
I/O operations to cause IOExceptions). After all, this is nicely
demonstrated as this change is caused by switching with this commit to
the Android API 19 compatible methods in FileBasedOmemoStore, which
throw.
The library can not decide what to do in case of those exceptions,
hence it is sensible to expose them to the user.
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.
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)