I am building an application that will send messages using STOMP over websockets. I want to send messages without a request being made by the client. According to the documentation, I can do this by using convertAndSend.
However when I try and do this, I get a null pointer exception. Please see code below:
public class ParseJSON {
#Autowired
private SimpMessagingTemplate template;
public void getDetails(String json) {
try {
Tweet status = sendDetails(TwitterObjectFactory.createStatus(json));
sentToWebApp(status);
} catch (TwitterException e) {
e.printStackTrace();
}
}
#Scheduled(fixedDelay = 50)
private void sentToWebApp(Tweet status) {
System.out.println(status);
this.template.convertAndSend("/tweet/update", status);
}
}
Stack Trace:
java.lang.NullPointerException: null
at org.myproject.worker.ParseJSON.sentToWebApp(ParseJSON.java:62)
at org.myproject.worker.ParseJSON.getDetails(ParseJSON.java:51)
at org.myproject.worker.TwitterClient.run(TwitterClient.java:50)
at org.myproject.Controllers.TweetController.greeting(TweetController.java:37)
Can anybody pour any light onto my situation so I'm able to send a message via websocket without encountering an exception.
Thanks in advance.
Your template variable is not properly autowired thats why its giving nullpointerException .
you can check spring configuration to autowire correctly
Related
I have a quarkus project connecting to monogdb using reactive panache.
I would like my method to be wrapped in a transaction and my current code looks roughly as follows:
#Traced
#ApplicationScoped
#Startup
public class MyReceiver implements com.google.cloud.pubsub.v1.MessageRecevier {
#Override
#ActivateRequestContext
public void receiveMessage(PubsubMessage pubsubMessage, AckReplyConsumer ackReplyConsumer) {
try {
final String messageStr = pubsubMessage.getData().toStringUtf8();
final MyMessage messageContent = objectMapper.readValue(messageStr, getTypeReference());
handleMessage(messageContent).await().indefinitely();
ackReplyConsumer.ack();
} catch (Throwable ex) {
log.warn("{} Message ID: [{}] on [{}] ", ex.getMessage(), pubsubMessage.getMessageId(), subscriptionName);
ackReplyConsumer.nack();
}
}
public TypeReference<MyMessage> getTypeReference() {
return new TypeReference<>(){};
}
#ReactiveTransactional
public Uni<Void> handleMessage(MyMessage message) {
// code here is never reached
}
}
When i try to test my code however and get a message,
I am getting this error: java.lang.NullPointerException: Cannot invoke "org.hibernate.reactive.mutiny.Mutiny$Session.withTransaction(java.util.function.Function)" because "session" is null
And it happens when the code tries to go into handleMessage, so when the aspect for #ReactiveTransactional is being triggered
What can I look out for that is causing this cause I can't find anything that can be the source of the issue.
It seems at the moment, panache does not support transactions in mongodb which was the source of this issue.
I use an external rest api in my spring application, I can send json post requests to create objects but when a field is incorrect or if there is a duplicate it returns a 400 bad request error, and a body saying what the problem is.
I use Spring 5 with #PostExchange in the following code:
This is used to point spring into the right direction of the external api
public interface HardwareClient {
#PostExchange("/assetmgmt/assets/templateId/C04DBCC3-5FD3-45A2-BD34-8A84CE2EAC20")
String addMonitor(#RequestBody Monitor monitor);
}
This is the helper that is autowired into the class where I have the data that needs to be sent.
#Component
public class HardwareHelper {
private Logger logger = Logger.getLogger(getClass().getName());
#Autowired
HardwareClient hardwareClient;
#Async
public Future<String> addMonitor(MonitorForm monitorForm){
try {
Monitor monitor = new Monitor(monitorForm.objectID(), monitorForm.model(), monitorForm.make(),monitorForm.serialNumber(), monitorForm.orderNumber(),monitorForm.budgetholder(),monitorForm.ownership());
hardwareClient.addMonitor(monitor);
return new AsyncResult<String>("Success");
} catch (Exception e){
logger.info("HardwareHelper.addMonitor error: " + e.getMessage());
//todo error handling
}
return null;
}
}
When an error occurs the logger will print the error but I need to be able to control what happens after based on the response. So I need to see the body of the post request that is returned after. If everything goes well an ID is returned that I can read by printing the results of the addMonitor() method, but this is obviously not possible when it throws an exception as it skips to the catch part. How do I scan the request body when an error is thrown and handle this appropriately
how can I handle exceptions coming from the gateway implementation when we are building software using the Onion Architecture?
To clarify, I've created an example using Java and SpringBoot:
#Component
#AllArgsConstructor
public class SaveAddressUseCase{
private final GetCustomerGateway getCustomerGateway;
public void execute(AddressDomain address, Long customerId){
try{
//validates the customerId supplied and returns the customer from an external service.
CustomerDomain customer = getCustomerGateway.execute(customerId);
address.setCustomer(customer);
//saves the address
}catch(CustomerNotFoundException ex) {
AddressErrorDomain addressErrorDomain = new AddressErrorDomain();
//saves the address in a error table with httpStatus 404
} catch (InternalErrorException ex) {
AddressErrorDomain addressErrorDomain = new AddressErrorDomain();
//save the address in a error table with httpStatus 500
}
}
}
This is a simple useCase that will save an address but first, it needs to get the customer of this address from an external service. If the customer is not found, I need to save the address in an error table to processes it later. The same goes if this external service is down, but it's important to differentiate between these two errors and I can handle this problem using the HttpStatus returned from my API call.
public interface GetCustomerGateway {
CustomerDomain execute(Long customerId);
}
#Component
#AllArgsConstructor
public class GetCustomerGatewayImpl implements GetCustomerGateway {
private final CustomerApi customerApi; //Feign interface to call an external service
public CustomerDomain execute(Long customerId){
try{
return customerApi.getCustomerById(customerId);
}catch(FeignException ex){
if (ex.status() == HttpStatus.NOT_FOUND.value()) {
throw new CustomerNotFoundException();
} else {
throw new InternalErrorException();
}
}
}
}
Lastly, this is my gateway implementation that just makes a call to this external service using a simple Feign interface and throws two custom exceptions that I extended from RuntimeException.
Question: Catching these two exceptions in the usecase I'm not dealing with details that only the gateway must know? Or even worse, I'm not using exceptions to control the flow of my application? How can I handle the errors coming from the Gateway implementation in a better way than I did in my example?
Obs: In this example, it's important to save the address in error table to not ruins the user experience in the client-side, and I also need to differentiate between these errors.
Thanks in advance!
Consider using #ControllerAdvice for this to keep the controller clean and focused
#ControllerAdvice
#Slf4j
public class RestExceptionHandler {
//Magic happens here
}
Inside RestExceptionHandler, you can catch all feign exceptions like this and handle them however you want
#ResponseBody
#ExceptionHandler(Throwable.class)
public final ResponseEntity<?> handleFeignExceptions(Exception ex, WebRequest request) {
if (ex instanceof FeignException) {
return handle((FeignException) ex);// define your custom handle method
}
}
I'm having a problem with Dropwizard where I can't catch the exception thrown by the Hibernate DAO object within my resource.
I have the following DAO object
public class ApplicantDAO extends AbstractDAO<Applicant>
{
public ApplicantDAO(SessionFactory factory)
{
super(factory);
}
public long create(Applicant person)
{
return persist(person).getApplicantId();
}
}
I am calling the create method from inside my Dropwizard resource to which I'm passing on my managed DAO from my Application's run method. The following doesn't work:
try
{
long id = dao.create(applicant);
message += "[Stored: " + id + "] ";
}catch (HibernateException ex)
{
message +="Could't store: " + exptionToString(ex);
}
Instead I get Dropwizard's/Jersey's message:
{"code":500,"message":"There was an error processing your request. It has been logged (ID a785167e05024c69)."}
Is there a way to get around that?
I am not familiar with Drop Wizard.
But my best guest is that it has a JAX-RS ExcepionMapper registered that writes its own error when an exception is thrown
see : javax.ws.rs.ext.ExceptionMapper
I figured it out. The problem was happening because of an exception throw inside of a transaction.
So instead of having #UnitOfWork on my resource method, I added #UnitOfWork(transactional = false)
Then I was able to manage my own transactions by passing in the SessionFactory to my resource and that did the trick!
It might be related to the following issue: https://github.com/dropwizard/dropwizard/issues/949
I try to build wsdl client for jre5 with JAX-WS RI 2.1.3 its my first expirience. I genereted classes with wsdl2java tool from cxf and wrote wrapper class around client looks like:
public class RequestHelper {
private DataLoadService service = new DataLoadService();
private DataLoadServiceSoap client;
private static String token;
//....my constructor....
public void sendData(data){
try{
if (tokenIsExpired()){
renewToken();
}
client.sendData(data, this.token);
}catch(SOAPFaultException e){
//...work with e
}
}
}
I can't understand how i can process exception in sendData method. I mean, for example, in HTTP we have status codes, we can read status code and decide which type of error we get from server and how we want process them.
In my case i have problem with token expired time. Sometimes sendData request goes to the server for a long time. And the token is no longer valid when the request is already on the server then i get exception with text message "Token expired". And i want catch this type of exception separately, somthing like this:
public class RequestHelper {
private DataLoadService service = new DataLoadService();
private DataLoadServiceSoap client;
private static String token;
//....my constructor....
public void sendData(data){
try{
if (tokenIsExpired()){
renewToken();
}
client.sendData(data, this.token);
}catch(SOAPFaultException e){
//...work with e
}catch(TokenExpiredException e){
renewToken();
client.sendData(data, this.token);
}
}
}
How i can achieve this with JAX-WS RI 2.1.3 library?
UPD:
} catch (SOAPFaultException e) {
SOAPFault f = e.getFault();
f.getFaultString() //yes here we have error description with "Token"
//but with locals dependency, this is not safe handle exception by this value
f.getFaultCode() //here simply string "soap:Receiver", do not know how i can recognize only "token exceptions"
}
Find out what is been returned as part of the SOAPFaultException from the server. If the Exception contains the error message then we can write something like below. note: Error code will be the best way to handle this.
try{
if (tokenIsExpired()){
renewToken();
}
client.sendData(data, this.token);
}catch(SOAPFaultException e){
if(e.getFault().getFaultString().equalsIgnoreCase("Token expired") ) {
renewToken();
client.sendData(data, this.token);
}
......
}
Another way is to have custom SOAP exception thrown from the sever with error code and error message and handle that in the code