The user macro show-ancestor-with-label (copy below) generates exceptions (eg, null pointer, array bounds, hibernate) but only on a small number of invocations. It is intended to include a link to the first ancestor it finds with the given label.
Strangely rendering a page that calls the macro ~260 times is successful in approx. 2/3 tries, but on the failed case generates one of the exceptions.
Any suggestions on what may be driving the exceptions (some but not all of the time)?
## @Param Label:title=Label|type=string|required=true|desc=Pages that contain this label should be displayed
##set ( $ancestor = "" )
#foreach ( $ancestor in $content.getAncestors() )
#foreach ( $label in $ancestor.getLabels() )
#if ($label == $paramLabel)
#contentLink2($ancestor, false, false)
#break($foreach.parent)
#end
#end
#end
Thanks Bill Bailey, Changing from
# foreach ( $ancestor in $content.getAncestors() ) ** causes the semi-random exceptions **
to
#set( $currentPage = $pageManager.getPage($content.id) )
#foreach ( $ancestor in $currentPage.getAncestors() )
Has cleared up the exceptions !
Not sure exactly why, can only presume that the value of $content is somehow thread unsafe.
Thanks again for the tip Bill.
You're welcome. A guess made because I am not sure what the scope of $content always is. So I try to be as restrictive as possible in my references.
And I learned a new macro: #contentLink2, so thanks for that!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Stephen,
Is this a User Macro you wrote or did you acquire it from somewhere?
What are the actual error messages from your Confluence server logs?
Shannon
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Macro is a combination of grabs from other user's macros posted online (ie, picked up the labels and ancestors portions separately), and mixed them locally into a composite.
Exceptions include:
I'm beginning to wonder if there is a thread safety issue - not sure why a macro that is only reading should suffer though?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
An example exception, which flags the 'getLabels()' call is:
– url: /confluence/pages/viewpage.action | page: 13868615 | traceId: 7f2326fc8022b66b | userName: noneill | referer: https://atlas/confluence/login.action?os_
destination=%2Fpages%2Fviewpage.action%3FspaceKey%3DL200%26title%3D03%2BMonitor&permissionViolation=true | action: viewpage
com.atlassian.core.exception.InfrastructureException: Error occurred rendering template content
...
Caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getLabels' in class com.atlassian.confluence.pages.Page threw exception java.lang.NullPointerException at getRenderedContent[line 17, column 34]
...
Caused by: java.lang.NullPointerException
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
What happens with a page with no labels? Are you trapping that event?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Bill, no seems to work just fine on a page with no labels (see image above).
The odd thing is that it is being called ~1000 times one each load of the page in question, and the exceptions occur roughly 1 in 6 page loads. That's what gets me thinking it may be an asynchronous race condition style cause?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
What exactly are you trying to do with this macro, and where is the rest of the macro? I assume line 17 is
#foreach ( $label in $ancestor.getLabels() )
Could also be the error is actually in the line previous.
When I was writing a custom child page by label macro, I used the following to get the collection of children of page
#set( $children = $currentPage.getSortedChildren() )
which did not result in tons of calls. Your call does, depending on where it is.
$content.getAncestors()
Which by definition is very recursive
Gets the list of ancestors of this page (its parents, and its parents parents, right up to the root level of the containing space).
If you are trying to look at parents of a current page, I probably would have used the below instead:
$currentPage.getAncestors()
To be more restricted in my reference.
What I wrote was inspired by this macro:
https://github.com/unidwell/confluence-include-child-pages-macro
It could also give you some hints.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Bill,
The macro is trying to find the first parent page of the page it is on with the specified label, and display that page as a hyperlink. The reason is I have a hierarchy of pages that are organised into categories, and at the leafs of the structure I want to display the root page for that item.
The whole macro is right at the top of this thread. I wasn't sure I understood the $content vs $currentPage distinction you we makeing, so modified the macro (see updated macro below), and for an example instance get the following output. Seems to say they are the same thing - do you concur?
content page: ENAP Provisioning from SW-2072 USB v.4 (28639832) currentPage page: ENAP Provisioning from SW-2072 USB v.4 (28639832) ancestorsContent [page: Office of the Product Owner v.18 (8028373), page: MSS R2 Product Backlog (PBL) v.72 (8028219), page: 54 MSM Console v.37 (8028229)] ancestorsCurrentPage [page: Office of the Product Owner v.18 (8028373), page: MSS R2 Product Backlog (PBL) v.72 (8028219), page: 54 MSM Console v.37 (8028229)] 54 MSM Console
Updated macro:
## Macro title: My Macro
## Macro has a body: N
## Body processing: Selected body processing option
## Output: Selected output option
##
## Developed by: Stephen Baxendale
## Date created: 17 Aug 2018
## Installed by: Stephen Baxendale
## @Param Label:title=Label|type=string|required=true|desc=Pages that contain this label should be displayed
content $content
#set( $currentPage = $pageManager.getPage($content.id) )
currentPage $currentPage
ancestorsContent $content.getAncestors()
ancestorsCurrentPage $currentPage.getAncestors()
##set ( $ancestor = "" )
##foreach ( $ancestor in $content.getAncestors() )
#foreach ( $ancestor in $currentPage.getAncestors() )
##anc $ancestor
##set ( $label = "a-very-unusual-and-unlikely-to-match-value" )
#foreach ( $label in $ancestor.getLabels() )
##label $label
#if ($label == $paramLabel)
#contentLink2($ancestor, false, false)
#break($foreach.parent)
#end
#end
#end
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.