Here is a list of questions people often ask about Muse.
 | Contributing to Muse
Since the API is entirely modular, we are looking for people who can help fix bugs or add enhancements to the project. For the codes you contribute, we will gladly incorporate them into the API so others can use. After all, that's what Open Source is all about. You can send the code straight to us at support@echomine.com, post them on Jira if they are patches, or post them on the [Muse Community Space].
All codes contributed back to Muse will be distributed under the Muse License. |
Jabber FAQ
Occasionally when I send a synchronized message, my entire application hangs. Why?
If you happen to send a synchronized message inside a JabberMessageListener.messageReceived() method, then it will surely hang. This is not a bug (yes, it's a feature.
).
JabberMessageListener.messageReceived() is actually called inside the SAX Incoming Reader Thread. This thread reads incoming data, parses it into message objects, and then dispatches events to the listeners for handling. Now if in response to a incoming message, you decide to send another synchronized message. You're thinking that you can just send it and wait for a reply inside the messageReceived() method. The problem is that when you send a synchronized method, you are essentially waiting for a reply message. But since you're inside the Incoming Reader Thread, the Reader can't read any incoming messages while you're still inside your messageReceived() method. Thus, you have put yourself in a thread deadlock.
Fear not, there is a solution. The JabberConnection offers a sendLater(Runnable) method. You simply wrap your code inside a Runnable class and submit it with the sendLater() method. This way, the Reader thread can continue parsing incoming messages, and your message processing will not get in the way. The solution is similar to the SwingUtility.invokeLater() method for you SwingUI gurus.
I notice Muse is using Reflection to instantiate message objects for handling incoming messages. Isn't that slow?
Jabber now uses reflection to instantiate message objects that parses incoming data. The decision was made to simplify support for working with custom messages. However, I have done some benchmarking – Static message instantiation vs. Dynamic Reflection instantiation. On my machine (1.5 GHz, 1.5 Gigs RAM) running JDK 1.3.1_01 on Windows 2000, I get the following results:
As you can see, Dynamic Instantiation is definitely slower. However, based on the assumption that the Jabber is an IM and will not be receiving so many messages at once, I do not see a big problem with it. Jabber module will most likely be used on the client side, in which case dynamic instantiations should not even be a issue at all. If the Jabber module is used on the server side, unless you're using it on a highly-trafficked site, it should not even reach up to 1 million incoming message at once. And for those that do think it will, the Jabber module's message parsing mechanism is pluggable; you can simply write your own custom message parsing algorithm that uses static instantiation instead.
Sometimes when I set certain data for a message and then retrieve the DOM using getDOM(), I don't get the data that I set inside the DOM. The DOM and the data are not synchronized. Why is that?
Ah, this is actually not a bug but rather an adverse effect of the duality nature of the Message classes. Normally, many classes synchronized the DOM tree and the data correctly by updating the DOM tree when any data is modified. However, some of them do not dynamically update the DOM tree until when parse() or encode() is called. The latter way is actually more efficient in terms of performance. But what actually happens is because of the duality nature of the Message classes. Normally, you would not be modifying any data if the message is an incoming message. Thus, the DOM would contain the same information as the data since it's been parsed and no changes are made.
Now, let's look at the other side. When you create an outgoing message, you normally do not need to touch the DOM. You simply use the provided methods to set the data. When the time comes to send the message, the message will be transformed into a string by calling the encode() method. At this point, the encode() method will transform all the data into DOM, at which point the DOM and the data are synchronized. But before then, both are actually not in sync.
There are a few solutions. (1) Don't use getDOM() if it's an outgoing message (I really don't see a need for you to do so, and if you do, send me comments on why and I can add it into the API so you can don't have to). (2) If it's an incoming message, you can use getDOM() since the data and the DOM are the same (unless you decide to change the data, which is a big nono). (3) Call encode() before you do a getDOM(). This will ensure that the DOM is updated. However, this does come with a performance penalty because the data needs to be updated just for you. (4) Create a subclass that overrides the parse() and encode() so that you can retrieve or set your own data. Then, you simply use your own methods to retrieve the information rather than call getDOM(). But then if you're going this route, you might as well just share with the rest of us and have it integrated into the API. 
I'm trying to use Xerces as my JAXP parser, but it's not working. What's up?
You know you have problems with an XML Parser when you connect successfully to the server, and you submit a login request, but the server simply hangs for a while and gives you back an error that says something like "Timeout during connection". You will notice that you actually received a <stream:stream> tag, but then the server disconnects you even though you sent a login message.
The reason this happens is that most parsers out there currently do not support Streamable XML Parsing. The only ones I know of that currently support such a feature are Crimson and Xerces2 (not Xerces 1.x). For those that want to use Xerces 1.x for parsing, you can try the Jabber Xerces Parser that I have created. It actually doesn't work on my computer, but supposedly it should. If you find out why it doesn't work, please submit back a patch.
Due to this bug, as of Muse 0.7b2, a new pluggable parser implementation is added into the Jabber module. To use your own custom parser, you simply set the system property com.echomine.jabber.SAXParser to the customer parser class. This custom parser class must implement com.echomine.jabber.JabberSAXParser and provide an empty constructor for dynamic instantition purpose.
Currently only a JAXP Parser class and the XPP Pull Parser class is included with the Muse distribution. The default uses the JAXP Parser. In JDK 1.4, the default JAXP parser is Crimson, which is distributed with the JDK itself.
If you have other parsers loaded into your classpath, you may get a problem where JAXP is loading the first parser that it can find (normally the first parser specified in the classpath). To specify JAXP to use a specific parser, you need to set the System Properties javax.xml.parsers.DocumentBuilderFactory and javax.xml.parsers.SAXParserFactory. For instance, if you want to set JAXP to use Crimson as the underlying parser, you would set the DocumentBuilderFactory to org.apache.crimson.jaxp.DocumentBuilderFactoryImpl and SAXParserFactory to org.apache.crimson.jaxp.SAXParserFactoryImpl.
I am using Muse as a module in Netbeans and suddenly my code doesn't work. Why?
This hint is given to me by Vegard Skjefstad (thanks!). When running Muse in NetBeans with internal execution, everything will work fine. However, problems begin to surface when you try to load your code the right module way with a module JAR. Logs will show that Muse was able to send out a stream to the server, but unable to handle the reply correctly. This should indicate that something is wrong with the XML parser. Specifically, you are now encountering the problem as described in the FAQ Question above.
Likely, the problem is that NetBeans is using an XML parser that does not support XML Stream parsing, and you happen not to know about it. Vegard gave the following suggestion for NetBeans users:
- Add the crimson JAR to your module JAR (mount the crimson JAR and add the org package inside the JAR to your module JAR).
- Add the line System.setProperty("com.echomine.jabber.SAXParser", "com.echomine.jabber.parser.JabberJAXPParser"); somewhere in the code before Muse calls any XML-related stuff.
The goal is to force the use of an XML parser that supports stream parsing. This should hopefully allow you to get Muse to work properly within the NetBeans environment.
 |
This tip was given to work with Muse 0.8a5. Muse 0.81 now defaults to using JAXP Parser. Thus, this issue may not exist in 0.81. We have yet to confirm this. If you have any updates, let us know. |
How do I enable logging and tracing to see the incoming and outgoing packets that is being sent or received by Muse?
Many users would like to see raw incoming and outgoing data packets during debugging phase. This is enabled easily in Muse. See 6.1 Debugging and Tracing.
I can connect successfully, but afterwards, Muse simply hangs and disconnects after a timeout period. Login won't work properly.
This problem is likely the symptom described in the other FAQ question regarding XML Parser problems. Look at the solution.
FAQ for older/obsolete modules
Check the Archived FAQ