From 6d7b2b70e8143febbd17a3b174789f436f4e42f1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 21 Sep 2019 22:54:50 +0200 Subject: [PATCH 01/16] Add util.Consumer and use it in StateDescriptorGraph --- .../smack/fsm/StateDescriptorGraph.java | 15 +++++------- .../org/jivesoftware/smack/util/Consumer.java | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/util/Consumer.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java index 661c35426..bc4fa7ca8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java @@ -31,6 +31,7 @@ import java.util.Set; import java.util.logging.Logger; import org.jivesoftware.smack.fsm.AbstractXmppStateMachineConnection.DisconnectedStateDescriptor; +import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.MultiMap; /** @@ -330,7 +331,8 @@ public class StateDescriptorGraph { return res; } - private static void dfsVisit(GraphVertex vertex, DfsFinishedVertex dfsFinishedVertex, DfsEdgeFound dfsEdgeFound) { + private static void dfsVisit(GraphVertex vertex, Consumer> dfsFinishedVertex, + DfsEdgeFound dfsEdgeFound) { vertex.color = GraphVertex.VertexColor.grey; final int totalEdgeCount = vertex.getOutgoingEdges().size(); @@ -349,11 +351,12 @@ public class StateDescriptorGraph { vertex.color = GraphVertex.VertexColor.black; if (dfsFinishedVertex != null) { - dfsFinishedVertex.onVertexFinished(vertex); + dfsFinishedVertex.accept(vertex); } } - private static void dfs(Collection> vertexes, DfsFinishedVertex dfsFinishedVertex, DfsEdgeFound dfsEdgeFound) { + private static void dfs(Collection> vertexes, Consumer> dfsFinishedVertex, + DfsEdgeFound dfsEdgeFound) { for (GraphVertex vertex : vertexes) { if (vertex.color == GraphVertex.VertexColor.white) { dfsVisit(vertex, dfsFinishedVertex, dfsEdgeFound); @@ -407,12 +410,6 @@ public class StateDescriptorGraph { dotOut.append("}\n"); } - // TODO: Replace with java.util.function.Consumer> once Smack's minimum Android SDK level is 24 or higher. - private interface DfsFinishedVertex { - void onVertexFinished(GraphVertex vertex); - } - - // TODO: Replace with java.util.function.Consumer> once Smack's minimum Android SDK level is 24 or higher. private interface DfsEdgeFound { void onEdgeFound(GraphVertex from, GraphVertex to, int edgeId, int totalEdgeCount); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/Consumer.java b/smack-core/src/main/java/org/jivesoftware/smack/util/Consumer.java new file mode 100644 index 000000000..eb1419bf6 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/Consumer.java @@ -0,0 +1,24 @@ +/** + * + * Copyright 2019 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.util; + +// TODO: Replace with java.util.function.Consumer once Smack's minimum Android SDK level is 24 or higher. +public interface Consumer { + + void accept(T t); + +} From 002d060584251b1b014d9a5b05006a0d0bf6b72b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 21 Sep 2019 22:56:20 +0200 Subject: [PATCH 02/16] XmlStringBuilder: Map all XML serialization to appendXmlTo() this is now the single place where serializatin happens. --- .../smack/util/XmlStringBuilder.java | 50 ++++++++++++++----- .../smack/tcp/XmppNioTcpConnection.java | 3 +- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index f8c030501..427fc2f94 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -18,9 +18,10 @@ package org.jivesoftware.smack.util; import java.io.IOException; import java.io.Writer; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.Iterator; +import java.util.List; import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.ExtensionElement; @@ -606,6 +607,17 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { return toString().hashCode(); } + private static final class WrappedIoException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private final IOException wrappedIoException; + + private WrappedIoException(IOException wrappedIoException) { + this.wrappedIoException = wrappedIoException; + } + } + /** * Write the contents of this XmlStringBuilder to a {@link Writer}. This will write * the single parts one-by-one, avoiding allocation of a big continuous memory block holding the @@ -620,10 +632,25 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { .withNamespace(enclosingNamespace) .build(); appendXmlTo(writer, enclosingXmlEnvironment); + try { + appendXmlTo(csq -> { + try { + writer.append(csq); + } catch (IOException e) { + throw new WrappedIoException(e); + } + }, enclosingXmlEnvironment); + } catch (WrappedIoException e) { + throw e.wrappedIoException; + } } - public Iterator getCharSequenceIterator() { - return sb.getAsList().iterator(); + public List toList(XmlEnvironment enclosingXmlEnvironment) { + List res = new ArrayList<>(sb.getAsList().size()); + + appendXmlTo(csq -> res.add(csq), enclosingXmlEnvironment); + + return res; } @Override @@ -631,29 +658,26 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { // This is only the potential length, since the actual length depends on the given XmlEnvironment. int potentialLength = length(); StringBuilder res = new StringBuilder(potentialLength); - try { - appendXmlTo(res, enclosingXmlEnvironment); - } catch (IOException e) { - // Should never happen. - throw new AssertionError(e); - } + + appendXmlTo(csq -> res.append(csq), enclosingXmlEnvironment); + return res; } - private void appendXmlTo(Appendable appendable, XmlEnvironment enclosingXmlEnvironment) throws IOException { + private void appendXmlTo(Consumer charSequenceSink, XmlEnvironment enclosingXmlEnvironment) { for (CharSequence csq : sb.getAsList()) { if (csq instanceof XmlStringBuilder) { - ((XmlStringBuilder) csq).appendXmlTo(appendable, enclosingXmlEnvironment); + ((XmlStringBuilder) csq).appendXmlTo(charSequenceSink, enclosingXmlEnvironment); } else if (csq instanceof XmlNsAttribute) { XmlNsAttribute xmlNsAttribute = (XmlNsAttribute) csq; if (!xmlNsAttribute.value.equals(enclosingXmlEnvironment.getEffectiveNamespace())) { - appendable.append(xmlNsAttribute); + charSequenceSink.accept(xmlNsAttribute); enclosingXmlEnvironment = new XmlEnvironment(xmlNsAttribute.value); } } else { - appendable.append(csq); + charSequenceSink.accept(csq); } } } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java index e9992b367..ef9a64984 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java @@ -82,6 +82,7 @@ import org.jivesoftware.smack.packet.StreamOpen; import org.jivesoftware.smack.packet.TlsFailure; import org.jivesoftware.smack.packet.TlsProceed; import org.jivesoftware.smack.packet.TopLevelStreamElement; +import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.sasl.SASLErrorException; import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown; import org.jivesoftware.smack.util.Async; @@ -509,7 +510,7 @@ public class XmppNioTcpConnection extends AbstractXmppNioConnection { CharSequence nextCharSequence = currentlyOutgonigTopLevelStreamElement.toXML(StreamOpen.CLIENT_NAMESPACE); if (nextCharSequence instanceof XmlStringBuilder) { XmlStringBuilder xmlStringBuilder = (XmlStringBuilder) nextCharSequence; - outgoingCharSequenceIterator = xmlStringBuilder.getCharSequenceIterator(); + outgoingCharSequenceIterator = xmlStringBuilder.toList(XmlEnvironment.EMPTY).iterator(); } else { outgoingCharSequenceIterator = Collections.singletonList(nextCharSequence).iterator(); } From bd4b91fc26ff2007a24a33d514e6226c15016402 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 21 Sep 2019 23:00:17 +0200 Subject: [PATCH 03/16] Introduce AbstractXMPPConnection.outgoingStreamXmlEnvironment --- .../org/jivesoftware/smack/AbstractXMPPConnection.java | 10 +++++++++- .../org/jivesoftware/smack/packet/XmlEnvironment.java | 6 ++++++ .../org/jivesoftware/smack/util/XmlStringBuilder.java | 8 ++------ .../org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 5 ++--- .../jivesoftware/smack/tcp/XmppNioTcpConnection.java | 3 +-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index e22ecb289..225b8d66f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -235,6 +235,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { private XmlEnvironment incomingStreamXmlEnvironment; + protected XmlEnvironment outgoingStreamXmlEnvironment; + final Map nonzaCallbacks = new HashMap<>(); protected final Lock connectionLock = new ReentrantLock(); @@ -2017,7 +2019,13 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { from = XmppStringUtils.completeJidFrom(localpart, to); } String id = getStreamId(); - sendNonza(new StreamOpen(to, from, id, config.getXmlLang(), StreamOpen.StreamContentNamespace.client)); + + StreamOpen streamOpen = new StreamOpen(to, from, id, config.getXmlLang(), StreamOpen.StreamContentNamespace.client); + sendNonza(streamOpen); + + XmlEnvironment.Builder xmlEnvironmentBuilder = XmlEnvironment.builder(); + xmlEnvironmentBuilder.with(streamOpen); + outgoingStreamXmlEnvironment = xmlEnvironmentBuilder.build(); } public static final class SmackTlsContext { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java index 4abc3eb06..810d8f75f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java @@ -163,6 +163,12 @@ public class XmlEnvironment { return this; } + public Builder with(StreamOpen streamOpen) { + withNamespace(streamOpen.getNamespace()); + withLanguage(streamOpen.getLanguage()); + return this; + } + public XmlEnvironment build() { return new XmlEnvironment(this); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 427fc2f94..28890b368 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -624,14 +624,10 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { * XmlStringBuilder contents. * * @param writer TODO javadoc me please - * @param enclosingNamespace the enclosing XML namespace. + * @param enclosingXmlEnvironment the enclosing XML environment. * @throws IOException if an I/O error occured. */ - public void write(Writer writer, String enclosingNamespace) throws IOException { - XmlEnvironment enclosingXmlEnvironment = XmlEnvironment.builder() - .withNamespace(enclosingNamespace) - .build(); - appendXmlTo(writer, enclosingXmlEnvironment); + public void write(Writer writer, XmlEnvironment enclosingXmlEnvironment) throws IOException { try { appendXmlTo(csq -> { try { diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 9eaa606bd..ed250eb65 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -87,7 +87,6 @@ import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StartTls; import org.jivesoftware.smack.packet.StreamError; -import org.jivesoftware.smack.packet.StreamOpen; import org.jivesoftware.smack.proxy.ProxyInfo; import org.jivesoftware.smack.sasl.packet.SaslStreamElements; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Challenge; @@ -1347,9 +1346,9 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } maybeAddToUnacknowledgedStanzas(packet); - CharSequence elementXml = element.toXML(StreamOpen.CLIENT_NAMESPACE); + CharSequence elementXml = element.toXML(outgoingStreamXmlEnvironment); if (elementXml instanceof XmlStringBuilder) { - ((XmlStringBuilder) elementXml).write(writer, StreamOpen.CLIENT_NAMESPACE); + ((XmlStringBuilder) elementXml).write(writer, outgoingStreamXmlEnvironment); } else { writer.write(elementXml.toString()); diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java index ef9a64984..94d4abf49 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java @@ -82,7 +82,6 @@ import org.jivesoftware.smack.packet.StreamOpen; import org.jivesoftware.smack.packet.TlsFailure; import org.jivesoftware.smack.packet.TlsProceed; import org.jivesoftware.smack.packet.TopLevelStreamElement; -import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.sasl.SASLErrorException; import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown; import org.jivesoftware.smack.util.Async; @@ -510,7 +509,7 @@ public class XmppNioTcpConnection extends AbstractXmppNioConnection { CharSequence nextCharSequence = currentlyOutgonigTopLevelStreamElement.toXML(StreamOpen.CLIENT_NAMESPACE); if (nextCharSequence instanceof XmlStringBuilder) { XmlStringBuilder xmlStringBuilder = (XmlStringBuilder) nextCharSequence; - outgoingCharSequenceIterator = xmlStringBuilder.toList(XmlEnvironment.EMPTY).iterator(); + outgoingCharSequenceIterator = xmlStringBuilder.toList(outgoingStreamXmlEnvironment).iterator(); } else { outgoingCharSequenceIterator = Collections.singletonList(nextCharSequence).iterator(); } From b1a5509927fe74d095add35ae014a713a169c49e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 15:02:49 +0200 Subject: [PATCH 04/16] smack-tcp: Split dot to png into two makefile steps Since using a pipe, as we did previously would not error the target if the first command in the pipe fails. It is still far from ideal, since the dot file is also generated if the gradle command fails. At some point, this should probably become part of gradle build step instead of shelling out to a Makefile. --- smack-tcp/Makefile | 19 ++++++++++++++----- .../smack/tcp/doc-files/.gitignore | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/smack-tcp/Makefile b/smack-tcp/Makefile index 00e349208..8decb8444 100644 --- a/smack-tcp/Makefile +++ b/smack-tcp/Makefile @@ -1,12 +1,21 @@ -.PHONY := clean generate +.PHONY := all clean GRADLE_QUITE_ARGS := --quiet --console plain -GENERATED_FILES := src/javadoc/org/jivesoftware/smack/tcp/doc-files/XmppNioTcpConnectionStateGraph.png -generate: $(GENERATED_FILES) +XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_PNG := src/javadoc/org/jivesoftware/smack/tcp/doc-files/XmppNioTcpConnectionStateGraph.png +XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_DOT := $(XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_PNG:.png=.dot) + +GENERATED_FILES := $(XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_PNG) $(XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_DOT) + +all: $(XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_PNG) clean: rm -f $(GENERATED_FILES) -src/javadoc/org/jivesoftware/smack/tcp/doc-files/XmppNioTcpConnectionStateGraph.png: src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java ../smack-core/src/main/java/org/jivesoftware/smack/fsm/AbstractXmppStateMachineConnection.java - gradle $(GRADLE_QUITE_ARGS) :smack-repl:printXmppNioTcpConnectionStateGraph | dot -Tpng -o $@ +%.png: %.dot + dot -Tpng -o $@ $^ + +$(XMPP_NIO_TCP_CONNECTION_STATE_GRAPH_DOT): src/main/java/org/jivesoftware/smack/tcp/XmppNioTcpConnection.java ../smack-core/src/main/java/org/jivesoftware/smack/fsm/AbstractXmppStateMachineConnection.java + # TODO: This also creates the dot file even if the command + # fails. It would be better if this was not the case. + gradle $(GRADLE_QUITE_ARGS) :smack-repl:printXmppNioTcpConnectionStateGraph > $@ diff --git a/smack-tcp/src/javadoc/org/jivesoftware/smack/tcp/doc-files/.gitignore b/smack-tcp/src/javadoc/org/jivesoftware/smack/tcp/doc-files/.gitignore index e68066393..35616fd31 100644 --- a/smack-tcp/src/javadoc/org/jivesoftware/smack/tcp/doc-files/.gitignore +++ b/smack-tcp/src/javadoc/org/jivesoftware/smack/tcp/doc-files/.gitignore @@ -1 +1,2 @@ /XmppNioTcpConnectionStateGraph.png +/XmppNioTcpConnectionStateGraph.dot From 28ef30b4b38c8f8b862df3da66e41ed5122d35d1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 15:11:22 +0200 Subject: [PATCH 05/16] smack-java7: Add missing smack-xmlparser-stax dependency Since 2f667f95a ("gradle: Remove archives configuration") the :smack-repl:printXmppNioTcpConnectionStateGraph JavaExec task failed with > Task :smack-repl:printXmppNioTcpConnectionStateGraph FAILED Exception in thread "main" java.lang.ExceptionInInitializerError at org.jivesoftware.smack.SmackConfiguration.getVersion(SmackConfiguration.java:108) at org.jivesoftware.smack.AbstractXMPPConnection.(AbstractXMPPConnection.java:187) at org.igniterealtime.smack.smackrepl.StateGraph.main(StateGraph.java:37) Caused by: java.lang.IllegalStateException: Could not parse Smack configuration file at org.jivesoftware.smack.SmackInitialization.(SmackInitialization.java:100) ... 3 more Caused by: java.lang.IllegalStateException: Could not load a XmlPullParserFactory via Service Provider Interface (SPI) at org.jivesoftware.smack.xml.SmackXmlParser.getXmlPullParserFactory(SmackXmlParser.java:34) at org.jivesoftware.smack.xml.SmackXmlParser.newXmlParser(SmackXmlParser.java:53) at org.jivesoftware.smack.util.PacketParserUtils.getParserFor(PacketParserUtils.java:76) at org.jivesoftware.smack.SmackInitialization.processConfigFile(SmackInitialization.java:144) at org.jivesoftware.smack.SmackInitialization.processConfigFile(SmackInitialization.java:139) at org.jivesoftware.smack.SmackInitialization.(SmackInitialization.java:97) ... 3 more because no XmlPullParser was registered via SPI. The 'archives' configuration which was removed with 2f667f95a ("gradle: Remove archives configuration"), previously pulled in the parser. Just like smack-android delcares a dependency on smack-xmlparser-xpp3, smack-java7 should declare a dependency on smack-xmlparser-stax. --- smack-java7/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/smack-java7/build.gradle b/smack-java7/build.gradle index 52f0197d7..8546e7dbb 100644 --- a/smack-java7/build.gradle +++ b/smack-java7/build.gradle @@ -8,6 +8,7 @@ dependencies { compile project(":smack-core") compile project(":smack-resolver-javax") compile project(":smack-sasl-javax") + implementation project(":smack-xmlparser-stax") } javadoc { From be0830fc8f22daa4f2a3ffa23af76d5cbf110cb0 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 15:18:06 +0200 Subject: [PATCH 06/16] smack-xmlparser: Improve ISE message --- .../main/java/org/jivesoftware/smack/xml/SmackXmlParser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java index 16f61e732..a8e76c294 100644 --- a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java +++ b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java @@ -31,7 +31,8 @@ public class SmackXmlParser { public static XmlPullParserFactory getXmlPullParserFactory() { Iterator iterator = xmlPullParserFactoryServiceLoader.iterator(); if (!iterator.hasNext()) { - throw new IllegalStateException("Could not load a XmlPullParserFactory via Service Provider Interface (SPI)"); + throw new IllegalStateException( + "No XmlPullParserFactory registered with Service Provider Interface (SPI). Is smack-xmlparser-xpp3 or smack-xmlparser-stax in classpath?"); } return iterator.next(); } From 5b1d2664af583e7c88101a1040e6c8ea3640ed78 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 19:47:37 +0200 Subject: [PATCH 07/16] Clear saslException class field before throwing Thanks to PolFW, who writes: A SASLErrorException is thrown before we have received the "". This is because SASLAuthentication is keeping a reference to a "saslException" so to clear that after a authentication failure we have to invoke again connect on the xmpptcpconnection to initialize again the saslAuthentication. But it doesn't solve the issue because an AlreadyConnectedException is thrown before the initialisation of the "this.saslAuthentication.init();" Note that the user uses one time tokens for authentication. --- .../java/org/jivesoftware/smack/SASLAuthentication.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 15175d2b0..2fe581b17 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -216,6 +216,11 @@ public final class SASLAuthentication { } if (saslException != null) { + Exception saslException = this.saslException; + // Clear the saslException class field, so that this exception is not thrown after a new authenticate() + // invocation (with different credentials). + this.saslException = null; + if (saslException instanceof SmackSaslException) { throw (SmackSaslException) saslException; } else if (saslException instanceof SASLErrorException) { @@ -321,7 +326,6 @@ public final class SASLAuthentication { */ void init() { authenticationSuccessful = false; - saslException = null; } String getNameOfLastUsedSaslMechansism() { From bf538129c29a95ba3bed2c06247ab939bc38a624 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 19:54:47 +0200 Subject: [PATCH 08/16] SASL: Add missing InterruptedException to "else if" cascade --- .../main/java/org/jivesoftware/smack/SASLAuthentication.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 2fe581b17..4bc2ec749 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -160,7 +160,8 @@ public final class SASLAuthentication { private boolean authenticationSuccessful; /** - * Either of type {@link SmackException} or {@link SASLErrorException} + * Either of type {@link SmackSaslException},{@link SASLErrorException}, {@link NotConnectedException} or + * {@link InterruptedException}. */ private Exception saslException; @@ -227,6 +228,8 @@ public final class SASLAuthentication { throw (SASLErrorException) saslException; } else if (saslException instanceof NotConnectedException) { throw (NotConnectedException) saslException; + } else if (saslException instanceof InterruptedException) { + throw (InterruptedException) saslException; } else { throw new IllegalStateException("Unexpected exception type" , saslException); } From 93aaf6d8d7df1071a224ef406738ff322c20724b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Sep 2019 20:00:16 +0200 Subject: [PATCH 09/16] Remove SASLAuthentication.init() --- .../jivesoftware/smack/AbstractXMPPConnection.java | 1 - .../org/jivesoftware/smack/SASLAuthentication.java | 12 ++---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 225b8d66f..8e8725a3a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -500,7 +500,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // Reset the connection state initState(); - saslAuthentication.init(); streamId = null; try { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 4bc2ec749..d014fd53b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -168,7 +168,6 @@ public final class SASLAuthentication { SASLAuthentication(AbstractXMPPConnection connection, ConnectionConfiguration configuration) { this.configuration = configuration; this.connection = connection; - this.init(); } /** @@ -200,6 +199,8 @@ public final class SASLAuthentication { final String host = connection.getHost(); final DomainBareJid xmppServiceDomain = connection.getXMPPServiceDomain(); + authenticationSuccessful = false; + synchronized (this) { if (callbackHandler != null) { currentMechanism.authenticate(host, xmppServiceDomain, callbackHandler, authzid, sslSession); @@ -322,15 +323,6 @@ public final class SASLAuthentication { return authenticationSuccessful; } - /** - * Initializes the internal state in order to be able to be reused. The authentication - * is used by the connection at the first login and then reused after the connection - * is disconnected and then reconnected. - */ - void init() { - authenticationSuccessful = false; - } - String getNameOfLastUsedSaslMechansism() { SASLMechanism lastUsedMech = currentMechanism; if (lastUsedMech == null) { From 1d03cfdc790c627bbed2e79a3266fe8d6d1526b4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 24 Sep 2019 10:12:13 +0200 Subject: [PATCH 10/16] checkstyle: Remove redundant whitespace check The "line contains only whitespace character(s)" check is the same as the trailing whitespace characters check a few lines below. --- config/checkstyle/checkstyle.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index a2eeb7b26..c62f00a71 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -35,10 +35,6 @@ - - - -