How can I get an instance of XWikiContext?

In my extension, I’m running a background thread which runs forever. The job of this thread is to sync user profiles (such a photo, phone, few more user-defined fields) with profiles on some external services (such as Slack or so), in addition to few other things such as keeping the rights as desired (e.g, an admin mistakenly made the wiki public from UI without realizing it, so this thread reverts those changes). This thread mostly sleeps, wakes up on a regular period, does it work and then goes back to sleep, in a loop.

In this thread, I need an instance of XWikiContext so that it could do its work. Both these calls return null for me:

Utils.getContext();                        // returns null
Utils.getComponent(XWikiContext.class);    // returns null

I vaguely understand that these functions will return non null value only within a context of calls such as login, logout, and other (http) requests. Am I right?

My queries are:

  • How do I get an instance of XWikiContext in the above background-thread context? Alternatively, how do I safely carry out the above tasks in the background?
  • Can XWikiContext be used by multiple threads?

It’s really not designed for this no and you will have problem.

There is actually several kind of context in XWiki:

  • the ExecutionContext
  • the XWikiContext which is actually an old thing now part of the more generic ExecutionContext

So the first thing to do when you start a background thread is to take care of initialize and clean an ExecutionContext.

Then the standard way to access the current XWikiContext (or have one automatically generated for you) is by using the Provider component. See for more details.

Now something which is really not recommended is to keep the same ExecutionContext/XWikiContext forever since it’s supposed to be short lived and you might end up with a memory leak caused by module caching stuff in it supposedly for a short time (unless you absolutely control everything that may manipulate the context in your thread but that’s usually not the case when you need a XWikicontext).

I can suggest several cleaner possibilities: