Reputation: 21
I'm trying to make a simple message manager for my game. However, I'm getting the following exception:
Exception in thread "main" Exception in thread "Thread-4" java.lang.ClassCastException: MessageManagement.Message cannot be cast to java.lang.Comparable
at java.util.concurrent.PriorityBlockingQueue.siftUpComparable(Unknown Source)
at java.util.concurrent.PriorityBlockingQueue.offer(Unknown Source)
at java.util.concurrent.PriorityBlockingQueue.add(Unknown Source)
at MessageManagement.MessageManager.EnqueueMessage(MessageManager.java:69)
The initialization code is:
MessageManager messageManager = new MessageManager();
messageManager.start();
//send bootstrap message
CJournal.Journal(Main.class, "Testing messanger: ending bootstrapping message to messagemanager");
Message boot_strap_message = new Message();
boot_strap_message.mflag = EEventMachine.EM_BOOTSTRAP;
messageManager.EnqueueMessage(boot_strap_message);
And the actual message manager is:
public class MessageManager extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
while (true)
{
if (!messagesQueue.isEmpty())
{
//pull message from queue
Message message = messagesQueue.remove();
//dispatch messages according to their type
switch(message.mflag)
{
case EM_BOOTSTRAP:
CJournal.Journal(MessageManager.class, "Messaging system working properly.");
default:
CJournal.Journal(MessageManager.class, "Dispatch Message Trashed");
}
}
}
}
public static PriorityBlockingQueue<Message> messagesQueue = new PriorityBlockingQueue<Message>();
public static void EnqueueMessage(Message message)
{
//Error happens here
messagesQueue.add(message);
}
Why am I getting this error and what do I need to do to fix it?
Upvotes: 2
Views: 823
Reputation: 1140
Per PriorityBlockingQueue's javadoc
A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).
Your Message
class needs to implement Comparable
class Message implements Comparable<Message> {
public int compareTo(Message m) {
int comparisonResult = //comparison logic.
return comparisonResult;
}
}
Per Comparable#compareTo's javadoc, compareTo
Set a negative integer, zero, or a positive integer if this message is less than, equal to, or greater than (respectively) the specified object.
Your other option is to supply a Comparator to PriorityBlockingQueue
.
Upvotes: 1
Reputation: 14873
Javadoc is clear:
public class PriorityBlockingQueue extends AbstractQueue implements BlockingQueue, Serializable
An unbounded blocking queue that uses the same ordering rules as class PriorityQueue and supplies blocking retrieval operations. While this queue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryError). This class does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).
You have to implement the Comparable interface.
class Message implements Comparable<Message> {
public int compareTo( Message o ) {
int diff = ...;
return diff;
}
}
or implement the Comparator interface and give it to the constructor of PriorityBlockingQueue.
class MyComp implements Comparator<Message> {
public int compare( Message l, Message r ) {
int diff = ...;
return diff;
}
}
Upvotes: 0