Closing resources created in failed constructor - oop

Assume I have a class C that holds resources that need to be closed as member variables.
public class C {
private ClosableResource1 closableResource1;
private ClosableResource2 closableResource2;
.....
public C(){
closableResource1 = new ClosableResource1();
closableResource2 = new ClosableResource2();
.....
// some logic that can fail
}
close(){
closableResource1.close()
closableResource2.close()
.....
}
}
If the constructor succeeds I can be sure that close() will be called eventually by some entity manager and all the resources will be freed.
But how can I make sure I close the resources when the constructor fails? The failure can happen because I have additional logic in the constructor that can throw exception or I get some RuntimeException outside of my control?
Some things I though of:
Wrapping the constructor body with a try-catch block. Then, assuming I have a lot of closable members I'll have to have a big if statement in the catch block checking which resources were already initializing and only close them.
Offloading the ClosableResources creation to some init() function. Then I would have to make sure init() succeeded every time I try to use the object.
Is there some elegant solution? Or is this much more implementation specific then that?

You can do something like below:
public class C {
private List<AutoCloseable> closableResources = new ArrayList();
private ClosableResource1 closableResource1;
private ClosableResource2 closableResource2;
.....
public C() {
closableResource1 = new ClosableResource1();
closableResources.add(closableResource1)
closableResource2 = new ClosableResource2();
closableResources.add(closableResource2);
.....
try {
// some logic that can fail
} catch(Exception e) {
close();
}
}
close(){
for (AutoCloseable closableResource : closableResources) {
if (closableResource != null) {
closableResource.close();
}
}
}
}

Surrounding your code with try-catch and closing all your resources in catch is the correct solution here. Also read about method finalize() (Here is one tutorial). In general, I would recommend one method that cleans up all the resources (like you suggested method close(), I would call it though cleanup()) and call that method in your catch section and in your finalize() method

I asked and answered a very similar question here. It is very important that a constructor either succeeds or fails completely i.e. leaving no resources open. In order to achieve that I would follow each resource creation statement by a try-catch block. The catch block closes the resource and rethrows the exception so it is not lost:
public C() {
closableResource1 = new ClosableResource1();
closableResource2 = new ClosableResource2();
try {
// .....
// some logic that can fail and throw MyCheckedException or some RuntimeException
} catch (RuntimeException | MyCheckedException e) {
try {closableResource1.close();} catch (Exception ignore) {}
try {closableResource1.close();} catch (Exception ignore) {}
throw e;
}
}
If creating a resource can fail you need nested try-catch blocks as demonstrated here.

Here's a wild idea: create a class called something like DefusableCloser (that you can "defuse", like an explosive device being made safe):
class DefusableCloser implements AutoCloseable {
boolean active = true;
final AutoCloseable closeable;
DefusableCloser(AutoCloseable closeable) {
this.closeable = closeable;
}
#Override public void close() throws Exception {
if (active) closeable.close();
}
}
Now you can use this in a try-with-resources block:
c1 = new CloseableResource();
try (DefusableCloseable d1 = new DefusableCloseable(c1)) {
c2 = new CloseableResource();
try (DefusableCloseable d2 = new DefusableCloseable(c2)) {
// Do the other stuff which might fail...
// Finally, deactivate the closeables.
d1.active = d2.active = false;
}
}
If execution doesn't reach d1.active = d2.active = false;, the two closeables (or one, if the exception was in creating the second resource) will be closed. If execution does reach that line, they won't be closed and you can use them.
The advantage of doing it like this is that the exceptions will be correctly handled.
Note that the ordering is important: don't be tempted to create the two CloseableResources first, then the two DefusableCloseables: doing that won't handle an exception from creating the second CloseableResource. And don't put the creation of the CloseableResources into the TWR, as that would guarantee their closure.
For closing the resources in your class' close() method, you can also use try-with-resources to ensure that both resources are closed:
try (c1; c2) {}
You don't actually have to declare a new variable in the TWR syntax: you can just effectively say "close the resource for this existing variable afterwards", as shown here.

Related

What's the point of the use function in Kotlin

I'm trying to use the inline function use with a FileInputStream instead of the classic try/catch IOException so that
try {
val is = FileInputStream(file)
// file handling...
}
catch (e: IOException) {
e.printStackTrace()
}
becomes
FileInputStream(file).use { fis ->
// do stuff with file
}
My question is, why use the function use if it stills throws exception? Do I have to wrap use in a try/catch? This seems ridiculous.
From Kotlin documentation:
Executes the given block function on this resource and then closes it
down correctly whether an exception is thrown or not.
When you use an object that implements the Closeable interface, you need to call the close() method when you are done with it, so it releases any system resources associated with the object.
You need to be careful and close it even when an exception is thrown. In this kind of situation that is error prone, cause you might not know or forget to handle it properly, it is better to automate this pattern. That's exactly what the use function does.
Your try-catch does not close the resource so you are comparing apples to oranges. If you close the resource in finally block:
val is = FileInputStream(file)
try {
...
}
catch (e: IOException) {
...
}
finally {
is.close()
}
is definitely more verbose than use which handles closing the resource.

Handling exceptions with in velocity template

How do I handle exceptions with in velocity template when I am processing say 100 records in a loop. If I get an exception while processing one record then I should be able to continue with the next record. Is this possible with velocity template or this needs to be handled in java.
What is the best way to handle exceptions when using velocity templates?
Thanks for your clarification
There is no exception flow control handling inside the template itself. If an exception is thrown, the rendering of the current template will stop and the exception will be logged and displayed in the output. The overall philosophy is to try to contain the exceptions to the Java objects methods.
For instance, instead of exposing Object MyObject.mayThow() into the template, you can use a wrapper:
class MyWrapper
{
bool doesntThrow()
{
try
{
return mayThrow()
}
catch (MyException e)
{
// log it if necessary
return null
}
}
}
And in the template:
#foreach($i in $items)
## ...
#set ($obj = $i.doesntThrow())
#if($obj)
## ...
#end
#end
Instead of a wrapper, you can also use a MethodExceptionEventHandler:
package mypackage;
import org.apache.velocity.app.event.MethodExceptionEventHandler;
public class MyHandler implements MethodExceptionEventHandler
{
public Object methodException(Class claz, String method, Exception e) throws Exception
{
// for instance, return null as a convention
if (claz == MyObject.class && method.equals("doesThrow")) return null;
// something else happened...
else throw e;
}
}
And you can then directly call mayThrow() in the template:
#foreach($i in $items)
## ...
#set ($obj = $i.mayThrow())
#if($obj)
## ...
#end
#end
Of course you have to register your event handler in your velocity.properties file:
eventhandler.methodexception.class = mypackage.MyHandler

Should a class be able to catch an exception from a class that it doesn't know about?

I wrote some code in an MVC Framework that looks something like:
class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
try
{
$results = $obj->doSomething();
}
catch(MyObject_Exception $e)
{
$e->getErrors();
}
catch(Exception $e)
{
$errors[] = $e->getMessage();
}
}
My friend argues that the Controller should know nothing about MyObject, and therefore I should not catch MyObject_Exception.
He argues that the code should do something like this instead:
class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
if($obj->doSomething())
{
$results = $obj->getResults();
}
else
{
$errors = $obj->getErrors();
}
}
I definitely understand his approach, but feel as though state management can lead to unintended side effects.
What is the right or preferred approach?
Edit: mistakenly put $obj->getErrors() in MyObject_Exception catch clause instead of $e->getErrors();
The debate about exceptions vs. returned error codes is a long and bloody one.
His argument breaks down in that, by using a getErrors() function, you are learning information about the object. If that is your reason for using a boolean return to indicate success, then you are wrong. In order for the Controller to handle the error properly, it has to know about the object it was touching and what the specific error was. Was it a network error? Memory error? It has to know in some way or another.
I prefer the exception model because it's cleaner and allows me to handle more errors in a more controlled fashion. It also provides a clear cut way for the data relating to an exception to be passed.
However, I disagree with your use of a function like getErrors(). Any data pertaining to the exception that would help me handle it should be included with the exception. I should not have to go hunting into the object again to get information about what went wrong.
Did the network connection timeout? The exception should contain the host/port it tried to connect to, how long it waited, and any data from the lower networking levels.
Let's do this in example (in psuedo c#):
public class NetworkController {
Socket MySocket = null;
public void EstablishConnection() {
try {
this.MySocket = new Socket("1.1.1.1",90);
this.MySocket.Open();
} catch(SocketTimeoutException ex) {
//Attempt a Single Reconnect
}
catch(InvalidHostNameException ex) {
Log("InvalidHostname");
Exit();
}
}
}
Using his method:
public class NetworkController {
Socket MySocket = null;
public Boolean EstablishConnection() {
this.MySocket = new Socket("1.1.1.1",90);
if(this.MySocket.Open()) {
return true;
} else {
switch(this.MySocket.getError()) {
case "timeout":
// Reattempt
break;
case "badhost":
Log("InvalidHostname");
break;
}
}
}
}
Ultimately, you need to know what happened to the object to know how to respond to it, and there is no sense in using some convoluted if statement set or switch-case to determine that. Use the exceptions and love them.
EDIT: I accidentally the last half of a sentence.
In general, I would say that what's important is whether the controller understands the meaning of the exception and can handle it properly. In many cases (if not most), the controller will not know how to properly handle the exception, and so should not catch and handle it.
On the other hand, the controller might reasonably be permitted to understand some specific exception like a "DatabaseUnavailableException", even if it has no idea how or why MyObject used a database. The controller might be permitted to retry the call to MyObject a certain number of times, all without knowing about how MyObject is implemented.
First of all controller is not meant for handling the underlying exceptions thrown by classes.
Even if one occurs controller should halt saying something wrong at underlying error.
This way we make sure that controller does really and only do the job of flow control.
The other classes which give controller some output should be error free unless the error is very much controller specific.

How to tell the Session to throw the error query[NHibernate]?

I made a test class against the repository methods shown below:
public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File
{
try
{
_session.Save(FileToAdd);
_session.Flush();
}
catch (Exception e)
{
if (e.InnerException.Message.Contains("Violation of UNIQUE KEY"))
throw new ArgumentException("Unique Name must be unique");
else
throw e;
}
}
public void RemoveFile(File FileToRemove)
{
_session.Delete(FileToRemove);
_session.Flush();
}
And the test class:
try
{
Data.File crashFile = new Data.File();
crashFile.UniqueName = "NonUniqueFileNameTest";
crashFile.Extension = ".abc";
repo.AddFile(crashFile);
Assert.Fail();
}
catch (Exception e)
{
Assert.IsInstanceOfType(e, typeof(ArgumentException));
}
// Clean up the file
Data.File removeFile = repo.GetFiles().Where(f => f.UniqueName == "NonUniqueFileNameTest").FirstOrDefault();
repo.RemoveFile(removeFile);
The test fails. When I step in to trace the problem, I found out that when I do the _session.flush() right after _session.delete(), it throws the exception, and if I look at the sql it does, it is actually submitting a "INSERT INTO" statement, which is exactly the sql that cause UNIQUE CONSTRAINT error. I tried to encapsulate both in transaction but still same problem happens. Anyone know the reason?
Edit
The other stay the same, only added Evict as suggested
public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File
{
try
{
_session.Save(FileToAdd);
_session.Flush();
}
catch (Exception e)
{
_session.Evict(FileToAdd);
if (e.InnerException.Message.Contains("Violation of UNIQUE KEY"))
throw new ArgumentException("Unique Name must be unique");
else
throw e;
}
}
No difference to the result.
Call _session.Evict(FileToAdd) in the catch block. Although the save fails, FileToAdd is still a transient object in the session and NH will attempt to persist (insert) it the next time the session is flushed.
NHibernate Manual "Best practices" Chapter 22:
This is more of a necessary practice than a "best" practice. When
an exception occurs, roll back the ITransaction and close the ISession.
If you don't, NHibernate can't guarantee that in-memory state
accurately represents persistent state. As a special case of this,
do not use ISession.Load() to determine if an instance with the given
identifier exists on the database; use Get() or a query instead.

What is the most efficient way to handle the lifecycle of an object with COM interop?

I have a Windows Workflow application that uses classes I've written for COM automation. I'm opening Word and Excel from my classes using COM.
I'm currently implementing IDisposable in my COM helper and using Marshal.ReleaseComObject(). However, if my Workflow fails, the Dispose() method isn't being called and the Word or Excel handles stay open and my application hangs.
The solution to this problem is pretty straightforward, but rather than just solve it, I'd like to learn something and gain insight into the right way to work with COM. I'm looking for the "best" or most efficient and safest way to handle the lifecycle of the classes that own the COM handles. Patterns, best practices, or sample code would be helpful.
I can not see what failure you have that does not calls the Dispose() method. I made a test with a sequential workflow that contains only a code activity which just throws an exception and the Dispose() method of my workflow is called twice (this is because of the standard WorkflowTerminated event handler). Check the following code:
Program.cs
class Program
{
static void Main(string[] args)
{
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
{
waitHandle.Set();
};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));
instance.Start();
waitHandle.WaitOne();
}
Console.ReadKey();
}
}
Workflow1.cs
public sealed partial class Workflow1: SequentialWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
this.codeActivity1.ExecuteCode += new System.EventHandler(this.codeActivity1_ExecuteCode);
}
[DebuggerStepThrough()]
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("Throw ApplicationException.");
throw new ApplicationException();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Here you must free your resources
// by calling your COM helper Dispose() method
Console.WriteLine("Object disposed.");
}
}
}
Am I missing something? Concerning the lifecycle-related methods of an Activity (and consequently of a Workflow) object, please check this post: Activity "Lifetime" Methods. If you just want a generic article about disposing, check this.
Basically, you should not rely on hand code to call Dispose() on your object at the end of the work. You probably have something like this right now:
MyComHelper helper = new MyComHelper();
helper.DoStuffWithExcel();
helper.Dispose();
...
Instead, you need to use try blocks to catch any exception that might be triggered and call dispose at that point. This is the canonical way:
MyComHelper helper = new MyComHelper();
try
{
helper.DoStuffWithExcel();
}
finally()
{
helper.Dispose();
}
This is so common that C# has a special construct that generates the same exact code [see note] as shown above; this is what you should be doing most of the time (unless you have some special object construction semantics that make a manual pattern like the above easier to work with):
using(MyComHelper helper = new MyComHelper())
{
helper.DoStuffWithExcel();
}
EDIT:
NOTE: The actual code generated is a tiny bit more complicated than the second example above, because it also introduces a new local scope that makes the helper object unavailable after the using block. It's like if the second code block was surrounded by { }'s. That was omitted for clarify of the explanation.