From 5bf0fd64ac8d692c983a846e42343844bd285866 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 2 Aug 2018 09:37:26 +0200 Subject: [PATCH] Add ExceptionThrowingCallbackWithHint and javadoc about parsing exceptions also providing rationale. --- .../smack/AbstractXMPPConnection.java | 32 ++++++++++++++ .../smack/SmackConfiguration.java | 4 +- .../ExceptionThrowingCallbackWithHint.java | 43 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/parsing/ExceptionThrowingCallbackWithHint.java 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 ad576d00b..6ab848c50 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -97,6 +97,38 @@ import org.minidns.dnsname.DnsName; import org.xmlpull.v1.XmlPullParser; +/** + * This abstract class is commonly used as super class for XMPP connection mechanisms like TCP and BOSH. Hence it + * provides the methods for connection state management, like {@link #connect()}, {@link #login()} and + * {@link #disconnect()} (which are deliberately not provided by the {@link XMPPConnection} interface). + *

+ * Note: The default entry point to Smack's documentation is {@link XMPPConnection}. If you are getting started + * with Smack, then head over to {@link XMPPConnection} and the come back here. + *

+ *

Parsing Exceptions

+ *

+ * In case a Smack parser (Provider) throws those exceptions are handled over to the {@link ParsingExceptionCallback}. A + * common cause for a provider throwing is illegal input, for example a non-numeric String where only Integers are + * allowed. Smack's default behavior follows the "fail-hard per default" principle leading to a + * termination of the connection on parsing exceptions. This default was chosen to make users eventually aware that they + * should configure their own callback and handle those exceptions to prevent the disconnect. Handle a parsing exception + * could be as simple as using a non-throwing no-op callback, which would cause the faulty stream element to be taken + * out of the stream, i.e., Smack behaves like that element was never received. + *

+ *

+ * If the parsing exception is because Smack received illegal input, then please consider informing the authors of the + * originating entity about that. If it was thrown because of an bug in a Smack parser, then please consider filling a + * bug with Smack. + *

+ *

Managing the parsing exception callback

+ *

+ * The "fail-hard per default" behavior is achieved by using the + * {@link org.jivesoftware.smack.parsing.ExceptionThrowingCallbackWithHint} as default parsing exception callback. You + * can change the behavior using {@link #setParsingExceptionCallback(ParsingExceptionCallback)} to set a new callback. + * Use {@link org.jivesoftware.smack.SmackConfiguration#setDefaultParsingExceptionCallback(ParsingExceptionCallback)} to + * set the default callback. + *

+ */ public abstract class AbstractXMPPConnection implements XMPPConnection { private static final Logger LOGGER = Logger.getLogger(AbstractXMPPConnection.class.getName()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index 4b99bc20f..01f2995a4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -29,7 +29,7 @@ import javax.net.ssl.HostnameVerifier; import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory; import org.jivesoftware.smack.debugger.SmackDebuggerFactory; -import org.jivesoftware.smack.parsing.ExceptionThrowingCallback; +import org.jivesoftware.smack.parsing.ExceptionThrowingCallbackWithHint; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; import org.jivesoftware.smack.util.Objects; @@ -80,7 +80,7 @@ public final class SmackConfiguration { * The default parsing exception callback is {@link ExceptionThrowingCallback} which will * throw an exception and therefore disconnect the active connection. */ - private static ParsingExceptionCallback defaultCallback = new ExceptionThrowingCallback(); + private static ParsingExceptionCallback defaultCallback = new ExceptionThrowingCallbackWithHint(); private static HostnameVerifier defaultHostnameVerififer; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/parsing/ExceptionThrowingCallbackWithHint.java b/smack-core/src/main/java/org/jivesoftware/smack/parsing/ExceptionThrowingCallbackWithHint.java new file mode 100644 index 000000000..299b21242 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/parsing/ExceptionThrowingCallbackWithHint.java @@ -0,0 +1,43 @@ +/** + * + * Copyright 2018 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.parsing; + +import java.util.logging.Logger; + +import org.jivesoftware.smack.UnparseableStanza; + +/** + * Like {@link ExceptionThrowingCallback} but additionally logs a warning message. + * + * @author Florian Schmaus + * + */ +public class ExceptionThrowingCallbackWithHint extends ExceptionThrowingCallback { + + private static final Logger LOGGER = Logger.getLogger(ExceptionThrowingCallbackWithHint.class.getName()); + + @Override + public void handleUnparsableStanza(UnparseableStanza packetData) throws Exception { + LOGGER.warning("Parsing exception encountered." + + " This exception will be re-thrown, leading to a disconnect." + + " You can change this behavior by setting a different ParsingExceptionCallback using setParsingExceptionCallback()." + + " More information an be found in AbstractXMPPConnection's javadoc."); + + super.handleUnparsableStanza(packetData); + } +}