I have to develop a Spark plugin what uses ad-hoc commands (XEP-50) between two clients for exchange informations. I use the Smack 4.4.6 what included with Spark 3.0.2 When i use a command what has only one stage it works fine. However if i want to send parameters for the execution, i have to use multi stage command. When the second stage execution is invoked, the smack of the receiver side throws and uncaught exception what is thrown in the line of 54 in FillableForm.java. The situation is the following, i send a submit form where i answer for the response form, but in this file there is the following:
if (dataForm.getType() != DataForm.Type.form) {
throw new IllegalArgumentException();
}
so as i send a submit form the exception is thrown. I’ve tested the command from other clients like Pidgin and GajIm as well, with the same problem. My question is why the DataForm must be a form type why cannot be a submit type as well?
Thank you for your answer in advance.
Warm regards
Attila
Stack:
java.lang.IllegalArgumentException
at org.jivesoftware.smackx.xdata.form.FillableForm.<init>(FillableForm.java:54)
at org.jivesoftware.smackx.commands.AdHocCommandManager.processAdHocCommand(AdHocCommandManager.java:467)
at org.jivesoftware.smackx.commands.AdHocCommandManager.access$100(AdHocCommandManager.java:70)
at org.jivesoftware.smackx.commands.AdHocCommandManager$3.handleIQRequest(AdHocCommandManager.java:176)
at org.jivesoftware.smack.AbstractXMPPConnection$3.run(AbstractXMPPConnection.java:1561)
at org.jivesoftware.smack.AbstractXMPPConnection$10.run(AbstractXMPPConnection.java:2146)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
Could you show us also the XMPP trace of the multi-stage ad-hoc command exchange? You can obtain it, for example, by setting SmackConfiguration.DEBUG = true.
I applied your patch, and tested with the same XMPP stanzas. Unfortunately there is an other exception in Form.java in the line of 29:
public Form(DataForm dataForm) {
super(dataForm);
if (dataForm.getType() != Type.form) {
throw new IllegalArgumentException();
}
}
Stack:
java.lang.IllegalArgumentException
at org.jivesoftware.smackx.xdata.form.Form.<init>(Form.java:29)
at org.jivesoftware.smackx.commands.AdHocCommandManager.processAdHocCommand(AdHocCommandManager.java:467)
at org.jivesoftware.smackx.commands.AdHocCommandManager.access$100(AdHocCommandManager.java:70)
at org.jivesoftware.smackx.commands.AdHocCommandManager$3.handleIQRequest(AdHocCommandManager.java:176)
at org.jivesoftware.smack.AbstractXMPPConnection$3.run(AbstractXMPPConnection.java:1561)
at org.jivesoftware.smack.AbstractXMPPConnection$10.run(AbstractXMPPConnection.java:2146)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
What is your opinion, can be the solution if the line of 467 in AdHocCommandManager would be
Form filledForm = new FilledForm(dataForm);
instead of
Form filledForm = new Form(dataForm);
because there the form have to be filled. Thank you for the help.
Ok, I think I have now a better understanding of the situation.
But I have think to about about the potential API design solutions. Right now, the API appears to be simply broken for AdHocManager and LocalCommand. Using FilledSubscribeForm there is not an option, as its PubSub specific and at that place you want to be generic.
I have updated the PR with
but that is really just an experiment, even though, it could get you going. But I am not sure if I like this approach (and if it is correct). This approach also means that you have to subclass FilleForm, but that is always a good idea.
I wonder if the subclasses of AdHocCommand should be more separated…
Meanwhile i noticed that the FilledSubscribeForm is different, so i agree with the generic solution. I tested your patch only a small thing what i modified, i have to put the visibility from private to protected in LocalCommand.java line 171. Thank you for the help, it works fine.
Thanks for the fast feedback. Please note that I can not guarantee that this will be the final solution. The more I think about it, the more I believe that the AdHocCommand API needs a overhaul. I’ll let you know once I have something to share.