So I am trying to send a message across the cluster, the message will contain a User object which is a Serializable class.
When I send a String or an int it works perfectly, the message is sent without a problem and all channels on the cluster receive it.
When I try to send my own object User it gives me this exception;
Dec 7, 2013 3:55:19 PM org.jgroups.logging.JDKLogImpl error
SEVERE: JGRP000019: failed passing message to receiver: %s
java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: User
at org.jgroups.Message.getObject(Message.java:378)
at AuctionImpl$ReceiverClass.receive(AuctionImpl.java:151)
at org.jgroups.JChannel.up(JChannel.java:738)
This is my receive code;
public void receive(Message msg) {
User user = (User) msg.getObject();
System.out.println("Username: " + user.getUsername());
}
The odd thing is I can create a new instance of User inside the receive and get no problems. for example;
public void receive(Message msg) {
User user = new User("Test", "Test");
User user = (User) msg.getObject();
System.out.println("Username: " + user.getUsername());
}
Anyone got any ideas?
Take a look at the ClassNotFoundException: your User class is not on the classpath when running your program.
Related
I currently have 4 queues:
test-queue
test-queue-short-term-dead-letter
test-queue-long-term-dead-letter
test-queue-parking-lot
When a message comes into test-queue, I do a check to see if the message is in the correct format. If it isn't I want to send the message directly to the parking lot queue.
I can't use AmqpRejectAndDontRequeue() because it will automatically send the message to the configured DLQ (test-queue-short-term-dead-letter).
Using RabbitTemplate.convertAndSend() with another exception such as BadRequestException doesn't work. The message goes to the parking lot queue as expected, however the same message will stay in the test-queue
Using RabbitTemplate.convertAndSend() on it's own won't work as the program continues execution.
All queues are bound to a single direct exchange, each with unique routing keys. The test-queue is configured with the following arguments:
x-dead-letter-exchange: ""
x-dead-letter-routing-key: <shortTermDeadLetterKey>
Receiver:
#RabbitListener(queues = "test-queue")
public void receiveMessage(byte[] person) {
String personString = new String(person);
if (!personString.matches(desiredRegex)) {
rabbitTemplate.convertAndSend("test-exchange", "test-queue-parking-lot",
"invalid person");
log.info("Invalid person");
}
...some other code which I dont want to run as the message has arrived in the incorrect format
}
The problem was solved by manually acknowledging the message and returning from the method.
#RabbitListener(queues = "test-queue")
public void receiveMessage(byte[] person, Channel channel,
#Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception) {
String personString = new String(person);
if (!personString.matches(desiredRegex)) {
rabbitTemplate.convertAndSend("test-exchange", "test-queue-parking-lot",
"invalid person");
log.info("Invalid person");
channel.basicAck(tag, false);
return;
}
...some other code which I dont want to run as the message has arrived in the incorrect format
}
I am using gprc bidirectional streaming for chat application in Spring boot and since StreamObserver<T> object is used to send message back from sever to client. So, I want to serialize StreamObserver<T> object and convert it into stream of bytes to store it in redis or some other database. But since, StreamObserver<T> is a interface which doesn't implement or extend serializable. So, I am looking for a solution to how to serialize it since there would be around thousands of user which be using the chat application and storing StreamObserver <T> in some Map<String, StreamObserver<T>> won't be good idea.
Currently, I am storing StreamObserver<T> objects in map.
Map<String, StreamObserver<T>>
Here, key of map is chat application's user's id and value of is StreamObserver object which contains onNext, onError, onCompleted functions to send message from server to client
// Storing StreamObserver object with user Id
public static Map<String, StreamObserver<Chat.ChatMessageFromServer>> observersMap = new HashMap<String, StreamObserver<Chat.ChatMessageFromServer>>();
#Override
public StreamObserver<Chat.ChatMessage> chat(final StreamObserver<Chat.ChatMessageFromServer> responseObserver) {
// responseObserver -> Storing it into a map. So, server could send message back to the client
String user = grpcServerInterceptor.contextKey.get();
System.out.println("");
System.out.println("User : " + user);
if (observersMap.get(user) == null) {
System.out.println("New User : " + user);
System.out.println("Adding User to observers map");
System.out.println("");
observersMap.put(user, responseObserver);
} else {
System.out.println("This User already exists in observersMap : " + user);
System.out.println("By the way, Updating it");
observersMap.put(user, responseObserver);
}
// This function sends message to client from Server
public void sendMessageFromServerToClient(String user, String message) {
// Fetching StreamObserver from observersMap as defined above
observersMap.get(user).onNext(Chat.ChatMessageFromServer.newBuilder().setMessage(Chat.ChatMessage.newBuilder().setTo(user).setFrom("Server").setMessage(message)).build());
System.out.println("Pushed message to user : " + user);
System.out.println("");
}
StreamObserver corresponds to a stream on a real TCP connection. That resource can't be transferred to a DB. There's no way to serialize it to a DB to reduce memory usage.
I have a web app that has registered users and i would like to push messages to users who have unique user ids. To be able to send a message to the clients, i need to know how to pass unique user id in the #sendto annotation
This is the annotation
#SendTo("/topic/uniqueuserid")
public Greeting greeting(HelloMessage message) throws Exception {
int uniqueuserid;
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + message.getName() + uniqueuserid "!");
}
and this the stomp js
stompClient.subscribe('/topic/uniqueuserid', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
How can i pass a unique user id in #SendTo("/topic/uniqueuserid")
You can use #DestinationVariable annotation in a method argument, like that:
#MessageMapping("/mychat/{uniqueUserId}")
#SendTo("/topic/{uniqueUserId}")
public Message message(#DestinationVariable("uniqueUserId") Long uniqueUserId, HelloMessage message) {
logger.info("Unique user id: {}", uniqueUserId);
}
Situation:
Using Spring MVC I prompt a user in my view to enter some information into the form.
I bind that information to a form object (like normal).
I successfully get data back to my controller (confirmed) via log dump.
The Problem:
Now I'm in the controller with all the data the user entered into the form (bound to a form object).
I take that same object with data in it and I try to pass it to my service class method to use the data in a way I need it to.
The problem is that as soon (as soon) as my controller calls the service method it throws an exception. It doesn't even reach a 'log.info' (which is the first line of code in that method).
This should absolutely be working and I'm very taken back as to why it isn't. It seems like a very simple matter. i.e.(get the data back to my controller; use that data in a call to a service method).
CONTROLLER
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerAccount(#ModelAttribute User user, Locale locale,
Model model) {
String theView = "";
try{
logger.info("User submitted Registration Form");
user.setPaidStatus("ACTIVE");
user.setUserRole("SUBSCRIBER");
logger.info(user.toString()); //Proving all the data is available.
userService.createNewUser(user); //This is the call to my service
//method. As soon as it reaches it it exceptions out right away.
//userDao.createNewUser(userDto); //just to see if it does the same
//thing elsewhere - (it does)
model.addAttribute("command", new User());
theView = "login";
} catch(SaveMyFavsException se){
logger.info(se.getCmdCode() + ", Message: " + se.getCmdMsg());
model.addAttribute("command", new User());
model.addAttribute("error", se.getCmdCode() + ", Message: " +
se.getCmdMsg());
return "register";
} catch(Exception e){
logger.info(e.getLocalizedMessage());
model.addAttribute("command", new User());
model.addAttribute("error", e.getLocalizedMessage());
return "register";
}
return theView;
}
SERVICE CLASS (See createNewUser())
#Component
public class UserService implements UserServiceInterface{
#Autowired
UserDaoInterface userDao;
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void createNewUser(User user){
int result = 0;
try{
//FAILS BEFORE MAKING IT HERE (automatically ends up in the second Catch block for Exception with no message)
logger.info("Entered createNewUser() service");
logger.info("User ID: " + user.getUserId());
result = userDao.createNewUser(user);
logger.info("New User DAO Complete - Rows Inserted: " + result);
} catch(SaveMyFavsException se){
throw new SaveMyFavsException(se.getCmdCode(), se.getCmdMsg());
} catch(Exception e){
logger.info("General Exception occurred during service to create new user... Trace: " + e.getLocalizedMessage());
throw new SaveMyFavsException(2000015, "General Exception occurred during service to create new user... Trace: " + e.getLocalizedMessage());
}
}
You're not seeing the full error message because you're eating the full stack trace. Change your logger to:
logger.info("General Exception occurred during service to create new user.", e);
Please share the code which inject the userService to the controller. This seems to be an issue with the bean injection.
I am using "simplewire" library (for Java) which should be able to send SMS from PC to mobile. However, I am seeting the following error:
Message was not sent! Error Code: 420
Error Description: Invalid Subscriber
ID or Subscriber Password.
Here is my code sample
import com.simplewire.sms.*;
public class send_text
{
public static void main(String[] args) throws Exception
{
SMS sms = new SMS();
// Subscriber Settings
sms.setSubscriberID("123-456-789-12345");
sms.setSubscriberPassword("1234");
// Message Settings
sms.setMsgPin("+11005101234");
sms.setMsgFrom("Demo");
sms.setMsgCallback("+11005551212");
sms.setMsgText("Hello World From Simplewire!");
System.out.println("Sending message to Simplewire...");
// Send Message
sms.msgSend();
// Check For Errors
if(sms.isSuccess())
{
System.out.println("Message was sent!");
}
else
{
System.out.println("Message was not sent!");
System.out.println("Error Code: " + sms.getErrorCode());
System.out.println("Error Description: " + sms.getErrorDesc());
System.out.println("Error Resolution: " + sms.getErrorResolution() + "\n");
}
}
}
I want to know how to get Subscriber ID and Subscriber Password? Do I need an account for that?.
From the Simplewire Java SMS SDK Manual
The subscriber ID is an ID number
provided to paid subscribers that
gives access to all of Simplewire’s
resources. The appropriate password
must also be set.
SimpleWire is now OpenMarket
You would need to setup an account with OpenMarket to use their SDK.
They offer two types of accounts:
Demo: which is where you could test your code on a short code that is for testing
Commercial: This is where you would pay for a Short Code and access to their platform/service