I'm using a QueueBrowser to get and then loop through an enumeration of messages on a JMS queue. When I try to cast msgs.nextElement() as a TextMessage, IntelliJ IDEA tells me:
java.lang.ClassCastException: weblogic.jms.common.ObjectMessageImpl cannot be cast to javax.jms.TextMessage
I'm very new to JMS and I'm not quite sure what weblogic.jms.common.ObjectMessageImpl is. Casting msgs.nextElement() to type Message seems to work fine. My code is below.
private void readQueueMessage() throws JMSException {
int counter = 0;
System.out.println("Starting the subscriber");
QueueBrowser queueBrowser = queueSession.createBrowser(queue);
Enumeration msgs = queueBrowser.getEnumeration();
//queueConnection.start();
System.out.println("Queue started");
if ( !msgs.hasMoreElements() ) {
System.out.println("No messages in queue");
} else {
while (msgs.hasMoreElements()) {
System.out.println(">>> message count: " + ++counter);
Message message = (Message)msgs.nextElement();
System.out.println("MessageID: " + message.getJMSMessageID() + "\tPriority: " + message.getJMSPriority() + "\tDeliveryMode: " + message.getJMSDeliveryMode());
System.out.println("Timestamp: " + message.getJMSTimestamp() + "\tJMSDestination: " + message.getJMSDestination() + "\tReplyTo: " + message.getJMSReplyTo());
System.out.println("Data: " + ((TextMessage)message).getText());
if (counter >= 3) break;
}
}
System.out.println("stopping the queue");
queueConnection.stop();
}
There are several different types of messages in JMS. You are trying to read a TextMessage that basically contains a String, but the message you are reading is in fact an ObjectMessage which contains a Java object. You should check if the message is a text message using instanceof TextMessage and either ignore it if it is something else or throw an exception.
The class weblogic.jms.common.ObjectMessageImpl is simply WebLogic's implementation of ObjectMessage.
Related
I Have the following code, i want to provide the "topicName" as paramater or read it dynamically from a property, is the possible
#KafkaListener(offsetReset = OffsetReset.EARLIEST)
public class KafkaConsumer {
private final String topicName;
public KafkaConsumer(String topicName) {
this.topicName = topicName;
}
#Topic("topicName")
public void receive(#KafkaKey String day, String message) {
System.out.println("Got Message for the - " + day + " and Message is " + message);
}
}
You can do:
#Topic("${myTopicFromProperties}")
It's a bit confusing because if the question to be combined with the OP's comment "i need to use a different topic name in every method call, such as getting the topic name from the user and then creating a listener" one might think of the following examples/scenarios based on the official doc:
#Topic({"topic1", "topic2", "topic3}) //multiple topics, see "Specifying Topics" sub-section on the linked page
public void receive(
#KafkaKey String key,
String message,
long offset,
int partition,
String topic, // topic as a parameter
long timestamp
) {
System.out.println("Got message: " + message + " from topic: " + topic);
}
You can also use ConsumerRecord and get all the necessary information from there:
// "Receiving a ConsumerRecord" sub-section on the linked page
#Topic({"topic1", "topic2", "topic3})
public void receive(ConsumerRecord<String, String> record) {
System.out.println("Got message: " + record.value() + " from topic: " + record.topic());
}
You should also be able to specify the topics through the property placeholders as found in another answer like #Topic({"${topic1}", "${topic2}", "${topic3}"}).
P.S. The above examples assume that for each specified topic both the message key and the message body are deserialized to strings.
My problem is, that my code, especially tc.addReactionById(messageID, emote);, dont adds a reaction. The whole code is following!
if(args[0].equalsIgnoreCase(prefix + "system") && args[1].equalsIgnoreCase("radd")){
if(args.length == 6){
Message message = event.getMessage();
List<TextChannel> channels = event.getMessage().getMentionedChannels();
List<Role> roles = message.getMentionedRoles();
if(!channels.isEmpty() && !roles.isEmpty()){
TextChannel tc = event.getMessage().getMentionedChannels().get(0);
Role role = roles.get(0);
String messageIDString = args[2];
try{
long messageID = Long.parseLong(messageIDString);
String emote = args[5];
tc.addReactionById(messageID, emote);
eb.setAuthor("Oni System");
eb.setColor(Color.MAGENTA);
eb.setDescription(emote);
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
LiteSQL.onUpdate("INSERT INTO reactionroles(guildid, channelid, messageid, emoji, roleid) VALUES(" + event.getGuild().getIdLong() + ", " + tc.getIdLong() + ", " + messageID + ", '" + emote +"', " + role.getIdLong() + ")");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
else{
eb.setAuthor("Oni System");
eb.setColor(Color.RED);
eb.setDescription(userMent + " bitte benutze !system radd <messageid> <#role> <channel> <emoji>");
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
}
}
addReactionById is a RestAction in the JDA library, so you will need to queue the operation.
Replace
tc.addReactionById(messageID, emote);
with
tc.addReactionById(messageID, emote).queue();
Assuming the messageID and emote arguments are valid, the call to .queue() should process the reaction. In particular, emote needs to be one of either:
An Emote object created by JDA (usually these are custom server emotes), or
A Unicode string of the emoji you want to add
See the MessageChannel documentation for more info.
So I'm making a kick/ban command for my server and the format is /kick name reason.
I got it all working but the reason can only be 1 word and anything over that excludes it, for example /kick BattleDash hello world would say BattleDash was kicked for hello.
Here's my code:
if (cmd.getName().equalsIgnoreCase("kick") && sender instanceof Player) {
Player player = (Player) sender;
int length = args.length;
if (length >= 2) {
boolean playerFound = false;
for (Player playerToKick : Bukkit.getServer().getOnlinePlayers()) {
if(playerToKick.getName().equalsIgnoreCase(args[0])) {
playerToKick.kickPlayer(ChatColor.RED + "Kicked by Administrator " + player.getName() + "\nReason: " + args[1]);
player.sendMessage(ChatColor.RED + "[BATTLEDASHLOGS]: Kicked player " + playerToKick.getName() + "succesfully!");
break;
}
}
if (playerFound == false) {
player.sendMessage(ChatColor.RED + "[BATTLEDASHLOGS]: " + args[0] + " was not found!");
}
} else player.sendMessage(ChatColor.RED + "[BATTLEDASHLOGS]: Incorrect arguments!" + ChatColor.RED + " /kick <PlayerName> <reason>");
return true;
}
(Also if you don't include a reason it gives internal error in chat and exception occured in console)
Your code is doing that due to the way it was programmed.
If we take a look at line that takes the argument:
playerToKick.kickPlayer(ChatColor.RED + "Kicked by Administrator " + player.getName() + "\nReason: " + args[1]);
We can see that you're only using args[1]. If we see a message as an array, the problem will be clear:
At position 0 (remember arrays start at 0): BattleDash
1: hello
2: world
When you take only args[1] to your message, only hello would be used! What we need to do instead, is use all the arguments. One way to do that is like this:
// First, transform your array into a list, so it's easier to understand
List<String> arguments = new ArrayList<>(args);
String playerName = arguments.get(0); // Get the player name
arguments.remove(0); // Remove the player name from our arguments list, we don't want it in the message
String message = String.join(" ", arguments); // Combine all the other arguments into a message
I'm coding a webservice in Java using aws and in many method i need to have a try catch block that can actually log any errors that can occur in the execution of each exposed methods.
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
#WebMethod(operationName = "addObjectToBucket")
public String addObjectToBucket(String bucketName, String objectName, File file) throws IOException{
if ( file == null ){
file = createSampleFile();
}
String message = "";
try {
message += "Uploading a new object to S3 from a file\n";
s3.putObject(new PutObjectRequest(bucketName, objectName, file));
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
How Can i avoid to repeat this try catch block throw all methods that use this kind of stuff ?
Thanks for your help !
Edit : Actually I modified the code :
private String parseError(AmazonServiceException ase) {
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
private String parseError(AmazonClientException ace) {
String message;
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException exc) {
message += parseError(exc);
} catch (AmazonClientException exc) {
message += parseError(exc);
}
return message;
}
Clearer indeed ! :)
I'll just take a look about the command pattern to see if I can use it for this kind of application.
There are two aspects in here.
One thing is about the code repetition in the catch block; which can be easily turned into something like
public class ExceptionHandler {
public String buildMessageFor(AmazonServiceException ase) {
... }
public String buildMessageFor(AmazonClientException ase) {
... }
...
You can even unit test that thing very easily (where "naming" could be improved; but I guess the example should be good enough to get you going).
That would also make it easier in the future to turn from "pure string" messages into something else. You know, hardcoding user messages in source code is not the smartest thing to do.
The other part, the try/catch itself; somehow depends. You see, the try/catch is an essential part of your operations; so many people would argue that you simply keep that structure in your code. The only alternative would be to define some kind of interface like
public interface RunAmazonOperation {
public void run() throws Amazon...
}
Then you can write down all your operations as little classes implementing that interface; to be called by some framework that does the try/catch for you. If that is worth the price ... depends on your application.
In other words: if you turn to the "command" pattern; you might find it useful to define a variety of "commands"; implementing that interface; thus reducing the number of places with try/catch dramatically.
Just do it with methods. One possibility would look like:
String parseError(AmazonServiceException ase){
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
String parseError(AmazonClientException ace){
String message;
message = "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
Now you can just write:
catch(AmazonServiceException exc){
message=parseError(exc);
}
catch(AmazonClientException exc){
message=parseError(exc);
}
We have a restlet server and client. We need to pass the error status and exception traces back to the client so that the client can take appropriate actions depending on the error status code. I read about StatusService and using response.setStatus() method but I can't get the specific exceptions thrown during server side processing be displayed on client side. The DAO layer from the server throws specific DB related exceptions and status code such as (Unique key violation etc), which the client needs to see and take appropriate actions.
Also, what is the common way of doing this to have centralized error handling / processing on server and client side ? Filters ?
A brief example will really help.
Thanks,
Deep
You can only send HTTP status codes and optionally your own description message. You can also send a representation of the error by overriding the getRepresentation in the StatusService.
#Override
public Status getStatus(Throwable throwable, Resource resource) {
Status ret = null;
Throwable cause = throwable.getCause();
if (cause == null) {
Status status = super.getStatus(throwable, resource);
ret = new Status(status, throwable.getMessage());
log.log(Level.SEVERE, "Unexpected resource exception <" + ret.toString() + "> for throwable of type <" + throwable + "> at resource <" + resource + ">");
} else if (cause instanceof NotFoundException) {
ret = new Status(Status.CLIENT_ERROR_NOT_FOUND, cause, resource.getReference().toString());
log.info("Not found <" + ret.toString() + "> for throwable of type <" + cause + "> at resource <" + resource + ">");
} else if (cause instanceof ConstraintViolationsException) {
ConstraintViolationsException e = (ConstraintViolationsException) cause;
ret = new Status(Status.CLIENT_ERROR_BAD_REQUEST, cause, e.getViolations().iterator().next().getMessage());
log.log(Level.SEVERE, "Constraint violation <" + e.getViolations().iterator().next().getMessage() + "> at resource <" + resource + ">");
} else if (cause instanceof BusinessRuleException) {
ret = new Status(Status.CLIENT_ERROR_BAD_REQUEST, cause, cause.getMessage());
log.log(Level.SEVERE, "Business rule exception: <" + cause.getMessage() + "> at resource <" + resource + ">");
} else {
Status status = super.getStatus(throwable, resource);
ret = new Status(status, throwable.getMessage());
log.log(Level.SEVERE, "Unexpected server exception <" + ret.toString() + "> for throwable of type <" + throwable + "> at resource <" + resource + ">");
}
return ret;
}
#Override
public Representation getRepresentation(Status status, Request request, Response response) {
String ret = "";
if (status.getDescription() != null) {
ret = status.getDescription();
} else {
ret = "unknown error";
}
return new StringRepresentation(ret, MediaType.TEXT_PLAIN);
}
You can return a representation of the error in getRepresentation in whatever format (XML, JSON, HTML) you want.