First, thanks to Jive for such a nice, free library. I got a lot out of Instant Messaging in Java and Smack seems like a great way to extend the ideas there.
Speaking of extending… The PacketExtensionProvider interface requires a “public, no-argument constructor.” Does this ever get called, though? I seem to be able to use a PacketExtensionProvider object created with arguments when registering through ProviderManager.addExtensionProvider(), and I have not yet seen the no-arg version called by anything behind the scenes.
You can add new PacketExtensionProviders in two ways.
Option 1:
Register in the file “smack.providers” the new PacketExtensionProvider so that when Smack starts up the providers defined in the mentioned file are automatically available. This option requires that the registered provider defines a public, no-argument constructor.
Option 2:
Use the ProviderManager.addExtensionProvider message. Until you register the new provider through this message any packet that Smack receives will be treated as a default packet extension.
I recommend to use the first option if you know beforehand the providers to register.
Thank you for distinguishing the two options for me. I had somehow decided that I needed to do both, which is very clearly not right.
Option 2 (ProviderManager.addExtensionProvider) works great; whenever I specify my custom PacketExtensionProviders in this way it all works as expected, regardless of the presence or absence of the smack.providers file.
Unfortunately, I am now having a bit of trouble trying only the smack.providers file. PacketFilters and PacketListeners are invoked correctly. However, the Extension in the Packet coming into the processPacket callback is of class DefaultPacketExtension rather than my FooExtension class (as returned by my FooExtensionProvider). Trying to cast it as a FooExtension causes cast exceptions.
Am I still erring somewhere on the Smack side? Am I just exhibiting stupid-Java-newbie syndrome?
trying only the smack.providers file. PacketFilters
and PacketListeners are invoked correctly. However,
the Extension in the Packet coming into the
processPacket callback is of class
DefaultPacketExtension rather than my FooExtension
class (as returned by my FooExtensionProvider).
Trying to cast it as a FooExtension causes cast
t exceptions.
The reason why you are getting a DefaultPacketExtension and not a FooExtension is that your FooExtensionProvider is not being used when parsing the received packet extension.
Smack decides the PacketExtensionProvider to use according the elementName and namespace of the packet extension. When no PacketExtensionProvider is found for the elementName and namespace of the packet extension then a DefaultPacketExtension is created.
If you paste in an example of the received packet and your smack.providers file we can help you find where the problem is.
For what it’'s worth I will probably end up using the ProviderManager.addExtensionProvider() approach. I am curious about how I am going wrong here, though.
Incidentally, say the main program lives in ~keith/foo. FooExtensionProvider, FooExtension (the PacketExtension implementation), and the META-INF directory containing smack.providers are all in ~keith/foo/com/cmdc/tfas. Does that seem reasonable?
I moved META-INF to ~keith/foo (which is, as Matt surmised, in my classpath) and had the same result.
My original question has certainly been answered, and I very much appreciate folks clearing up my confusion here, but it’‘s certainly understandable if you’'d all like to move on.
Urg, was hoping the problem would be solved. One thing we’'ll do for an upcoming Smack release is also let smack.providers be loaded from “/” in the classpath instead of just “/META-INF/”. That should make it easier to find the right place to put the file.