You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by "David Rauschenbach (JIRA)" <ji...@apache.org> on 2007/08/29 23:12:30 UTC

[jira] Created: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
----------------------------------------------------------------------------

                 Key: JCR-1099
                 URL: https://issues.apache.org/jira/browse/JCR-1099
             Project: Jackrabbit
          Issue Type: Bug
          Components: SPI
    Affects Versions: 2.0
            Reporter: David Rauschenbach


The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.

Calling code:

    Session sess = repo.login(creds);
    Node inboxNode = sess.getRootNode().getNode("Inbox");
    inboxNode.getPath(); <== blows stack

Tracing reveals:

    1. NodeEntryImpl.getPath() ultimately calls getIndex()
    2. getIndex() calls NodeState.getDefinition()
    3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
    4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
    5. which calls NodeEntryImpl.getWorkspaceIndex()
    6. which calls getIndex() (back to step 2, ad infinitum)

Configuration:
    1. A configuration is loaded specifying in-memory persist manager
    2. Config is wrapped in TransientRepository
    3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
    4. a jcr2spi provider is instantiated that directly couples to spi2jcr
    5. Node in question is created as follows:

    Session sess = repo.login(creds);
    sess.getRootNode().addNode("Inbox", "nt:folder");
    sess.save();

I guess that's about it.
David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "Julian Reschke (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Julian Reschke updated JCR-1099:
--------------------------------

    Assignee:     (was: Julian Reschke)

OK, the problem can be relatively easily reproduced by changing ItemDefinitionProviderImpl.getQNodeDefinition() to

    public QNodeDefinition getQNodeDefinition(NodeState nodeState) throws RepositoryException {
        if (nodeState.getHierarchyEntry().getParent() == null) {
            return getRootNodeDefinition();
        }
        QNodeDefinition definition;
        try {
            // TEST
            throw new ConstraintViolationException();
        } catch (RepositoryException e) {
            definition = service.getNodeDefinition(sessionInfo, nodeState.getNodeEntry().getWorkspaceId());
        } catch (NodeTypeConflictException e) {
            definition = service.getNodeDefinition(sessionInfo, nodeState.getNodeEntry().getWorkspaceId());
        }
        return definition;
    }

I think we need to fix this, but I'm not sure where in the recursion the fix needs to take place.


> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "angela (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12524042 ] 

angela commented on JCR-1099:
-----------------------------

hi david

i tried to reproduce the problem with the instructions you provided: 
therefore i created a tests that creates and accesses a node as you did. running that test with my default setup (jcr2spi-spi2jcr-on-jackrabbit). that worked for me.

second, i re-read your description regarding configuration setup. unfortunately i don't get it.
what do you mean by:

"3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig" ?
and
"4. a jcr2spi provider is instantiated that directly couples to spi2jcr" ?

please provide additional information that allows me to understand your setup and reproduce the problem.
thanks

angela

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: angela
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12524147 ] 

David Rauschenbach commented on JCR-1099:
-----------------------------------------

Angela, in your test, make sure you don't perform getPath() in the same session that created the test node. Your test would be invalid because of the cache being primed.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: angela
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12523884 ] 

David Rauschenbach commented on JCR-1099:
-----------------------------------------

That wouldn't change the flow. I'm having a ConstraintViolationException thrown, so it'd get caught the same way. The exception message is "no matching child node definition found for {}Inbox". I guess that's my ultimate problem, that my effective node type object has empty named and unnamed node definition arrays. But those values are coming straight from the in-memory transient repository, through my SPI bridge, so I don't see where the values could get dropped.

Nevertheless, if those arrays are empty (maybe due to a counterpart flaw in spi2jcr?), this flow still seems to be invalid, since an SPI can return anything, and it should not trigger a crash.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 1.4
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

David Rauschenbach updated JCR-1099:
------------------------------------

    Affects Version/s:     (was: 2.0)
                       1.4

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 1.4
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "Julian Reschke (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Julian Reschke reassigned JCR-1099:
-----------------------------------

    Assignee: Julian Reschke  (was: angela)

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: Julian Reschke
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "Julian Reschke (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12523824 ] 

Julian Reschke commented on JCR-1099:
-------------------------------------

Could you try changing ItemDefinitionProviderImpl.getQNodeDefinition() to catch a ConstraintViolationException instead of RepositoryException? 


> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 1.4
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12526314 ] 

David Rauschenbach commented on JCR-1099:
-----------------------------------------

I have identified and resolved the trigger of this problem. In my SPI, my NodeTypeDefinition "propertyDefs" were not being populated.

Fixing this bug is not a pressing issue for me now, and could probably be a low priority, since it is now only a matter of defensive programming, and preventing bad data from crashing the JVM, and also an issue of the stack overflow obscuring and complicating the problem solving process.

Thx again, Angela and Julian.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "angela (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12533166 ] 

angela commented on JCR-1099:
-----------------------------

i see 2 possibilities to solve this (apart from the obvious one "get rid of SNSs" ;-)):

1) only check for NodeDefinition.allowsSNS if the definition has been retrieved before.
     if the definition is not yet present (which is the default for existing nodes), the index is calculated from the
     parents child entries.
     potential drawback: more traffic to the server since the entries list probably more often get invalidated compared 
     to the chance, that no matching definition is found in the ItemDefinitionProvider (which would result in the 
    described problem).

2) omit the fallback in ItemDefinitionProvider, that tries to retrieve the definition from the server
     if no matching definition can be found.
     drawback: if the definition is not available on the client, the retrieval of the definition fails with exception. i couldn't
     produce that since in my test case all definitions are available, but i'm quite sure that this would cause problems.

so... basically i would prefer 2) but i think 1) is the proper solution to go for just for the sake of stability and that
special (unlikely?) case that no matching definition can be found....  
comments?

angela

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Re: [jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by Angela Schreiber <an...@day.com>.
hi david

jira is down again :(
here some thoughts, that i would have put into the issue....

//---------------------------------------------------------------------

so, you are having:

jcr2spi -> your spi impl -> spi2jcr -> jackrabbit.

is that correct?
in that case i would like you to check, whether it makes a difference if 
you omit 'your spi impl'. and if it indeed would make
a difference i suggest, that you provide some analysis on this.

it's perfectly possible, that the jcr2spi does not behave properly, but 
i don't like guessing.
and maybe its the SPI that unintentionally leaves room for 
interpretation (or jcr2spi is expecting the wrong thing)....

//---------------------------------------------------------------------

kind regards
angela




David Rauschenbach (JIRA) wrote:
>     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12524114 ] 
> 
> David Rauschenbach commented on JCR-1099:
> -----------------------------------------
> 
> Thanks Angela,
> 
> Here's what I mean by my spi2jcr setup (repository.xml already attached):
> 
>     // Bring up the in-mem repository
>     final URL REPOSITORY_URL = getClass().getClassLoader().getResource("/repository.xml");
>     storageDir = new File(System.getProperty("java.io.tmpdir"));
>     RepositoryConfig config = RepositoryConfig.create(REPOSITORY_URL.toURI(), storageDir.getAbsolutePath());
>     repository = new TransientRepository(config);
> 
>     // Bring up the spi2jcr bridge in front of in-memory repository
>     BatchReadConfig batchReadConfig = new BatchReadConfig();
>     RepositoryService spi2jcrRepositoryService = new RepositoryServiceImpl(repository, batchReadConfig);
> 
> Next, I wrote an SPI that is coupled to that spi2jcrRepositoryService. I wrap my SPI in jcr2spi, so that's what I meant by the direct coupling of a JCR front-end being invoked by unit tests, a jcr back-end that's the in-mem store, and an SPI coupling inbetween.
> 
>> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
>> ----------------------------------------------------------------------------
>>
>>                 Key: JCR-1099
>>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>>             Project: Jackrabbit
>>          Issue Type: Bug
>>          Components: SPI
>>            Reporter: David Rauschenbach
>>            Assignee: angela
>>         Attachments: repository.xml
>>
>>
>> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
>> Calling code:
>>     Session sess = repo.login(creds);
>>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>>     inboxNode.getPath(); <== blows stack
>> Tracing reveals:
>>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>>     2. getIndex() calls NodeState.getDefinition()
>>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>>     6. which calls getIndex() (back to step 2, ad infinitum)
>> Configuration:
>>     1. A configuration is loaded specifying in-memory persist manager
>>     2. Config is wrapped in TransientRepository
>>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>>     5. Node in question is created as follows:
>>     Session sess = repo.login(creds);
>>     sess.getRootNode().addNode("Inbox", "nt:folder");
>>     sess.save();
>> I guess that's about it.
>> David
> 

[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12524114 ] 

David Rauschenbach commented on JCR-1099:
-----------------------------------------

Thanks Angela,

Here's what I mean by my spi2jcr setup (repository.xml already attached):

    // Bring up the in-mem repository
    final URL REPOSITORY_URL = getClass().getClassLoader().getResource("/repository.xml");
    storageDir = new File(System.getProperty("java.io.tmpdir"));
    RepositoryConfig config = RepositoryConfig.create(REPOSITORY_URL.toURI(), storageDir.getAbsolutePath());
    repository = new TransientRepository(config);

    // Bring up the spi2jcr bridge in front of in-memory repository
    BatchReadConfig batchReadConfig = new BatchReadConfig();
    RepositoryService spi2jcrRepositoryService = new RepositoryServiceImpl(repository, batchReadConfig);

Next, I wrote an SPI that is coupled to that spi2jcrRepositoryService. I wrap my SPI in jcr2spi, so that's what I meant by the direct coupling of a JCR front-end being invoked by unit tests, a jcr back-end that's the in-mem store, and an SPI coupling inbetween.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: angela
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

David Rauschenbach updated JCR-1099:
------------------------------------

    Attachment: repository.xml

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 2.0
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "Julian Reschke (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12526003 ] 

Julian Reschke commented on JCR-1099:
-------------------------------------

I haven't been able to reproduce this either.

However, what's clear is that a recursion can occur, because:

- to build the path, we want to know whether the parent allows same-name siblings, so we need that node definition,

- calculation the node definition inside JCR2SPI *can* lead to an exception, and

- re-fetching the QNodeDef through SPI requires knowledge of the node id, whose construction may need the index.



> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: angela
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "angela (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

angela resolved JCR-1099.
-------------------------

    Resolution: Fixed

resolved as described in variant 1).

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "angela (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

angela updated JCR-1099:
------------------------

             Assignee: angela
    Affects Version/s:     (was: 1.4)

i will take a look at it.
btw: jcr2spi is not released yet -> remove 'affected version'


> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>            Assignee: angela
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "angela (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12531823 ] 

angela commented on JCR-1099:
-----------------------------

> I think we need to fix this, but I'm not sure where in the recursion the fix needs to take place. 

without having a close look at it, i would guess the best place would be the NodeEntry.getIndex.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "Julian Reschke (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12523904 ] 

Julian Reschke commented on JCR-1099:
-------------------------------------

Understood and agreed. I just wanted to make sure it's not a non-ConstraintViolationException that shouldn't have been called in the first place.


> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 1.4
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (JCR-1099) jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself

Posted by "David Rauschenbach (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-1099?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12523905 ] 

David Rauschenbach commented on JCR-1099:
-----------------------------------------

The bottom line, I think, is that in my case the jcr2spi bridge is unable to get around to making the getNodeDefinition SPI invocation, because the call to NodeEntry.getWorkspaceId()  at ItemDefinitionProviderImpl.java:90, which would provide the NodeId to use as the second argument, causes the recursion.

> jcr2spi NodeEntryImpl.getPath() blows stack due to getIndex() calling itself
> ----------------------------------------------------------------------------
>
>                 Key: JCR-1099
>                 URL: https://issues.apache.org/jira/browse/JCR-1099
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: SPI
>    Affects Versions: 1.4
>            Reporter: David Rauschenbach
>         Attachments: repository.xml
>
>
> The jcr2spi NodeEntryImpl class contains logic that causes getIndex() to call itself.
> Calling code:
>     Session sess = repo.login(creds);
>     Node inboxNode = sess.getRootNode().getNode("Inbox");
>     inboxNode.getPath(); <== blows stack
> Tracing reveals:
>     1. NodeEntryImpl.getPath() ultimately calls getIndex()
>     2. getIndex() calls NodeState.getDefinition()
>     3. which calls ItemDefinitionProviderImpl.getQNodeDefinition(...)
>     4. which catches a RepositoryException then calls NodeEntryImpl.getWorkspaceId()
>     5. which calls NodeEntryImpl.getWorkspaceIndex()
>     6. which calls getIndex() (back to step 2, ad infinitum)
> Configuration:
>     1. A configuration is loaded specifying in-memory persist manager
>     2. Config is wrapped in TransientRepository
>     3. that's wrapped in spi2jcr's RepositoryService using default BatchReadConfig
>     4. a jcr2spi provider is instantiated that directly couples to spi2jcr
>     5. Node in question is created as follows:
>     Session sess = repo.login(creds);
>     sess.getRootNode().addNode("Inbox", "nt:folder");
>     sess.save();
> I guess that's about it.
> David

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.