Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try-with-resources fails to call close()

I am using the handy try-with-resources statement to close connections. This works great in most cases but only in one utterly simple method it does not work properly. Namely, here:

public boolean testConnection(SapConnection connection) {
  SapConnect connect = createConnection(connection);
  try ( SapApi sapApi = connect.connect() ) {
    return ( sapApi != null );
  } catch (JCoException e) {
    throw new UncheckedConnectionException("...", e);
  }
}

The sapApi object is non-null, the method returns true, but the close() method of sapApi is never called. I now resorted to use a finally block which works fine. But this is quite puzzling. The Java byte code also contains a call to close. Has anyone seen this behavior before?

Edit to clarify the situation:

This is the SapApi, it implements AutoCloseable, of course.

class SapApi implements AutoCloseable {

  @Override
  public void close() throws JCoException {
    connection.close(); // this line is not hit when leaving testConnection(..)
  }
..
}

The following is another method in the same class as testConnection(..). Here SapApi.close() is called before returning.

@Override
public List<Characteristic> selectCharacteristics(SapConnect aConnection,   InfoProvider aInfoProvider) {
  try (SapApi sapi = aConnection.connect()) {
    return sapi.getCharacteristics(aInfoProvider);
  } catch ( Exception e ) {
    throw new UncheckedConnectionException(e.getMessage(), e);
  }
}

Edit 2: This is SapConnect.connect():

SapApi connect() {
  try {
    ... // some setup of the connection
    return new SapApi(this); // single return statement
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

SapApi has no subclasses. There is just one implementation with the close method as above. In particular, there is no empty close().

like image 404
avidD Avatar asked Oct 20 '22 15:10

avidD


2 Answers

In order for close() to be called, SapApi must implement AutoCloseable interface, but since we are talking about connection, it is more appropriate that you SapApi will implement Closable interface which throws IOException.

Read this: http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html

like image 139
Eyal Avatar answered Oct 22 '22 07:10

Eyal


I do not know what you mean by

This works great in most cases

1 That normally the SapApi is closed when used in try-with-resources

or

2 That it normally works for resources other than SapApi

I am answering on the assumption of number 2.

Try-with-resources will only work in Java 7 for resources that implement the AutoCloseable interface. So my first advice would be to for you to check the API for SapConnect and SapApi (whatever they are) to determine if that is the case.

like image 20
APD Avatar answered Oct 22 '22 08:10

APD