Reputation: 786
I'm new to Java's AutoClosable interface (but not new to Java). I'm trying to force client code which requests an instance of WebDriver
to close the driver
after it finishes using it (by calling driver.quit()
)
I want a way to force any method that instantiates instance of WebDriver
to close it.
So I created a new class that implements AutoClosable
:
public class WebDriverLauncher implements AutoCloseable {
WebDriver driver;
public WebDriverLauncher()
{
driver = new FirefoxDriver();
}
public WebDriver getDriver()
{
return driver;
}
@Override
public void close() throws Exception {
driver.quit();
}
}
Now instead of instantiating WebDriver directly (WebDriver driver = new FirefoxDriver()
) I'm instantiating instance of this class and have it return an instance of WebDriver
such as in the following example:
public WebDriver launchDriver()
{
WebDriverLauncher webDriverLauncher = new WebDriverLauncher();
WebDriver driver = webDriverLauncher.getDriver();
return driver;
}
When I do this I receive a warning/error: Resource leak: 'webDriverLauncher' is never closed
Since I cannot close the resource within this method because the resource (i.e, WebDriver
) is being used in the caller method I want to force the caller of launchDriver()
to close the driver
.
So instead I decided to have the method return an instance of WebDriverLauncher
- such as in the following example:
public WebDriverLauncher launchDriver()
{
WebDriverLauncher webDriverLauncher = new WebDriverLauncher();
return webDriverLauncher;
}
This way the caller will have access to driver
(by calling webDriverLauncher .getDriver()
) and be warned to close the resource (so I thought).
However, when I tried this, the warning message disappeared entirely. In other words, I no longer see the warning to close resource - neither in the launchDriver()
class/method nor in the caller/client class (As I mentioned, I want the warning to appear so whoever calls this method is warned to close resource)
What I'm trying to understand is the following:
1) Why isn't the warning propagated up to the caller class (if the resource has never been closed)?
2) Why does the warning disappear when I return webDriverLauncher
but not when I return driver
?
3) Is there a way to modify the code to force the warning to propagated up the caller? (so as to warn the caller of this method to close the resource)
4) If this cannot be done, what can be done to force the client to close WebDriver
?
Thanks!
Upvotes: 0
Views: 911
Reputation: 63
I am late for this question. But here is my take: If we want to force client to use resource carefully, we can restrict the resource creation (private constructor plus disable reflection access by enabling property -Djava.security.manager
for jar
) and allow clients to only provide method to be called on that resource to the Resource factory.
public class MyResource implements AutoCloseable {
public static class ResourceFactory {
public static void useResourceSafely(Consumer<MyResource> work) {
try(MyResource res = new MyResource()) {
work.accept(res);
}
catch(Exception e) {
e.printStackTrace();
//you may even check for Suppressed exceptions
}
}
}
private MyResource() {
System.out.println("Resource created");
}
public void doWork() {
System.out.println("resource in use");
}
@Override
public void close() throws Exception {
System.out.println("Closing myResource");
}
}
Client code may look like this:
public static void main(String[] args) throws Exception {
ResourceFactory.useResourceSafely(s -> {
s.doWork();
System.out.println("Check 1");
s.doWork();
System.out.println("Check 2");
});
}
This might not be recommended way, but just an attempt to do so.
Upvotes: 1
Reputation: 129
Using Try-with-resources statement:
try (WebDriverLauncher webDriverLauncher = new WebDriverLauncher(){
//Your Code Here
}//webDriverLauncher.close() will be called after here weather throw any exception in try...catch block or not.
In other worlds, AutoClosable
interface is a constraint to determine which type can be used in Try-with-resources statement
Upvotes: -1