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
Context
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.