How to handle com.netflix.client.ClientException in Spring Cloud - spring-boot

I have two services: A and B. B makes a request via feign client when starts.
But when A is unavailable I get com.netflix.client.ClientException
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: A
I'm looking for the best practice for handling such an exception

right now there is no official way to catch FeignClient exception. but you can handle FeignClient exception by catching as a java.lang.Exception and throw your own exception.
for ex:
try{
feignClient.feignMethod();
} catch(Exception ex){
//throw your own exception
throw new CustomFeignException();
}

Related

How do i resolve this : javax.ws.rs.NotFoundException: HTTP 404 Resource_not_found

I was trying to get familier with JAX-RS and here is my code sniplets
WebTarget target; // this object reference was created successfully
public Client[] getClients() {
return target.request().get(Client[].class); // NOTE target is not null
}
This is the exception which is logged
Caused by: javax.ws.rs.NotFoundException: HTTP 404 Resource_not_found
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:945)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:784)
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:91)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:672)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:668)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:397)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:297)
at org.business.bee.client.ClientBean.getClients(ClientBean.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
If an error is thrown in a getter you'll get the _"FATAL: JSF1073: javax.el.ELException caught during processing of RENDER_RESPONSE 6"_ or similar. The underlying (real!) error has nothing to do with jsf, ejb, jstl or facelets. Just make sure the following exception (thrown in your code trying to access a rest service) does not happen:
javax.ws.rs.NotFoundException: HTTP 404 Resource_not_found

MQ JMS reconnect - exception listener

MQ version 7.5.0.4
Is there a way of getting a notification when the connection is lost. What I can se I only get an error when the timeout has been reached. (JMSWMQ1107: A problem with this connection has occurred.)
mqcf.setConnectionNameList(host); // "host1(1414),host2(1414)";
mqcf.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
mqcf.setClientReconnectTimeout(100); // seconds
ExceptionListener exceptionListener = new ExceptionListener(){
#Override
public void onException(JMSException e) {
System.out.println(e.getErrorCode() + " " + e.getMessage());
}
};
// need to reconnect on exception..!
connection.setExceptionListener(exceptionListener);
Using the Exception Listener for events (even reconnection) is outside of the scope of the JMS Specification. The strict definition is that that should be fired only for when a connection is broken - and the correct course of action is to recreate the connection. (note that various vendors MQ included do provide extensions - so it's always worth raising the requirement!)
In the JavaSE environment you have here, it's possible to set the autoreconnect. In managed environments that's not supported so you do actually have to listen for the connection broken and then the applicaiton needs to redrive createConnection(). The connectionNameList is then 'walked' to find a QM that is running.
Use the linked exception to get more details. In my tested I ended the queue manager without the reconnect option, hence the MQRC 2161 reason code.
code:
#Override
public void onException(JMSException e) {
System.out.println(e);//e.getErrorCode() + " " + e.getMessage());
if(e.getLinkedException() != null)
System.out.println(e.getLinkedException());
}
Exception details.
com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ1107: A problem with this connection has occurred.
An error has occurred with the WebSphere MQ JMS connection.
Use the linked exception to determine the cause of this error.
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2161' ('MQRC_Q_MGR_QUIESCING').

Servlet exception deploying maven enterprise project

I get this error when I try to access to the servlet named BookingServlet
Grave: exception caught
javax.naming.NamingException: Lookup failed for 'java:global/it.volaconnoi_VolaConNoi_webapp-ear_ear_1.0-SNAPSHOT/it.volaconnoi_VolaConNoi_webapp-ejb_ejb_1.0-SNAPSHOT/BookingBean!it.volaconnoi.logic.BookingBeanInterface' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: it.volaconnoi_VolaConNoi_webapp-ear_ear_1.0-SNAPSHOT]
and this is the screenshot
The project is deployed correctly but I don't understand why I get this error. Do you any suggest?
As you may see the booking servlet is in its place
EDIT
BookingBeanInterface bookingBean = lookupBookingBeanLocal();
private BookingBeanInterface lookupBookingBeanLocal() {
try {
Context c = new InitialContext();
return (BookingBeanInterface) c.lookup("java:global/it.volaconnoi_volaconnoi-webapp-ear_ear_1.0-SNAPSHOT/it.volaconnoi_volaconnoi-webapp-ejb_ejb_1.0-SNAPSHOT/BookingBean!it.volaconnoi.logic.BookingBeanInterface");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
Really not enough description, you should describe where is your class BookingBean is located, and by what means it registered in JNDI. But if we assume that registration is correct, you could try to lookup it using following string:
c.lookup("java:app/BookingBean/it.volaconnoi.logic.BookingBeanInterface");
See more description here: http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html

AMQAuthenticationException for WSO2 ESB Publisher

I'm trying to integrate WSO2 ESB (4.7.0) with WSO2 Message Broker (2.1.0).
This is my use case:
A generic HTTP Client sends a REST request to a PassThrough Proxy
deployed on WSO2 ESB
The ESB Proxy has an outsequence: forwards the request to the real
REST service, then, in the outsequence, it sends the response to a
mediator class (deployed inside the WSO2 ESB)
The mediator class make some stuff and has this method inside, by
which it can publish an event to a topic on the Message Broker:
Code:
private void publishEvent(){
String topicName = "MyEvent";
Properties properties = new Properties();
TopicConnection topicConnection = null;
properties.put("java.naming.factory.initial", "org.wso2.andes.jndi.PropertiesFileInitialContextFactory");
String connectionString = "amqp://admin:admin#clientID/carbon?brokerlist='tcp://localhost:5673'";
properties.put("connectionfactory.QueueConnectionFactory", connectionString);
try {
InitialContext ctx = new InitialContext(properties);
TopicConnectionFactory tcf = (TopicConnectionFactory) ctx.lookup("QueueConnectionFactory");
TopicConnection connection = tcf.createTopicConnection();
TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topicName);
TopicPublisher publisher= session.createPublisher(topic);
TextMessage textMessage =
session.createTextMessage("<asd>sono il publisher di WSO2 message Broker!</asd>");
publisher.publish(textMessage);
publisher.close();
}catch (Exception e){
e.printStackTrace();
}
}
On the other end there is a subscriber to the "MyEvent" topic which
is already running.
(I took the code both for Publisher and subscriber from this URL: http://wso2.com/library/articles/2011/12/wso2-esb-example-pubsub-soa/)
When the client sends the REST request to the proxy (1), the mediator is invoked correctly but when it tries to execute the PublishEvent method (3), nothing happens and the WSO2 ESB logs this 530 error:
INFO - ConnectionCloseMethodHandler ConnectionClose frame received
[2013-10-17 12:43:47,733] INFO - ConnectionCloseMethodHandler Error :530: not allowed:Thread-33
[2013-10-17 12:43:47,734] ERROR - AMQStateManager No Waiters for error saving as last error:Attempt to redeclare exchange: amq.topic of type topic to null.
[2013-10-17 12:43:47,735] ERROR - AMQConnection Throwable Received but no listener set: org.wso2.andes.client.AMQAuthenticationException: Attempt to redeclare exchange: amq.topic of type topic to null. [error code 530: not allowed]
ERROR - AMQStateManager No Waiters for error saving as last error:Attempt to redeclare exchange: amq.topic of type topic to null.
[2013-10-17 20:53:44,996] ERROR - AMQConnection error:
org.wso2.andes.client.AMQAuthenticationException: Attempt to redeclare exchange: amq.topic of type topic to null. [error code 530: not allowed]
at org.wso2.andes.client.handler.ConnectionCloseMethodHandler.methodReceived(ConnectionCloseMethodHandler.java:79)
at org.wso2.andes.client.handler.ClientMethodDispatcherImpl.dispatchConnectionClose(ClientMethodDispatcherImpl.java:192)
at org.wso2.andes.framing.amqp_0_91.ConnectionCloseBodyImpl.execute(ConnectionCloseBodyImpl.java:140)
at org.wso2.andes.client.state.AMQStateManager.methodReceived(AMQStateManager.java:111)
at org.wso2.andes.client.protocol.AMQProtocolHandler.methodBodyReceived(AMQProtocolHandler.java:515)
at org.wso2.andes.client.protocol.AMQProtocolSession.methodFrameReceived(AMQProtocolSession.java:456)
at org.wso2.andes.framing.AMQMethodBodyImpl.handle(AMQMethodBodyImpl.java:96)
at org.wso2.andes.client.protocol.AMQProtocolHandler$2.run(AMQProtocolHandler.java:466)
at org.wso2.andes.pool.Job.processAll(Job.java:109)
at org.wso2.andes.pool.Job.run(Job.java:157)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
javax.jms.JMSException: Error closing connection: org.wso2.andes.client.AMQAuthenticationException: Attempt to redeclare exchange: amq.topic of type topic to null. [error code 530: not allowed]
at org.wso2.andes.client.AMQConnection.doClose(AMQConnection.java:920)
at org.wso2.andes.client.AMQConnection.close(AMQConnection.java:855)
at org.wso2.andes.client.AMQConnection.close(AMQConnection.java:846)
at org.wso2.andes.client.AMQConnection.close(AMQConnection.java:841)
at innova.esb.mediator.TopicPublisher.publishMessage(TopicPublisher.java:49)
at innova.esb.mediator.MediatorEventPublisher.mediate(MediatorEventPublisher.java:35)
at org.apache.synapse.mediators.ext.ClassMediator.mediate(ClassMediator.java:78)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:71)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:114)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:239)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:443)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:166)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:222)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.wso2.andes.client.AMQAuthenticationException: Attempt to redeclare exchange: amq.topic of type topic to null. [error code 530: not allowed]
at org.wso2.andes.client.handler.ConnectionCloseMethodHandler.methodReceived(ConnectionCloseMethodHandler.java:79)
at org.wso2.andes.client.handler.ClientMethodDispatcherImpl.dispatchConnectionClose(ClientMethodDispatcherImpl.java:192)
at org.wso2.andes.framing.amqp_0_91.ConnectionCloseBodyImpl.execute(ConnectionCloseBodyImpl.java:140)
at org.wso2.andes.client.state.AMQStateManager.methodReceived(AMQStateManager.java:111)
at org.wso2.andes.client.protocol.AMQProtocolHandler.methodBodyReceived(AMQProtocolHandler.java:515)
at org.wso2.andes.client.protocol.AMQProtocolSession.methodFrameReceived(AMQProtocolSession.java:456)
at org.wso2.andes.framing.AMQMethodBodyImpl.handle(AMQMethodBodyImpl.java:96)
at org.wso2.andes.client.protocol.AMQProtocolHandler$2.run(AMQProtocolHandler.java:466)
at org.wso2.andes.pool.Job.processAll(Job.java:109)
at org.wso2.andes.pool.Job.run(Job.java:157)
Obviously the subscriber doesn't catch any event.
What is wrong? Why do I have this Connection Exception?
Thanks a lot.

How to handle Error/Exception on multiple database connections with spring and hibernate?

I am using spring and hibernate to work on multiple database server save,update simultaneously using 2 datasource configuration.
I am using
org.springframework.jdbc.datasource.DriverManagerDataSource
class for creating datasource.
If both the database server up/running then it's work fine.
If I close one of my database server and trying to catch the exception then it's not coming in catch block
and the stack trace error displaying on my web browser.
Stack Trace:
** BEGIN NESTED EXCEPTION **
java.net.ConnectException
MESSAGE: Connection refused: connect
STACKTRACE:
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:525)
at java.net.Socket.connect(Socket.java:475)
at java.net.Socket.(Socket.java:372)
at java.net.Socket.(Socket.java:215)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:256)
at com.mysql.jdbc.MysqlIO.(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
at com.mysql.jdbc.Connection.(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:154)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:149)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:116)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:54)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2186)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2666)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:686)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:683)
at com.service.RegistrationServiceImpl.add(RegistrationServiceImpl.java:56)
at com.controller.RegistrationController.onSubmit(RegistrationController.java:48)
at org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272)
at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:763)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:709)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:536)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:619)
** END NESTED EXCEPTION *
How can I handle this exception.
I want to display in my GUI that one of my db server is down If any of my db server is down.
Please help on this.
I think there are two options:
List item You should catch the exception in your service layer (like for example in RegistrationServiceImpl), but you will have to do this in all your service classes.
Create a Servlet filter that catches this specific exception and redirect the user to a page showing something like "Sorry, the database is down".
There is #ExceptionHandler annotation in spring. You can create a handler method in some common class of yours. Whenever an exception is thrown you can conveniently show the message you want depending on the exception thrown something like this
#Component
public class BaseController {
#ExceptionHandler(Throwable.class)
public ModelAndView handleException(Throwable throwable, HttpServletRequest request){
ModelAndView view = null;
if (throwable instanceof ConnectException){
view = //set message and return view;
}else if (throwable instanceof someOtherException) {
//do something else;
//handle as many exceptions as you want
}else {
//do something by default for other unhandled/generic exceptions
}
return view;
}
}
The documentation explains more on the return types supported.
You can also make the handler to handle only the kind of exception you want, something like this:
#ExceptionHandler(ConnectException.class)
public ModelAndView handleException(ConnectException ex, HttpServletRequest request){
// handle it
}
You can check this example which is on similar lines.
I hope this helps. Cheers :)

Resources