masesgroup / JCOReflector

A set of Java classes to use .NET from any JVM enabled language (Java, Kotlin, Scala and others)

Home Page:https://jcoreflector.masesgroup.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Associate java.lang.AutoCloseable interface to system.IDisposable interface

mariomastrodicasa opened this issue · comments

Is your feature request related to a problem? Please describe.
Classes that implements the Disposable interface in .NET are normally called with the using keyword. Reflected classes in java have not an equivalent paradigm to use.

Describe the solution you'd like
Implementing the AutoClosable interface in reflected java classes is possible to emulate the using statement behavior via the try-with-resource statement.

Describe alternatives you've considered
No alternative was considered because it seams a 1 to 1 replacement for the using statement.

Additional context
If StringReader implements the AutoClosable interface, the following c# code

using (StringReader reader = new StringReader(manyLines))
{
    do something with reader;
}

can be wrote in java as

try (StringReader reader = new StringReader(manyLines)) {
       do something with reader;
 }

To simplify the implementation and avoid to add new templates (like the ones related to IEnumerable and IEnumerator) I propose to:

  • Create a new Java class named NetObjectAutoCloseable which:
  • During reflection, if the class under analysis implements IDisposable, use NetObjectAutoCloseable as base class instead to use NetObject

The code stub of NetObjectAutoCloseable will be:

public class NetObjectAutoCloseable extends NetObject implements AutoCloseable {

// other code

    public void close() throws Exception {
        try {
            if (classInstance == null)
                throw new UnsupportedOperationException("classInstance is null.");
            try {
                classInstance.Invoke("Dispose");
            } catch (JCNativeException jcne) {
                throw translateException(jcne);
            }
        } catch (Throwable t) {
            throw new java.lang.Exception(t);
        }
    }
}

In my opinion the proposed solution is a better solution than introducing a new template.

To simplify the implementation and avoid to add new templates (like the ones related to IEnumerable and IEnumerator) I propose to:

  • Create a new Java class named NetObjectAutoCloseable which:

  • During reflection, if the class under analysis implements IDisposable, use NetObjectAutoCloseable as base class instead to use NetObject

The code stub of NetObjectAutoCloseable will be:

public class NetObjectAutoCloseable extends NetObject implements AutoCloseable {

// other code

    public void close() throws Exception {
        try {
            if (classInstance == null)
                throw new UnsupportedOperationException("classInstance is null.");
            try {
                classInstance.Invoke("Dispose");
            } catch (JCNativeException jcne) {
                throw translateException(jcne);
            }
        } catch (Throwable t) {
            throw new java.lang.Exception(t);
        }
    }
}

@marcocappolimases verify if the objects with AutoCloseable works as expected: we need to verify try-with-resource statement.

During the modification to the HelloHierarchy.java test file to use the try-with-resources statement, I discovered that Stream class doesn't implements AutoClosable because of his Hierarchy.

Checking better, the solution proposed in #16 (comment) does not cover all cases. The Stream class implements IDisposable interface, but inherits from MarshalByRefObject. The implementation of the reflector engines expects the IDisposable interface is at top-most hierarchy level. I think it is necessary to add a template in any case.

Checking better, the solution proposed in #16 (comment) does not cover all cases. The Stream class implements IDisposable interface, but inherits from MarshalByRefObject. The implementation of the reflector engines expects the IDisposable interface is at top-most hierarchy level. I think it is necessary to add a template in any case.

NetObjectAutoCloseable isn't enough to cover the cases, I will remove it and add, instead, an analyzer which adds the AutoCloseable interface in implements with the same close method use in NetObjectAutoCloseable.

Checking better, the solution proposed in #16 (comment) does not cover all cases. The Stream class implements IDisposable interface, but inherits from MarshalByRefObject. The implementation of the reflector engines expects the IDisposable interface is at top-most hierarchy level. I think it is necessary to add a template in any case.

NetObjectAutoCloseable isn't enough to cover the cases, I will remove it and add, instead, an analyzer which adds the AutoCloseable interface in implements with the same close method use in NetObjectAutoCloseable.

With commits db73348 and 2c004c0 I added the reflected code containing the modification: @marcocappolimases check if code now works with try-with-resources statement.