In a recent project I decided to use Single Copy XPage Design (SCXD). This is a seemingly useful technique that is in many ways similar to the concepts underpinning XPages on Bluemix: one database holds the data and it points to another database that contains the XPages-specific design elements – XPages, Custom Controls, StyleSheets, Themes, Images, custom Java code and third-party jars. (At this point, it’s worth stating that although the concept of two NSFs is similar, my understanding from the demos I’ve seen is that Bluemix is sufficiently different in its runtime to make me hopeful that the critical issue I’ve encountered will not be relevant on Bluemix.) So if you have lots of XPages applications, all sharing the same design, it makes sense to use SCXD to minimise memory and, so it would seem, ease deployment of changes to the XPages elements.

The explanation of SCXD in Mastering XPages Second Edition is focused on its benefits for XPages in the Notes Client and, as one would expect from a book on the topic, concentrates on the “how” rather than going into depth on the real world experiences of development and implementation. That’s not a criticism of Mastering XPages, it’s a statement of what to expect from any book that introduces technical advancements, and the same was true of what I wrote for XPages Extension Library book. When writing a book, you are getting to grips with the basics and don’t have the time to go through a whole project using it in a customer environment. Similarly, no blogger has blogged on real-life implementations of every single piece of technology in XPages Extension Library or Mastering XPages, nor would anyone reasonably expect them to. We blog about our experiences and learning, both so others can learn from our knowledge and so we can easily find it when, a year from now, we hit the same problem!

So here is my detailed experiences of a few obvious gotchas and a big problem I’m yet to find a solution for.

Firstly, in this blog post I will talk about:

  • the master database, which is an NSF where the XPages-related design elements reside.
  • the slave template, which is an NTF from which each slave database picks up its design.
  • the slave databases, which are NSFs containing the data and any design elements required for data design and scheduled processing, e.g. Forms, Views, LotusScript Script Libraries, Agents etc.

A slave template is required. Trying to set or change the XPage Design Store Path in the Application Properties of a slave database doesn’t work – in my experience it will still look to its own design. Also, you can’t point a database to itself, so you can’t have a single template for master and slave. You have to split your design. If you try to point it to itself, the XPages runtime gets in an infinite loop, understandably. (I at least wanted to try this, because I was moving from a single database design to SCXD, and having several pointing to one instance would have minimised the changes I needed to make.)

The first thing to note when starting your development of the slave template is that it must have an XPage with the same name as the one in the launch properties. It doesn’t have to have the same design, and indeed I would strongly recommend having a different design, so it’s obvious if the SCXD settings are incorrect.

Initialising SCXD

If SCXD has never been used before, this is fairly straightforward.

  1. No changes are required to the Master Database.
  2. Open Application Properties in Designer on Slave Template.
  3. Go to XPages tab.
  4. Tick Single Copy XPage design and set XPage design store path. The format for the Master Database location in a folder is folder\filename.nsf.
  5. Refresh the design of the Slave Databases.
  6. If SCXD has not been in place before, there is no need to restart task http.

Things get trickier if you need to change the Master Database location or want to remove SCXD completely.

  1. Open Application Properties in Designer on Slave Template.
  2. Go to XPages tab.
  3. Untick Single Copy XPage design (to remove) or tick Single Copy XPage design and set XPage design store path (to change).
  4. Refresh the design of Slave Databases.
  5. Issue restart task http command to console.

One reason you may need to change the Master Database location is if you have a different location on development / test / production servers. If no database could be found at the XPage design store path location, the design of the Slave Database will be used instead. This is a good reason for giving an informative message on the Home page.

The reason for needing to restart HTTP is that once any Slave Database is in use, the Master Template design is cached in the XPages Runtime for use. Some functionality, like changing the SCXD location, doesn’t force a reload.

In terms of development, changes to XPages, Custom Controls, CSS etc get picked up immediately. New Java methods or classes also get picked up immediately. However, changes to existing Java methods seem to be cached and are only picked up after an HTTP restart or after the Master Database is removed from memory, because all instances have timed out. As I mentioned on StackOverflow, I’ve been unable to find any way to reload the Master Database into memory. No actions taken upon it remove it from memory. Thanks to Eric McCormick, I also tried ticking Refresh entire application when design changes (xsp.application.forcefullrefresh=true), but that has no effect either. Issuing the console command tell http xsp help gives a whole host of useful XPages-related console commands, but none for reloading an application. There are commands for reloading OSGi bundles, but not NSF classes.

I haven’t yet worked out exactly how SCXD designs are cached differently from normal XPages applications. I have deduced that they must be, because cleaning the Master database has no effect for SCXD, whereas it works fine for a normal XPages application.

Similarly, if your applications use only SSJS, SCXD is a very useful approach.

But the problem becomes significant for deploying to a production environment when a View and XPage need to be amended, but also the Java controller class for that XPage: the view and XPage designs are used immediately after a refresh, but the application then throws unexpected errors because the backend Java method cannot be found, because the cached version of the Java class is used until an HTTP restart. Obviously on a production server, where that has to be scheduled, it causes problems for deployment.

Currently, my approach has been to move everything back into a single template. It means more effort during deployments, refreshing the design of more databases. Longer term, I may use SCXD again, but move the Java classes into a plugin, since that can be reloaded independently of the rest of the runtime. It means an extra element in deployment, but changes to XPages only will require deployment to two places instead of fifty.

4 thoughts on “Single Copy XPage Design – Some Learning and Why It's Not For Me”

  1. Good points Paul. I’ve been hoping for the best for SCXD, but haven’t taken the plunge and may be glad of it. Most of my development style over the last 3 years has shifted away from SSJS as much as possible to as much Java as possible, making this sort of an issue to my potential adoption.

    You highlighted the most important issue, “exactly how SCXD designs are cached differently from normal XPages applications” and I wish I could bribe someone with some combination of beer, liquor, tea, and/or coffee to help out.

    Standing offer all, you read it here first!

    1. The symptoms remind me a little of the Design Refresh issue with Java code in 8.5.3 (I think), where existing Java methods appeared to be updated, when looking at the .java files, but the cached versions were still running until Project > Clean was run. This seems to be a layer higher up though, as if the SCXD NSF were loaded alongside the OSGi plugins, because Project > Clean doesn’t work here. And the console commands for refreshing OSGi elements only exist for OSGi bundles (e.g. org.openntf.domino.xsp). We just need a way of getting a handle on that master database and remove it from memory, as long as accessing the slave database then reloads the master database.

  2. We have been using SCXD for about 2 years in a very large deployment (thousands of databases across multiple servers) and have never had problems. In fact, we see significant performance increases when using it, particularly in the notes client but also on the server (both in reduction in server load and better response times).

    Why did you decide to stop using it? Our upgrade process is simple, out of hours we refresh the SCXD template then bounce the HTTP task (which takes all of 20 seconds). Doing this is actually less downtime that refreshing the design of all the databases, and the caching is helpful since people can still access the sites while we do it.

    I could see if you had a shared server you don’t want to impact other applications, but really you shouldn’t be doing frequent updates to a production environment anyway, certainly for us it was worth the trade off.

    1. The problem was a shared server on a customer site, so out of hours was not as easy and pushing up during the day could impact current use. Updates to SCXD database alone were relatively straightforward, but when updates include views in each database, XPages and Java design elements, the migrations became more challenging. Where all my business logic is in Java, the limitation of updates to that was a frustration. I spent some time testing the workaround IBM provided here, but couldn’t get it to work for me. I agree that updates to a live production environment should not be frequent, but my brain hurt trying to understand / identify the potential data impacts of some design elements updating while others didn’t. And this is only going to be at most about 25 databases plus the same number of archives, only via browser access. For something as large as you’re situation, I’d probably spend the time seeing if it’s possible to perform the relevant design refresh and trigger HTTP restart programmatically. I wouldn’t recommend refreshing that many databases manually either.

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top