jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Marcel Reutegger (JIRA)" <j...@apache.org>
Subject [jira] Commented: (JCR-2238) Binary throws NullPointerException
Date Tue, 04 Aug 2009 10:23:14 GMT

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

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

View raw message