ActiveMQ inactive broker - java

The problem is that I have defined some broker uri which could be inactive.
Then createConnection from ActiveMQConnectionFactory doesn't throw any exception. I need to handle such situation and if createConnection doesn't work because of uri won't be available then I should mark my service as unhealthy.
boolean healthy = true;
Connection conn = null;
try {
final ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("failover:(tcp://localhost:8080)?jms.prefetchPolicy.all=0&initialReconnectDelay=1000&maxReconnectDelay=30000&maxReconnectAttempts=20");
conn = factory.createConnection(this.userName, this.password);
} catch (JMSException e) {
healthy = false;
} finally {
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
healthy = false;
}
}
}

So you want create connection to fail with an exception but you are also using the failover transport? Doesn't that seem at odds to you?
The failover transport usage is resulting in the create to succeed because the failover transport is doing exactly what you asked it to do which is to try and establish a connection repeatedly until the configured number of attempts is made. Calling a method like create session will block and eventually throw an error once the failover transport gives up. Alternately you could set an exception listener that will be signalled once the connection is closed because the failover transport runs out of reconnect attempts.

Related

Connection.close() does not closes the connection, it make it sleep forever?

In my web app which I write it with java and it uses tomcat and sql server, I can not close the database connections by typing connection.close(). When I write sp_who to the SSMS I can see that sleeping connections count which is opened by me increases while my app is doing sql stuffs.
An example code is in below:
BaseRepository baseRepository = new BaseRepository();
try{
baseRepository.createStatement();
baseRepository.stmt.executeUpdate("update AutoRunURLs set STATUS = 0");
}catch (SQLException e){
e.printStackTrace();
}finally {
baseRepository.cleanResources();
}
Here is the other functions that I used above:
public void openConnection() {
try {
this.conn = ds.getConnection(); // ds is an instance of javax.sql.DataSource
this.isOpen = true;
} catch (Exception e) {
e.printStackTrace();
}
}
public void createStatement() {
try {
if (!this.isOpen) this.openConnection();
this.stmt = this.conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
if (this.stmt != null) {
stmt.close();
this.stmt = null;
}
if (this.conn != null) {
this.closeConnection();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (this.conn != null) this.closeConnection();
}
}
public void closeConnection() {
try {
if (this.conn != null){
this.conn.close();
}
this.isOpen = false;
} catch (Exception e) {
e.printStackTrace();
}
}
When I run the first part above which starts with BaseRepository baseRepository ... one sleeping connections occurs which I see with typing sp_who and it does not close(I waited about a day). Why is that? How can I prevent from this?
And I got one more situation. In my tomcat configurations I set the "maxIdle" value to 10 but even that sleeping connections increases up to thousands after a week. Why does maxIdle does not effect? Here is how I set it:
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Resource auth="Container" driverClassName="net.sourceforge.jtds.jdbc.Driver" maxTotal="999999" maxIdle="10" "Database info here..." validationQuery="select 1"/>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
How can I solve these? Regards,
Edit: I actually managed it by creating a scheduled task which runs every x minutes and kills sleeping connections that sleeps over y minutes. But this is not the way I want. Any other solution will be great.
You are using a connection pool built into Tomcat. This means that it keeps connections open for reuse. When you close connections in your code, they aren't actually closed, but returned to the pool for re-use by your application. This increases efficiency because opening new connections takes time.
In other words, there is nothing wrong and the connections being kept open is expected behaviour.
You might want to decrease your maxTotal to a more sane value of say 10 - 20 instead of 999999 though.
As an aside, the way you handle connections is a bit odd, and makes it very easy to leak connections. You might just want to obtain a connection from the data source when you really need it, and learn about try-with-resources so you close it as soon as possible.

Java obtain nio SocketChannel connection when the connection is already in use

If another application on the PC is connected to the same remote IP address, a java application will fail to connect properly.
This can also happen when a exits abruptly without closing the socket channel. The connection can be blocked and it is impossible to connect during a subsequent session.
What can I do to ensure that no matter the state of the connection in the underlying OS, my program will connect 100% of the time ?
I am looking for a cross platform solution (Windows & Ubuntu)
public void connect() throws CommunicationIOException {
try {
if (isConnected()) {
return;
}
socket = SocketChannel.open();
socket.socket().connect(new InetSocketAddress(getHostname(), getPort()), getConnectionTimeout());
if (!isConnected()) {
throw new CommunicationIOException("Failed to establish the connection");
}
socket.configureBlocking(false);
} catch (final IOException ex) {
throw new CommunicationIOException(
"An error occurred while connecting to " + getHostname() + " on port " + getPort(), ex);
}
}
.
public boolean isConnected() {
if (socket == null) {
return false;
} else {
return socket.isConnected();
}
}
.
public void close() throws CommunicationIOException {
if (socket != null) {
try {
socket.close();
} catch (final IOException ex) {
throw new CommunicationIOException(
MessageFormat.format(
"An error occurred while attempting to close the connection to {}:{}",
getHostname(), getPort()), ex);
}
}
}
If another application on the PC is connected to the same remote IP address, a java application will fail to connect properly.
No it won't, unless the server is improperly programmed.
This can also happen when a exits abruptly without closing the socket channel.
No it can't, again unless something is improperly programmed.
The connection can be blocked
No it can't.
and it is impossible to connect during a subsequent session.
No it isn't.
What can I do to ensure that no matter the state of the connection in the underlying OS, my program will connect 100% of the time ?
Nothing in this life will give you a 100% guarantee. However your fears as expressed above are baseless.

reconnect after OnWebSocketClose - jetty 9.4

According to this post [When does OnWebSocketClose fire in Jetty 9, OnClose fire for me correctly.
but i can not reconnect, because I have not correct situation. (websocett is closed and I can not send any message)
where and when I can reconnect in websocket problem (close by network problem or timeout or kickout by sever after n seconds without handshaking)
I'm not sure if you have solved this issue but I managed to come up with a solution to reconnect a WebSocket connection.
For my scenario, I would like to reconnect my WebSocket connection if #OnWebSocketError method is triggered. Initially I implemented it like this
Implementation A:
#OnWebSocketError
public void onError(Throwable e) {
someMethodToReconnect();
}
and inside someMethodToReconnect
if (client == null) {
client = new WebSocketClient(sslContextFactory);
client.setMaxIdleTimeout(0);
}
if (socket == null) {
socket = new ReaderSocket(); // ReaderSocket is the name of my #WebSocket class
}
try {
client.start();
client.connect(socket, new URI(socketUrl), request);
} catch (Exception e) {
LOGGER.error("Unable to connect to WebSocket: ", e);
}
However, this led to another issue. There are 2 types of error thrown back to me if the server is not up. The exceptions are java.net.ConnectException and org.eclipse.jetty.websocket.api.UpgradeException.
The flow would be:
Initial request to WebSocket server (server is not up)
java.net.ConnectException thrown
org.eclipse.jetty.websocket.api.UpgradeException thrown
And in Implementation A, someMethodToReconnect would be called twice.
This led to Implementation B
#OnWebSocketError
public void onError(Throwable e) {
if (e instanceof ConnectException) {
// Attempt to reconnect
someMethodToReconnect();
} else {
// Ignore upgrade exception
}
}
So far Implementation B works fine, however I'm trying to find out if there's any other exceptions that would be thrown.

javax.jms.ExceptionListener vs try {} catch (JMSException) {}

I'll try to be as detailed as possible. That said, this is my first post so please feel free to be critical of the form/structure/whatever, thanks!
I'm implementing a MessageListener (javax.jms.MessageListener) and when I began, my IDE (Netbeans) requested I set an ExceptionListener. Code something like:
public class MessageQueueListener implements MessageListener
{
public void run()
{
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(<ActiveMQ-address>);
Connection connection = connectionFactory.createConnection();
connection.setExceptionListener(new ExceptionListener()
{
#Override
public void onException(JMSException jmse)
{
//Handle Exception
}
});
Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("NotificationMessageQueue");
Consumer consumer = _session.createConsumer(destination);
consumer.setMessageListener(this);
connection.start();
}
}
I didn't think much of it at the time, as it makes sense to set a listener for potential connection issues. However as I continued with my implementation, I added try/catch statements on secondary methods that are more specific to my use case.
For example:
public boolean postNotification(Message message)
{
String urlParameters = "dummy=dummy";
try
{
postRequest(urlParams); //Below
}
catch (MalformedURLException mfe)
{
//Handle Exception
}
catch (IOException ioe)
{
String eMessage = ioe.getMessage();
if(eMessage.contains("401"))
{
//Handle Exception
}
return false;
}
return true;
}
public void postRequest(String urlParams) throws MalformedURLException, IOException
{
URL url = new URL(<url-to-post-to>);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.addRequestProperty("Authorization", "Basic " + encodedLogin);
con.setRequestMethod("POST");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParams);
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine);
}
in.close();
con.disconnect();
}
Anyways, now my run() method is requesting a try/catch and the ExceptionListener at the beginning of the project is no longer useful. Using try/catches everything seems to work well, so I'm curious as to what changed. I've tried to discover the reason on my own, but have no luck.
So all of this is context to ask: What is the difference between using an ExceptionListener vs try/catches? And is there an advantage to using one or the other, at least with regard to an implementation like mine?
They aren't alternatives. A consumer needs an ExceptionListener because it is a MessageListener, and doesn't call any methods on the connection, and therefore has no other way of knowing that a connection has failed. However when you call a method that throws a checked exception, you have to catch it. The compiler makes you.
try/catch is one of the fundamental Java constructs. It is used for handling unexpected errors. So, you'll gonna use try/catch a lot:
You associate exception handlers with a try block by providing one or
more catch blocks directly after the try block. No code can be between
the end of the try block and the beginning of the first catch block.
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
Each catch block is an exception handler and handles the type of
exception indicated by its argument. The argument type, ExceptionType,
declares the type of exception that the handler can handle and must be
the name of a class that inherits from the Throwable class. The
handler can refer to the exception with name.
On the other hand ExceptionListener is a specific only for JMS :
If a JMS provider detects a serious problem with a Connection object,
it informs the Connection object's ExceptionListener, if one has been
registered. It does this by calling the listener's onException method,
passing it a JMSException argument describing the problem. An
exception listener allows a client to be notified of a problem
asynchronously. Some connections only consume messages, so they would
have no other way to learn that their connection has failed.
A JMS provider should attempt to resolve connection problems itself
before it notifies the client of them.
In your case you'll have to use both try/catch and ExceptionListener. ExceptionListener is JMS specific and so you will not use it much. try/catch is a fundamental for Java.

Injecting datasource in EJB

When you inject a datasource in your application and get a connection by invoking getConnection() on it, are you supposed to close the connection?
Even though the datasource itself is container managed, the API indeed requires the programmer to close connections. This is different from a couple of other container managed resources (like the entity manager), where the container takes care of closing. Note that closing here in the majority of cases doesn't actually closes the connection here, but returns the connection to a connection pool.
As a rule of thumb, if you use a factory-ish resources to obtain one or more other resources from that can be closed, you have to close them. Otherwise the container does this.
Since Connection implements AutoCloseable, you can use a try-with-resources block for this:
#Stateless
public class MyBean {
#Resource(lookup = "java:/app/datasource")
private DataSource dataSource;
public void doStuff() {
try (Connection connection = dataSource.getConnection()) {
// Work with connection here
} catch (SQLException e) {
throw new SomeRuntimeException(e);
}
}
}
Of course, otherwise you'll exhaust your connection pool. It's best to do this in finally block:
#Resource(mappedName="jndi/yourDatasource")
DataSource ds;
..
Connection conn = null;
try {
conn = ds.getConnection();
//PERFORM QUERY, ETC..
}
catch(SQLException ex) {
//EXCEPTION HANDLING
}
finally {
try {
if(conn != null)
conn.close();
}
catch(SQLException ex) {..}
}

Categories

Resources