On Fri, Sep 13, 2013 at 02:28:35PM +0200, Stephan Bergmann wrote: > On 09/13/2013 11:07 AM, Lionel Elie Mamane wrote: >> On Wed, Sep 11, 2013 at 12:35:15PM +0200, Stephan Bergmann wrote:
>>> First, note that we don't have reference-counting garbage collection >>> in general in UNO. For example, Java-UNO doesn't use >>> reference-counting. >>> Second, note that there needs to be code (the "owner" in the jargon >>> of the udkapi/com/sun/star/lang/XComponent.idl documentation) that >>> explicitly calls dispose on a UNO object. It is not magically >>> called when a UNO object becomes unreachable. >> So let's take the concrete example of >> reportbuilder/java/org/libreoffice/report/SDBCReportDataFactory.java >> around line 233: >> private String getOrderStatement(final int commandType, final String >> command, final List sortExpressions) >> Concretely, the Java code does: >> final XComponent[] hold = new XComponent[1]; >> final XNameAccess columns = getFieldsByCommandDescriptor(commandType, >> command, hold); >> I assume this whole rigmarole with "hold" is to ensure that >> "dispose()" is called on "columns", providing an owner for it. >> (I assume it uses this round-about way instead of just declaring the >> caller the owner of columns because in some conditions columns will be >> a temporary and in other conditions, it will not; with this setup, >> this is testable with (hold[0] == null)). > (At least the documentation you cite above does not make it look > like keepFieldsAlive could return a null reference.) In my quote of the documentation, I simplified this point away. It depends. Sometimes it returns a temporary object (owned by another temporary that is put in keepFieldsAlive) and sometimes it returns a long-lived "shared" object that the caller should *not* dispose. >> So I need to do something like: >> final XComponent[] hold = new XComponent[1]; >> try >> { >> (...) >> final XNameAccess columns = getFieldsByCommandDescriptor(commandType, >> command, hold); >> (...) >> if(hold[0] != null) >> hold[0].dispose(); >> } >> catch (SQLException ex) >> { >> if(hold[0] != null) >> hold[0].dispose(); >> LOGGER.error("ReportProcessing failed", ex); >> } >> catch(java.lang.Exception e) >> { >> if(hold[0] != null) >> hold.dispose(); >> throw e; >> } > Why not use a finally block? Because my knowledge of Java is limited to what I had to learn. finally blocks seem to be *exactly* what is needed indeed. Thanks for the pointer. >> Did I understand what you were saying correctly? This function (and >> _any_ code getting a fresh/temporary UNO object) needs to clean up >> after itself manually in this pedestrian, error-prone way? Do we get a >> cop-out in C++ because of the use of com::sun::star::uno::Reference >> which calls _pInterface->release()? Do we get a cop-out in any other >> UNO language? (Python? Basic?) > This specific Java code obtaining ownership of an XComponent is > supposed to follow the protocol of XComponent and ensure that > dispose is called, yes. But not every UNO object implements the > XComponent protocol, so there is lots of code obtaining references > to UNO objects that does not need to do this sort of clean-up. So basically, the documentation of the API call should tell you whether you have to do that or not. OK. -- Lionel _______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice