Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-16694

After renaming a BlogPost, pageManager.getById() return a Page, not a BlogPost

    • Icon: Bug Bug
    • Resolution: Answered
    • Icon: Low Low
    • None
    • 3.0.1
    • None
    • Standalone, Java 1.6.0_15-b03, Windows.

      After renaming a BlogPost, pageManager.getById() starts to return a Page, not a BlogPost.

      It only seems to happen when inside an Action. Inside a Macro, it works fine, it returns a BlogPost.

      And it only seems to happen after the BlogPost is renamed. Before renaming it, it works fine, it returns a BlogPost. After the renaming, it returns a Page.

      Before:

      url of blogpost 'blogpost: demo page v.1 (13598761)'=/display/test/2009/08/23/demo+page

      After:

      url of page 'page: demo page - renamed v.2 (13598761)'=/display/test/demo+p
      age+-+renamed

        1. DemoAction.java
          3 kB
        2. DemoMacro.java
          2 kB

          Form Name

            [CONFSERVER-16694] After renaming a BlogPost, pageManager.getById() return a Page, not a BlogPost

            This issue can be caused by the PageTypes plugin by Scandio. de.scandio.confluence.plugins.pagetypes

            Foo Sim (Inactive) added a comment - This issue can be caused by the PageTypes plugin by Scandio. de.scandio.confluence.plugins.pagetypes

            Anatoli added a comment -

            Ben,

            in the version of the plugin that works in 3.0.1 do you still use pageManager.getById() or did you switch to PageManager.getBlogPost() or PageManager.getAbstractPage() methods?

            Anatoli added a comment - Ben, in the version of the plugin that works in 3.0.1 do you still use pageManager.getById() or did you switch to PageManager.getBlogPost() or PageManager.getAbstractPage() methods?

            Aha. Just realised that I seem to have misreported my version of
            confluence - should have been 3.0. And I have just upgraded to 3.0.1.
            And I can no longer reproduce the defect.

            Ben Aveling added a comment - Aha. Just realised that I seem to have misreported my version of confluence - should have been 3.0. And I have just upgraded to 3.0.1. And I can no longer reproduce the defect.

            Tried it. set JAVA_OPTS=%JAVA_OPTS% -Xms256m -Xmx1024m -XX:MaxPermSize=256m

            No difference.

            Ben Aveling added a comment - Tried it. set JAVA_OPTS=%JAVA_OPTS% -Xms256m -Xmx1024m -XX:MaxPermSize=256m No difference.

            Hi Anatoli. Sufficient code to reproduce the problem is attached. I'll try zhanghan's fix. If that doesn't work, I can create a plugin containing just the demo code, if necessary? Regards, Ben

            Ben Aveling added a comment - Hi Anatoli. Sufficient code to reproduce the problem is attached. I'll try zhanghan's fix. If that doesn't work, I can create a plugin containing just the demo code, if necessary? Regards, Ben

            zhanghan added a comment -

            fixed problem:
            enlarge jvm cache size like below:

            Applying Memory Settings

            Users of the EAR/WAR distribution set their memory in their application server. For Confluence Standalone, the heap space is set in the Confluence install directory.

            • Windows users edit TOMCAT_HOME/bin/setenv.bat
            • Other OS users edit TOMCAT_HOME/bin/setenv.sh

            If you are running Tomcat as a Windows service, you may need to run a regedt32 to increase memory as in the article on increasing JIRA memory. Although the article discusses JIRA, it should also be applicable to Confluence.

            The relevant parameter is

            JAVA_OPTS="-Xms256m -Xmx1024m"

            Where -Xms is the minimum and -Xmx is the maximum memory available to Apache Tomcat. In this sample the maximum memory has been set to 1024 megabytes, but you will have to figure out the best setting based on your particular environment.
            Note: In newer Tomcat distributions the file may not exist. Feel free to create it in the ./bin directory.

            zhanghan added a comment - fixed problem: enlarge jvm cache size like below: Applying Memory Settings Users of the EAR/WAR distribution set their memory in their application server. For Confluence Standalone, the heap space is set in the Confluence install directory. Windows users edit TOMCAT_HOME/bin/setenv.bat Other OS users edit TOMCAT_HOME/bin/setenv.sh If you are running Tomcat as a Windows service, you may need to run a regedt32 to increase memory as in the article on increasing JIRA memory. Although the article discusses JIRA, it should also be applicable to Confluence. The relevant parameter is JAVA_OPTS="-Xms256m -Xmx1024m" Where -Xms is the minimum and -Xmx is the maximum memory available to Apache Tomcat. In this sample the maximum memory has been set to 1024 megabytes, but you will have to figure out the best setting based on your particular environment. Note: In newer Tomcat distributions the file may not exist. Feel free to create it in the ./bin directory.

            zhanghan added a comment -

            Seems I also meet the same poblem :

            click the news Items then confluence throw :

            java.lang.RuntimeException: Error rendering template for decorator root
            at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:232)

            caused by: java.lang.RuntimeException: Error rendering template for decorator space
            at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:232)

            caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getDatePath' in class com.atlassian.confluence.pages.BlogPost$$EnhancerByCGLIB$$bad4e9e7 threw exception java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost @ /decorators/space.vmd[40,81]
            at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:205)

            caused by: java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost
            at com.atlassian.confluence.pages.BlogPost$$FastClassByCGLIB$$a5eaa355.invoke(<generated>)

            How can I resolve it ??

            zhanghan added a comment - Seems I also meet the same poblem : click the news Items then confluence throw : java.lang.RuntimeException: Error rendering template for decorator root at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:232) caused by: java.lang.RuntimeException: Error rendering template for decorator space at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:232) caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getDatePath' in class com.atlassian.confluence.pages.BlogPost$$EnhancerByCGLIB$$bad4e9e7 threw exception java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost @ /decorators/space.vmd [40,81] at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:205) caused by: java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost at com.atlassian.confluence.pages.BlogPost$$FastClassByCGLIB$$a5eaa355.invoke(<generated>) How can I resolve it ??

            Anatoli added a comment -

            Hi Ben,

            Renaming blogpost would probably load the blogpost object into hibernate cache as a page. Flushing caches should help in such case, but it contradicts the experience you describe. Is it possible for you to attach your plugin so that I could reproduce and debug problem locally?

            Anatoli.

            Anatoli added a comment - Hi Ben, Renaming blogpost would probably load the blogpost object into hibernate cache as a page. Flushing caches should help in such case, but it contradicts the experience you describe. Is it possible for you to attach your plugin so that I could reproduce and debug problem locally? Anatoli.

            Hi Anatoli,

            I think you are on the right track with your diagnosis of the problem,
            but a cure is elusive....

            After a page rename, calling an action gives the following:

            Using getAbstractPage returns a Page, which gives the wrong url

            Using getBlogPost throws an error.

            demo>pageManager.getBlogPost(pageId)...
            demo>failed:java.lang.ClassCastException:
            com.atlassian.confluence.pages.Page cannot be cast to
            com.atlassian.confluence.pages.BlogPost
            demo>pageManager.getAbstractPage(pageId)...
            demo>url of Page 'page: demo page - renamed again v.3
            (13598761)'=/display/test/demo+page+-+renamed+again
            demo>get page 13598761
            demo>pageManager:com.atlassian.confluence.pages.DefaultPageManager@1a6e4c3

            Flushing the cache then calling the action again without refreshing the
            page gives the same results as above.

            Flushing the cache, then refreshing the page (well, BlogPost), then
            calling the action again works - it now returns a BlogPost, as it used
            to before the the blogpost was renamed.

            demo>pageManager.getBlogPost(pageId)...
            demo>url of BlogPost 'blogpost: demo page - renamed again v.3
            (13598761)'=/display/test/2009/08/23/demo+page+-+renamed+again
            demo>pageManager.getAbstractPage(pageId)...
            demo>url of BlogPost 'blogpost: demo page - renamed again v.3
            (13598761)'=/display/test/2009/08/23/demo+page+-+renamed+again

            It seems that the renaming of the page causes something to get confused
            about what is/is not/should be in the cache?

            Regards, Ben

            Ben Aveling added a comment - Hi Anatoli, I think you are on the right track with your diagnosis of the problem, but a cure is elusive.... After a page rename, calling an action gives the following: Using getAbstractPage returns a Page, which gives the wrong url Using getBlogPost throws an error. demo>pageManager.getBlogPost(pageId)... demo>failed:java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost demo>pageManager.getAbstractPage(pageId)... demo>url of Page 'page: demo page - renamed again v.3 (13598761)'=/display/test/demo+page+-+renamed+again demo>get page 13598761 demo>pageManager:com.atlassian.confluence.pages.DefaultPageManager@1a6e4c3 Flushing the cache then calling the action again without refreshing the page gives the same results as above. Flushing the cache, then refreshing the page (well, BlogPost), then calling the action again works - it now returns a BlogPost, as it used to before the the blogpost was renamed. demo>pageManager.getBlogPost(pageId)... demo>url of BlogPost 'blogpost: demo page - renamed again v.3 (13598761)'=/display/test/2009/08/23/demo+page+-+renamed+again demo>pageManager.getAbstractPage(pageId)... demo>url of BlogPost 'blogpost: demo page - renamed again v.3 (13598761)'=/display/test/2009/08/23/demo+page+-+renamed+again It seems that the renaming of the page causes something to get confused about what is/is not/should be in the cache? Regards, Ben

            Anatoli added a comment -

            Hi Ben,

            I suspect the problem is within hibernate caching. When pageManager.getById() is called and hibernate does not have this object in a session or in its second level cache then it tries to load it from the db. PageManager is configured(wired) in a way that getById eventually delegates to getByClassId method of an object of type HibernatePageDao. This methods loads a Page object into hibernate's session and the second level cache. All subsequent calls to getById methods would get the Page object from the session/cache.

            It explains why sometimes it works - when BlogPost is in the session or the second level cache and does not need to be retrieved from db.

            Please use PageManager.getBlogPost() or PageManager.getAbstractPage methods to fix the problem.

            Anatoli.

            Anatoli added a comment - Hi Ben, I suspect the problem is within hibernate caching. When pageManager.getById() is called and hibernate does not have this object in a session or in its second level cache then it tries to load it from the db. PageManager is configured(wired) in a way that getById eventually delegates to getByClassId method of an object of type HibernatePageDao . This methods loads a Page object into hibernate's session and the second level cache. All subsequent calls to getById methods would get the Page object from the session/cache. It explains why sometimes it works - when BlogPost is in the session or the second level cache and does not need to be retrieved from db. Please use PageManager.getBlogPost() or PageManager.getAbstractPage methods to fix the problem. Anatoli.

            Deleting and undeleting a bad page makes no difference, it is still bad.

            I currently have the offending pages deleted, but have not yet purged the trash. I figure you may want more information about these bad pages, and I don't know how to reproduce that type of corruption.

            The blogposts macro is failing, even though all bad pages are in the trash (yes, I have checked the whole of the space - everything remaining is happy to render reliably). Does blogposts check pages that are in the trash?

            Ben Aveling added a comment - Deleting and undeleting a bad page makes no difference, it is still bad. I currently have the offending pages deleted, but have not yet purged the trash. I figure you may want more information about these bad pages, and I don't know how to reproduce that type of corruption. The blogposts macro is failing, even though all bad pages are in the trash (yes, I have checked the whole of the space - everything remaining is happy to render reliably). Does blogposts check pages that are in the trash?

            I don't know if this is one problem or two. Sadly, the 'almost-always-bad' pages are on the production box, which is hosted, so I have less access to it.

            I've done some experiments on the rename problem, which is on my development box.

            There are no interesting differences in the Content table, before and after a renaming.

            A page that has gone bad because of renaming cannot be rendered good by renaming it back to the original name.

            A page that has gone bad because of renaming cannot be rendered good by waiting a while before retrying.

            A page that has gone bad because of renaming can be rendered good by rebooting confluence.

            This feels like a caching issue, as if there is a cache of pages which is used for Actions, but is not used for displaying pages normally. Certainly, there is some difference - when visiting http://localhost:8080/plugins/demo/demo_action.action?pageId=14450695 it thinks it is dealing with a Page whereas when visiting http://localhost:8080/display/test/2009/09/05/Demomacro it knows it is dealing with a BlogPost - and in fact, both are the same BlogPost.

            Renaming the BlogPost changes the hashcode it returns. Restoring the original name restores the original hashcode.

            Caching the objects in a static hashmap and testing using containsKey shows that before renaming the same object (a blogpost) is passed when rendering the blogpost as when executing the action. After renaming the page, a different object (also a blogpost) is passed when rendering the blogpost, and a 3rd object (a page) is passed when executing the action. As above, the 2nd and 3rd objects have the same hashcode despite being different objects, indeed, different types. (Interestingly, hashCode() is implemented on SpaceContentEntityObject, while equals() is implemented on ContentEntityObject()).

            Ben Aveling added a comment - I don't know if this is one problem or two. Sadly, the 'almost-always-bad' pages are on the production box, which is hosted, so I have less access to it. I've done some experiments on the rename problem, which is on my development box. There are no interesting differences in the Content table, before and after a renaming. A page that has gone bad because of renaming cannot be rendered good by renaming it back to the original name. A page that has gone bad because of renaming cannot be rendered good by waiting a while before retrying. A page that has gone bad because of renaming can be rendered good by rebooting confluence. This feels like a caching issue, as if there is a cache of pages which is used for Actions, but is not used for displaying pages normally. Certainly, there is some difference - when visiting http://localhost:8080/plugins/demo/demo_action.action?pageId=14450695 it thinks it is dealing with a Page whereas when visiting http://localhost:8080/display/test/2009/09/05/Demomacro it knows it is dealing with a BlogPost - and in fact, both are the same BlogPost. Renaming the BlogPost changes the hashcode it returns. Restoring the original name restores the original hashcode. Caching the objects in a static hashmap and testing using containsKey shows that before renaming the same object (a blogpost) is passed when rendering the blogpost as when executing the action. After renaming the page, a different object (also a blogpost) is passed when rendering the blogpost, and a 3rd object (a page) is passed when executing the action. As above, the 2nd and 3rd objects have the same hashcode despite being different objects, indeed, different types. (Interestingly, hashCode() is implemented on SpaceContentEntityObject, while equals() is implemented on ContentEntityObject()).

            There are two such bad pages at the moment. If either is displayed, neither it nor the other one can displayed successfully for a short period of time.

            Ben Aveling added a comment - There are two such bad pages at the moment. If either is displayed, neither it nor the other one can displayed successfully for a short period of time.

            PS. It feels as if this page renders successfully more often if there is a delay before trying to render it, and less often if it is rendered twice quickly, and never if it is rendered immediately after a failure.

            Can't say how long a delay is necessary to make a difference, perhaps a minute or a small number of minutes?

            Is there some caching happening perhaps?

            Ben Aveling added a comment - PS. It feels as if this page renders successfully more often if there is a delay before trying to render it, and less often if it is rendered twice quickly, and never if it is rendered immediately after a failure. Can't say how long a delay is necessary to make a difference, perhaps a minute or a small number of minutes? Is there some caching happening perhaps?

            The following has been 'added to the mail queue', but mail is not yet set up. Rather than wait, I'll add it manually, an apologise in advance if it appears again.
            -----------------------------

            Instead of displaying a blogpost, Confluence displays an error:

            Cause

            java.lang.RuntimeException: Error rendering template for decorator root
            at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210)

            caused by: java.lang.RuntimeException: Error rendering template for decorator blogpost
            at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210)

            caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getDatePath' in class com.atlassian.confluence.pages.BlogPost$$EnhancerByCGLIB$$3409df68 threw exception java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost at template/includes/macros.vm[line 797, column 81]
            at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:223)

            caused by: java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost
            at com.atlassian.confluence.pages.BlogPost$$FastClassByCGLIB$$a5eaa355.invoke(<generated>)
            Stack Trace:[hide]

            java.lang.RuntimeException: Error rendering template for decorator root
            at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210)
            at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:175)
            at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336)
            at org.apache.velocity.Template.merge(Template.java:328)
            at org.apache.velocity.Template.merge(Template.java:235)

            This may be another manifestation of CONF-16694

            The behaviour is similar, but worse.

            Previously, this only happened under slightly unusual circumstances. (Rename a blog post, then select an action on it that needs to call pageManager.getById().)

            This now seems to happen nearly every time one certain page is rendered, including displaying all the blog posts for that day or month!

            Calling .../pages/editblogpost.action?pageId=426061 always seems to succeed.

            If I edit and save, it sometimes works, but not always, and not usually twice in a row.

            The page has been there for about 4 or 5 days without causing any drama until today.

            Ben Aveling added a comment - The following has been 'added to the mail queue', but mail is not yet set up. Rather than wait, I'll add it manually, an apologise in advance if it appears again. ----------------------------- Instead of displaying a blogpost, Confluence displays an error: Cause java.lang.RuntimeException: Error rendering template for decorator root at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210) caused by: java.lang.RuntimeException: Error rendering template for decorator blogpost at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210) caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getDatePath' in class com.atlassian.confluence.pages.BlogPost$$EnhancerByCGLIB$$3409df68 threw exception java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost at template/includes/macros.vm [line 797, column 81] at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:223) caused by: java.lang.ClassCastException: com.atlassian.confluence.pages.Page cannot be cast to com.atlassian.confluence.pages.BlogPost at com.atlassian.confluence.pages.BlogPost$$FastClassByCGLIB$$a5eaa355.invoke(<generated>) Stack Trace: [hide] java.lang.RuntimeException: Error rendering template for decorator root at com.atlassian.confluence.setup.velocity.ApplyDecoratorDirective.render(ApplyDecoratorDirective.java:210) at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:175) at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336) at org.apache.velocity.Template.merge(Template.java:328) at org.apache.velocity.Template.merge(Template.java:235) This may be another manifestation of CONF-16694 The behaviour is similar, but worse. Previously, this only happened under slightly unusual circumstances. (Rename a blog post, then select an action on it that needs to call pageManager.getById().) This now seems to happen nearly every time one certain page is rendered, including displaying all the blog posts for that day or month! Calling .../pages/editblogpost.action?pageId=426061 always seems to succeed. If I edit and save, it sometimes works, but not always, and not usually twice in a row. The page has been there for about 4 or 5 days without causing any drama until today.

            confdb3=# select contenttype from content where contentid=13598761;
            contenttype
            -------------
            BLOGPOST
            (1 row)

            I don't think it's changed type. After all, it generally behaves correctly. I suspect that inside a macro something is done wrongly.

            confdb3=# select *
            confdb3-# from content where contentid=13598761;
            contentid | contenttype | title | version | creator | creati
            ondate | lastmodifier | lastmoddate | versioncomment | prevver

            content_status spaceid child_position parentid messageid draftpagei
            d
            draftspacekey drafttype draftpageversion pageid parentcommentid us
            ername
            ------------------------------------------------------+-----------
            --------------------------------------------------------------------
            --------------------------------------------------------------
            --------------------------------------------------------------
            -------
            13598761
            BLOGPOST demo page - renamed 2 admin 2009-08-23
            13:00:38.571
            admin 2009-08-23 13:01:01.078  
            current 7667715      
                     

            (1 row)

            Ben Aveling added a comment - confdb3=# select contenttype from content where contentid=13598761; contenttype ------------- BLOGPOST (1 row) I don't think it's changed type. After all, it generally behaves correctly. I suspect that inside a macro something is done wrongly. confdb3=# select * confdb3-# from content where contentid=13598761; contentid | contenttype | title | version | creator | creati ondate | lastmodifier | lastmoddate | versioncomment | prevver content_status spaceid child_position parentid messageid draftpagei d draftspacekey drafttype draftpageversion pageid parentcommentid us ername ---------- ----------- ------------------- ------- ------- + ----------- ------------ ------------ ----------------------- -------------- ------- -------------- ------- -------------- -------- --------- ---------- - ------------- --------- ---------------- ------ --------------- -- ------- 13598761 BLOGPOST demo page - renamed 2 admin 2009-08-23 13:00:38.571 admin 2009-08-23 13:01:01.078   current 7667715                 (1 row)

            Anatoli added a comment -

            Hi Ben,

            BlogPost should not change its type to Page when renamed. Can you please check database and verify that row in a CONTENT table with id 13598761 has CONTENTTYPE of BLOGPOST

            Anatoli.

            Anatoli added a comment - Hi Ben, BlogPost should not change its type to Page when renamed. Can you please check database and verify that row in a CONTENT table with id 13598761 has CONTENTTYPE of BLOGPOST Anatoli.

              Unassigned Unassigned
              5a9ab946d8b5 Ben Aveling
              Affected customers:
              0 This affects my team
              Watchers:
              7 Start watching this issue

                Created:
                Updated:
                Resolved: