[ 
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.

Reply via email to