Raw XML Module Breaking Change for Confluence 9
Information about errors, symptoms, and solutions related to using a Raw XML module to generate fragments in Confluence 9.
The raw XML format for condition class and provider class has changed with Confluence 9.0.0. The formats previously generated from the Preview button for each of these built-in fragment scripts are no longer valid:
If you previously created a fragment using the raw XML generated from the Preview button, you will have to manually update it to the new format for your fragment to function correctly. On this page, find the following information about this breaking change:
Fragment XML conditions and web panel class scripts are now provided via XML parameters and are no longer directly set as the condition class element attribute or web panel class element attribute value. You can use this guide to help you convert your scripts to the new fragment XML parameters format.
Examples of the old Raw XML format
Below are examples of raw XML scripts that will no longer work and will need updating.
Web Items
Inline script:
<web-item key='test-key' name='ScriptRunner generated web item - test-key' section='system.header/spaces-menu' weight='1'>
<label>Test</label>
<condition class='myConditions/fooCondition.groovy'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebItem"}' />
<param name='£fragmentParameters' value='{"id":"9a4f29fb-4c4d-42b6-a602-b327606ba772"}' />
</condition>
<styleClass> test-key </styleClass>
<link linkId='test-key'>https://www.google.com?_=1</link>
</web-item>Script file:
<web-item key='test-key' name='ScriptRunner generated web item - test-key' section='system.header/spaces-menu' weight='1'>
<label>Test</label>
<condition class='myConditions/fooCondition.groovy'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebItem"}' />
<param name='£fragmentParameters' value='{"id":"9a4f29fb-4c4d-42b6-a602-b327606ba772"}' />
</condition>
<styleClass> test-key </styleClass>
<link linkId='test-key'>https://www.google.com?_=1</link>
</web-item>Web Panels
Inline script:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='myPanels/myPanelScript.groovy'>
<label>Test Panel</label>
<condition class='myConditions/fooCondition.groovy'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' />
<param name='£fragmentParameters' value='{"id":"eb7436cc-6ca9-4519-8c9b-cb94f68eb562"}' />
</condition>
<param name='lazy' value='true' />
</web-panel>Script file:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='myPanels/myPanelScript.groovy'>
<label>Test Panel</label>
<condition class='myConditions/fooCondition.groovy'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' />
<param name='£fragmentParameters' value='{"id":"eb7436cc-6ca9-4519-8c9b-cb94f68eb562"}' />
</condition>
<param name='lazy' value='true' />
</web-panel>Find the broken raw XML fragments
After you upgrade ScriptRunner for Confluence and you still have the outdated raw XML fragments, ScriptRunner for Confluence shows errors in the logs when ScriptRunner is enabled. Each error starts with this message:
Execution of Fragment script failed with errorThen the error message describes why it failed and gives a link to where you can edit the failing fragment.
Edit the broken fragment here: <URL Link to edit the broken fragment>The broken raw XML fragments will still show as active in the ScriptRunner UI fragments page, but they will not be functional.
Fix the broken raw XML fragments
Use the log output to find which raw XML fragments need to be fixed. Every time you edit or create a fragment, all fragments are re-registered, so you will see the log error messages every time you make changes until all invalid fragments have been fixed.
We suggest these steps to fix broken raw XML fragments:
Before you start updating XML, we suggest backing up the previous raw XML so that you can refer back to it if you are unable to get the new format working in the same way. This will help ScriptRunner Support if you need help creating the new raw XML format.
See below for detailed examples for each type of UI fragment.
Example: Fix a broken raw XML fragment in a web item
Let's say that you have the following web item script in your instances with the broken raw XML format:
<web-item key='test-key' name='ScriptRunner generated web item - test-key' section='system.header/spaces-menu' weight='1'>
<label>Test</label>
<condition class='script:def test = 1 true'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebItem"}' />
<param name='£fragmentParameters' value='{"id":"9a4f29fb-4c4d-42b6-a602-b327606ba772"}' />
</condition>
<styleClass> test-key </styleClass>
<link linkId='test-key'>https://www.google.com?_=1</link>
</web-item>Follow these steps to fix it:
Example: Fix a broken raw XML fragment in a web section
The process for migrating web sections is the same as for web items. Follow these steps:
Example: Fix a broken raw XML fragment in a web panel
Let's say that you have the following web panel script in your instances with the broken raw XML format:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='script:writer.write("This is HTML that my web panel generates!")'>
<label>Test Panel</label>
<condition class='script:true'>
<param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' />
<param name='£fragmentParameters' value='{"id":"eb7436cc-6ca9-4519-8c9b-cb94f68eb562"}' />
</condition>
<param name='lazy' value='true' />
</web-panel>The process for migrating a web panel's raw XML is the same as for web items when migrating the conditions element, but also requires one extra step to migrate the web panel provider class.
Follow these additional steps to migrate the provider class script:
Step 1: Fill out a form and get the new XML
- Navigate to General Configuration > ScriptRunner > UI Fragments > Create UI Fragment > Show a web panel.
- Fill out the fields that appear, as you did for the web item (Web Panels use
locationin place of the web items'section).Warning: The Provider Class/ScriptPlease review the following information closely. It differs from the web item process
- When filling out the Show a web panel form for the Provider Class/Script field, use the following template script to get the new XML. We will replace this later.
writer.write("Hello world!") - The web panel provider class script migration is similar to conditions, but your script needs to be placed within the parameters of our new
context-providerblock.
- When filling out the Show a web panel form for the Provider Class/Script field, use the following template script to get the new XML. We will replace this later.
- Click the Preview button to generate the new XML. It will look similar to this:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='com.onresolve.scriptrunner.fragments.ScriptWebPanel'> <label>Test Panel</label> <condition class='com.onresolve.scriptrunner.fragments.ConfluenceScriptRunnerCondition'> <param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' /> <param name='£fragmentParameters' value='{"id":"4bf6f413-f2d0-449b-b07a-4ebdff15d849"}' /> <param name='conditionConfig'><![CDATA[{"parameters":{},"script":"true","scriptPath":null}]]></param> </condition> <context-provider class='com.onresolve.scriptrunner.fragments.ScriptRunnerContextProvider'> <param name='panelClassConfig'><![CDATA[{"parameters":{},"script":"writer.write(\"Hello world!\") ","scriptPath":null}]]></param> </context-provider> <param name='lazy' value='true' /> </web-panel>
Step 2: Add the missing elements
Please follow the steps shown in Add the missing extra elements in the web item steps above.
Step 3: Add your condition script back to the XML
Please follow the steps shown in Add your condition script back to the XML in the web item steps above.
Step 4: Fix the provider class script
- Find the
panelClassConfigline in the new XML and look for the parameters section that looks like this:{"parameters":{},"script":"writer.write(\"Hello world!\")","scriptPath":null} - Determine which kind of script your provider class script is and follow the steps:
Inline scripts:
- Take the old XML inline script value for the web-panel class attribute, for example:
'script:writer.write("This is HTML that my web panel generates!")'and use this converter script to alter it to the new format.Converter script...
- Open the ScriptRunner Console.
Paste the following script into the console script area.
import groovy.json.JsonOutput import org.apache.commons.lang.StringEscapeUtils def scriptStringToConvert = 'script:def test = "hello" context.space != null && context.user.name == 'admin'' def xmlToJsonEscapedString(String xmlString) { if(xmlString.startsWith('script:')) { xmlString = xmlString.replaceFirst('script:', '') } def unescapedXmlString = StringEscapeUtils.unescapeXml(xmlString) JsonOutput.toJson(unescapedXmlString) } "<pre>" + xmlToJsonEscapedString(scriptStringToConvert) + "</pre>"- Set the value of the
scriptStringToConvertvariable to the exact value from your XML. - Click Run.
- Copy the output from the Result tab exactly, including the outer double quotes.
- Use that as the value for the "
script": property within theconditionConfig or thepanelClassConfig XML parameter element.
- Find the
<param name='panelClassConfig'element in the new XML. - Find the
{"parameters":{},"script":"writer.write(\"Hello world!\") ","scriptPath":null}value in the new XML. - Find the
"script":"writer.write(\"Hello world!\") "part of your new XML and replace the "writer.write(\"Hello world!\") " partwith the exact value that was output from the converter script it Step 1.
The new converted XML moves the script to a new context-provider section. The final converted XML would look like this:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='com.onresolve.scriptrunner.fragments.ScriptWebPanel'> <label>Test Panel</label> <condition class='com.onresolve.scriptrunner.fragments.ConfluenceScriptRunnerCondition'> <param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' /> <param name='£fragmentParameters' value='{"id":"4bf6f413-f2d0-449b-b07a-4ebdff15d849"}' /> <param name='conditionConfig'><![CDATA[{"parameters":{},"script":"true","scriptPath":null}]]></param> </condition> <context-provider class='com.onresolve.scriptrunner.fragments.ScriptRunnerContextProvider'> <param name='panelClassConfig'><![CDATA[{"parameters":{},"script":"writer.write(\"This is HTML that my web panel generates!\")","scriptPath":null}]]></param> </context-provider> <param name='lazy' value='true' /> </web-panel>Script files:
- If your broken XML used a file path to a script instead of an inline script, you will add your script path as the value for the
"scriptPath"section. The old XML web panel class attribute would have looked similar to this:<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='path/to/my/groovy/file.groovy'>The new converted XML moves the scriptPath to a new context-provider section, and therefore, the converted XML would look like this:
<web-panel key='test-one' name='ScriptRunner generated web panel - test-one' location='atl.confluence.header' weight='1' class='com.onresolve.scriptrunner.fragments.ScriptWebPanel'> <label>Test Panel</label> <condition class='com.onresolve.scriptrunner.fragments.ConfluenceScriptRunnerCondition'> <param name='£trackingParameters' value='{"scriptName":"com.onresolve.scriptrunner.canned.confluence.fragments.CustomWebPanel"}' /> <param name='£fragmentParameters' value='{"id":"4bf6f413-f2d0-449b-b07a-4ebdff15d849"}' /> <param name='conditionConfig'><![CDATA[{"parameters":{},"script":"true","scriptPath":null}]]></param> </condition> <context-provider class='com.onresolve.scriptrunner.fragments.ScriptRunnerContextProvider'> <param name='panelClassConfig'><![CDATA[{"parameters":{},"script":null,"scriptPath":"path/to/my/groovy/file.groovy"}]]></param> </context-provider> <param name='lazy' value='true' /> </web-panel>
- Take the old XML inline script value for the web-panel class attribute, for example: