[
https://issues.apache.org/jira/browse/JCR-2238?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12738924#action_12738924
]
Marcel Reutegger commented on JCR-2238:
---------------------------------------
As can be seen in the test output, the property always returns the same Binary
instance. For most implementations this is not an issue because they are
immutable and Binary.dispose() is a noop. Without the data store, the binary
instance is a BLOBInTempFile, which has state and will delete the underlying
temp file on dispose().
It seems to me that ownership of a binary instance is not well defined (that
includes the spec, as well as in our jackrabbit modules). I think we should
clarify the following questions and adjust the implementation accordingly:
1) Does Value return a new instance of Binary on Value.getBinary()?
I'd say yes, because Binary.dispose() may change the state of the object.
though an implementation may chose to return a binary that has no state and
dispose() is a noop. see our various Binary implementations in jackrabbit-core.
implementation consequences: we need to change our Binary implementations that
are not immutable, otherwise a call to getBinary() will become potentially
expensive because a new instance needs to be created (i.e. a new temp file
spooled). some sort of reference counting might be a solution. we need to make
sure dispose() is called whenever getBinary() is used internally in jackrabbit.
it seems this is not always the case yet.
- Does Value become the owner of the given Binary on ValueFactory.createValue()
?
I'd say no, because Value does not have a defined life cycle. there is no
dispose (or similar) method on Value, hence a client does not know when the
given Binary is disposed. furthermore a client may wish to still use the given
binary after the call to createBinary().
so, this is how we use Binaries already in our code:
Node n = ...
Binary bin = ...
try {
Value v = vf.createValue(bin);
n.setProperty("foo", v);
n.setProperty("bar", v);
} finally {
bin.dispose();
}
but it seems Value must come the owner of a Binary, even if it is not the
instance passed in createValue(), because otherwise the following code will not
work:
Node n = ...
Binary bin = ...
Value v;
try {
v = vf.createValue(bin);
} finally {
bin.dispose();
}
n.setProperty("foo", v);
n.setProperty("bar", v);
question: is this valid?
I think, yes. the implementation in jackrabbit core already creates a new
Binary instance in this situation. (but the implementation in jcr-commons
doesn't :-/)
Unfortunately this has the consequence that we need to add a finalize method to
either the temporary (?) resource backed Binary implementations or the Value
implementation. whenever possible we should avoid creating a Value instance for
a binary (at least internally in jackrabbit).
does anyone have an alternative solution?
> Binary throws NullPointerException
> -----------------------------------
>
> Key: JCR-2238
> URL: https://issues.apache.org/jira/browse/JCR-2238
> Project: Jackrabbit Content Repository
> Issue Type: Bug
> Components: jackrabbit-core
> Reporter: Marcel Reutegger
> Attachments: BinaryValueTest.patch
>
>
> Precondition: repository with datastore disabled!
> Steps to reproduce:
> 1) create binary from stream
> 2) set binary on property
> 3) dispose binary
> 4) get binary from property and dispose it immediately
> 5) go to 4)
> Binary.dispose() will throw a NullPointerException when 4) is executed the
> second time.
> The exception is not thrown if the property is saved after 2).
> See also attached test.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.