Deploying a flavor with custom XWikiPreferences

Hi everyone,

I have a project with a custom flavor which depends on the default subwiki flavor and on an extension which includes a customized XWikiPreferences. When creating a wiki with this flavor, the wiki creation job raises an error Collision found on object [wiki » XWiki » XWikiPreferences]. I’m wondering what’s the recommended way to deal with this scenario in XWiki 14.x.

I have considered several options:

  • Declare XWikiPreferences XAR type as customizable or as edit-nodelete-overwrite using the Extra XAR entry types extension: still getting the conflict error (and even if edit-nodelete-overwrite would work on first install, this is not the type we want for upgrades since the page can be customized).
  • Extension conflict setup: I enabled the extension conflict setup in my profile but the wiki creation job does not take this option into account → should we consider exposing the conflict resolution prompt on wiki creation just like when installing an extension from the extension manager? Note that even if we do this, in my scenario I would like to avoid any manual conflict resolution and to force the installation of the customized XWikiPreferences (or possibly other pages overriding the defaults with possible conflicts as well).
  • Two steps wiki provisioning: I considered deploying the wiki with an empty flavor and install the custom one in a second step via the Distribution Wizard, hence getting the conflict resolution prompts. This approach works, with the downside that it requires many more clicks and can be error prone (an admin may select initially the target flavor instead of leaving the wiki empty). In this scenario, despite configuring the conflict setup to “Ask what to do” in all cases, the customized XWikiPreferences is installed correctly without any conflict resolution question, I’m wondering why (while the wizard prompts a choice for XWiki.Notifications.Code.NotificationAdministration).
  • Create a custom XWikiDocumentMerger for XWikiPreferences as indicated here.
  • Create a listener on event WikiProvisionedEvent which would update programmatically the subwiki XWikiPreferences once deployed.

Any feedback or recommendation welcome,

Thanks

Stéphane

I guess before looking at possible solutions, my first question would be: what conflict do you get ?

I think you have the wrong assumption that having a custom XWikiPreferences page in your flavor will create a conflict, but there is such custom XWikiPreferences in the XWiki Standard flavor, and you don’t get a conflict for it.

You have to understand where the conflict for this page is coming from. In the case of a document associated with a mandatory initializer, we do a 3 ways merge between the following versions:

  • previous: an empty document is used as common ancestor
  • current: as usual, what’s current in the database (so in this case, the result of the execution of the mandatory initializer)
  • next: what’s in the XAR

Getting a conflict for XWikiPreferences generally suggests that the class part of your custom XWikiPreferences is not in sync with what’s in the standard one, so the current version and the next version have conflicting changes compared to the common ancestor.

1 Like

Thank you @tmortagne. In order to know which exact conflicts I’m getting, I’ve added a breakpoint at the line of the MergerManager where they are raised.

I’m getting 3 conflicts: two about XWikiGlobalRights objects, one about the XWikiPreferences object. For all of them, I have copied from the debugger the String representation (XML) of the variables objectResult and newObject to two distinct files (variable previousObject is null in all cases). When comparing the obtained XML in each case, the classes are identical, only the object values differ, reflecting indeed the actual changes brought by the new object, eg a differerence on <property><skin>...</skin></property> in the case of the new/next XWikiPreferences object.

I noticed that the previousDoc variable in method mergeXObjects where the breakpoint is located contains one XObject of class XWiki.ClassSheetBinding, and this object only. I’m wondering why this is the case: shouldn’t the previousDoc in this scenario be the one of the XWiki Standard subwiki flavor? My understanding is that XWiki first initializes XWikiPreferences with the mandatory initializer, then installs the custom one coming from the XWiki Standard subwiki flavor, then attempts to install the one from my custom flavor, which depends on the Standard one, does it not?

Actually, I read this one too quickly, so your problem is not so much the document initializer but the fact that you have conflicting XWikiPreferences in your own dependency tree. As I indicated in my first message, the standard flavor (on which you depend) have a custom XWikiPreferences page, but there is no link between the standard flavor and your application which also contains a custom XWikiPreferences page. It’s really not a great idea to have a custom XWikiPreferences in an extension, you would have less problem if you were putting it in your flavor (since your flavor depends on the standard flavor it officially overrides the pages from the standard flavor).

Right, I understand a link is needed. I tried moving the custom XWikiPreferences to the flavor indeed (src/main/resources/XWiki/XWikiPreferences), but I’m still getting the same error (made sure to redeploy the new flavor XAR with the custom XWikiPreferences and the new XAR of the extension it depends on without any XWikiPreferences).

… probably because it should be located in xwiki-platform-distribution-ui… Trying that.

I could not get a working setup so I created [XWIKI-20059] Creating a subwiki with a flavor depending on the standard subwiki flavor with custom XWikiPreferences raises conflict error - XWiki.org JIRA to follow up. Could be a misconfiguration on my side but can’t spot it.