Quick Tip: Deploying Static Resources As A Webapp

Sun Jun 29 13:38:14 EDT 2025

Tags: domino osgi

The other day, I had occasion to deploy a newer Dojo version to Domino than what was present - a later version fixed some layout problems in a chart, but the client isn't ready to update to Domino 14.5. Since this wasn't an XPages app, I didn't need to worry about incompatibilities or the XPages-specific extensions, but there was still the matter of getting Dojo's giant file tree served up by Domino.

Normally, this isn't a big deal - a JavaScript library can usually be plunked in to the NSF without issue. But Dojo's tree is still big enough that it will break the DB's design. I could probably fix that by pruning the directory, but I didn't want to spend that much time on the task. It'd also have the disadvantage that Domino would complain about any "?" URLs that don't start with "?Open", which is a drag.

The next option is to copy the files to the data/domino/html directory. That would work, but it kind of sucks: now you have files not represented in NSFs, and one more thing for admins to keep track of and for developers to forget. So that's an option of last resort.

Another approach I've taken in the past is to make an OSGi plugin that contributes an ExtLibLoaderExtension. That lets your plugin contribute resources to the ExtLib's own resource provider. The big advantage here is that, if you write your code right, they can participate in the minifier. However, since this isn't an XPages app, that won't realistically do me any good, and it'd also involve writing some fiddly custom code that we'd have to know about forever.

Wrapper App

But then I came up with another route: I could make a tiny little web app using the com.ibm.pvc.webcontainer.application extension point solely to host these files. Normally, you'd use that point to make a complicated (ancient) Java EE web app, but this use doesn't even involve any Java code. I made mine in Maven, but even that is technically optional: the result just has to be a JAR (which is a ZIP file) with a couple files in it, plus whatever resources you want to serve. I'll use it here, though, since it takes care of some fiddly bits for us.

First up, you should have a "src/main/resources/plugin.xml" file with contents like:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
	<extension point="com.ibm.pvc.webcontainer.application">
		<contextRoot>/dojo-1.17.3</contextRoot>
		<contentLocation>WebContent</contentLocation>
	</extension>
</plugin>

Here, "/dojo-1.17.3" is the path on the web server it'll be accessible as, while "WebContent" is where we'll be storing the files within our JAR.

Next up, we want a file named "src/main/resources/WebContent/WEB-INF/web.xml". This would normally list Servlets and other configuration for the web app, but we don't have any of that - it's just here as a stub:

1
2
3
4
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
</web-app>

Then, put any files you want to serve up in "src/main/resources/WebContent". We don't need to configure anything else to point at these, so they can be anything. Here, I put the "dojo", "dijit", and "dojox" directories there:

Screenshot of the project file layout

Finally, we'll have the "pom.xml" file at the root of our project to tell it how to build. This has a couple custom steps to the build, but mostly it could be copy-and-pasted into your own project, just changing the groupId, artifactId, and name to suit your needs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>com.example.dojo</artifactId>
	<version>1.17.3</version>
	<name>Dojo Assets Wrapper</name>
	<packaging>bundle</packaging>

	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.release>8</maven.compiler.release>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<osgi.qualifier>${maven.build.timestamp}</osgi.qualifier>
	</properties>

	<repositories>
		<repository>
			<id>artifactory.openntf.org</id>
			<name>artifactory.openntf.org</name>
			<url>https://artifactory.openntf.org/openntf</url>
		</repository>
	</repositories>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<version>5.1.2</version>
				<extensions>true</extensions>
				<configuration>
					<excludeDependencies>false</excludeDependencies>
					<instructions>
						<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
						<Automatic-Module-Name>${project.artifactId}</Automatic-Module-Name>
						<Export-Package />
						<Require-Bundle />
						<Import-Package />
						<Bundle-RequiredExecutionEnvironment>JavaSE-1.8</Bundle-RequiredExecutionEnvironment>
					</instructions>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.openntf.maven</groupId>
				<artifactId>p2-maven-plugin</artifactId>
				<version>2.2.0</version>
				<executions>
					<execution>
						<id>generate-site</id>
						<phase>install</phase>
						<goals>
							<goal>site</goal>
						</goals>
						<configuration>
							<featureDefinitions>
								<feature>
									<id>${project.artifactId}.feature</id>
									<version>${project.version}</version>
									<label>${project.name}</label>
									<providerName>${project.groupId}</providerName>
									<description>${project.name}</description>
									<artifacts>
										<artifact>
											<id>${project.groupId}:${project.artifactId}:${project.version}</id>
											<transitive>false</transitive>
										</artifact>
									</artifacts>
								</feature>
							</featureDefinitions>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.darwino</groupId>
				<artifactId>p2sitexml-maven-plugin</artifactId>
				<version>1.2.0</version>
				<executions>
					<execution>
						<phase>install</phase>
						<goals>
							<goal>generate-site-xml</goal>
						</goals>
						<configuration>
							<category>${project.name}</category>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Once you do a mvn install for that, you'll end up with a repository in "target/repository" with a "site.xml" file suitable for importing into an update site NSF.

This need doesn't come up too frequently, since it's rare that I have to deploy this many files at once, but I'm pleased with this technique. That update site can be replicated around, and the presence of it in the notes.ini means that it's much more self-documenting than dropping the files on the filesystem. Plus, the fact that involves no custom executable code or weird Domino dependencies makes it very portable to build anywhere. It's something for me to keep in my back pocket for the future.

Developing Jakarta Apps Via NSF File Server

Wed Jun 25 16:42:37 EDT 2025

In my previous post, I made an offhanded comment towards the end about how the tool was really for static files and, while it'd be technically possible to deploy Java code this way, it'd be awkward and weird.

But that got me thinking: just how awkward and weird are we talking here? So I set out to trying to see. An app that is all-in on Jakarta EE is basically a normal old webapp housed in an NSF, and the structure of the "WebContent" directory is the same as a WAR: visible files go in the top level, JARs go in "WEB-INF/lib", and compiled classes go in "WEB-INF/classes". Normally, the Code/Java design notes in an NSF are those compiled class files, doing double duty to hold the source and the bytecode in the same note, but that's not the only way. If you have a file resource that calls itself "WEB-INF/classes/foo/Bar.class", it'll count as a class in the app. This is how the pre-8.5.3 method of adding Java classes worked: Designer would make one file resource for the source file and another for the bytecode.

Trying It Out

So, since a running app doesn't care about the source, in theory the presence of just the .class files in the right place should suffice for deploying an app. I decided to put the theory to the test and, lo and behold, it worked:

Screenshot of Java bytecode being uploaded via scp to an NSF and a REST service working

Those are the classes from the Jakarta EE starter project, which gives you a Maven project with a JAX-RS resource that emits JSON. The XPages JEE project creates an environment pretty comparable to a normal Jakarta EE server, so the compiled classes work just the same when copied around.

So far, so good, but what about a more-complicated example? A real app will have non-class Java resources (translation properties files, for example), web resource files (HTML, CSS, JS), and dependency JARs. So I added commonmark as a dependency to my project via Maven and built the project. I found that, with a Maven project, the entire structure of your result WAR is present in "target/your-artifact-id", and thus I switched to copying that up:

Screenshot of a more-complicated app in Eclipse uploaded to and running in Domino

This actually scratches an itch I've had for a long time: I've considered the notion of having a mode in the NSF ODP Tooling project that takes a WAR and makes an NSF out of it in this format. As it turns out, the result of that would be the same as this, and this allows for faster iteration on testing changes.

Some Caveats

One major limitation not so much of the tools but of the underlying protocol is that "recursive delete" isn't inherently a thing in SFTP, but it's necessary to make sure that any files from an old build not in new builds (renamed classes, etc.) are deleted when deploying a new version. Since rsync would take a lot of work, I've been looking at lftp, which may fill the gap, but it'll take some fiddling. Dedicated file-transfer GUI tools like Transmit could help too.

Additionally, while it's possible to create a compatible classpath in a Maven project by including the core JEE APIs and some Domino-specific things like the NoSQL driver as dependencies, this route wouldn't help you for things like creating or modifying views. Those don't change as frequently as app code, though, so it'd probably be fine to have Designer (or Nomad Designer) around for that task in much the same way as one might use a database management app in other environments.

It's also a longer cycle between making a change and seeing it than when using Designer, since you'd have to make sure to do a local build and then copy the files up, which will scale in time with the complexity of your project. That may be a fair price to pay to have your choice of IDEs and the ability to use Maven for dependencies and processing, though.

Anyway, this is all pretty neat. I've really gotten into a good groove of app dev with the JEE project lately, but I won't pretend I wouldn't mind a nicer development environment. I think I'll have to try using this for some of my projects for a bit to find out if it'll work in general.

Integrating VS Code (And Others) With Domino Via NSF File Server

Wed Jun 25 13:46:23 EDT 2025

Earlier today, Richard Moy posted a neat blog post on a mechanism his team developed to be able to work on HTML, CSS, and JS in Visual Studio Code and sync the results to an NSF, allowing them to use more-modern tools while still hosting in an NSF.

That got me thinking about the NSF File Server project and its support for storing files in "WebContent" in an NSF, and how I could write about how it could accomplish a similar thing. After testing it and finding a bug to fix with served MIME types, I uploaded 2.1.0 and now I'm ready to talk about it!

Quick Intro

The current form of the project came out a bit over a year ago, and I posted about the various new features. The important one for our needs is the ability to use the conceptual "WebContent" directory in the NSF to house static files. As a note, though this directory usually comes up in the context of XPages/Java development, it's not really tied to them - it's just another type of File Resource.

The way the project works is that it's an OSGi plugin and thus best deployed in an Update Site NSF referenced via notes.ini. There's also a config NSF to create - the NTF is in the distribution as "fileserverconfig.ntf" and should be created on the server as "fileserverconfig.nsf". This DB can be replicated around your domain, since all of the configuration options are or can be server-specific.

Once the NSF is in place, create a document in the "Server Configurations" view for your server to set the port it will listen on. Then, create a document in "Mounts" to point to the NSF you want to work with, giving it an appropriate name and putting the NSF path in "Data Source Path":

Screenshot of the Mount configuration document UI

You'll probably also want to tweak your Domino Directory NSF to add a text item named "sshPublicKey" to house, well, each user's SSH public key (the kind you get from ssh-keygen). In my environment, I added this (and a bunch of other stuff) to the "$PersonExtensibleSchema" subform as a multi-value text item:

Screenshot of an sshPublicKey item in names.nsf

You can also use password-based authentication, but you shouldn't.

Once it's all set, restart HTTP, since the server's lifetime is bound to HTTP.

Testing It Out

Before trying any fancier integration, it'll be a good idea to test using a simple SFTP client. The simplest is the sftp tool that comes with the SSH suite on basically every OS:

1
sftp -v -i ~/.ssh/id_rsa -P 9022 "CN=Jesse Gallagher/O=IKSG@your.domino.server"

The username should be something recognizable to Domino - I'm sure variations will work, but I like using the full DN by default to eliminate ambiguity.

Once connected, you should see your mounted DB as a folder. You should be able to cd into it and ls to list the contents. In a new NSF, you'll see the WEB-INF directory Designer creates, and you'll also see anything you put in there intentionally. If you have a local file, you can put foo.txt to try uploading and deleting it:

1
2
3
4
5
6
7
sftp> cd appexample
sftp> put license.txt
Uploading license.txt to /appexample/license.txt
license.txt                                                                            100%  589   184.5KB/s   00:00
sftp> rm license.txt
Removing /appexample/license.txt
sftp> 

If all is set up properly and you have Designer access to the NSF, you should be good to go.

Configuring VS Code

In my tinkering, I used the simply-named SFTP plugin for VS Code, which lets you configure a directory to sync automatically with a remote SFTP server. Following the examples, I configured my .vscode/sftp.json config file like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
    "name": "Your Server",
    "host": "your.domino.server",
    "protocol": "sftp",
    "port": 9022,
    "secure": true,
    "username": "CN=Jesse Gallagher/O=IKSG",
    "privateKeyPath": "/Users/jesse/.ssh/id_rsa",
    "remotePath": "/appexample",
    "uploadOnSave": true,
    "ignore": [".vscode", ".git", ".DS_Store"]
}

Once I did that (and re-opened the dir in VS Code to be safe, though I don't know if that was needed), things started syncing on save:

Screenshot of a file edited in VS Code visible in Designer

In that screenshot, you can see the files in WebContent using Designer's Project Explorer view, but that's entirely optional - at this point, you're free to uninstall Designer if you so desire, since VS Code will get the files in there itself thanks to the SFTP server. Your files will show up at URLs like https://your.domino.server/yourapp.nsf/baz.html.

Other Uses

Though I focused on VS Code as an example, there's nothing special about it for using the SFTP server. Since it's a generic protocol, you could also use any other IDE with similar support, or any other SFTP client that can do the syncing for you (rsync doesn't work currently, since it requires its own protocol tunneled over SSH). For example, you might have a CI/CD server like Jenkins do the SFTP for you at the end of a build, so you can see files automatically deployed to Domino. You can also use whatever the heck OS you want as long as it has an SFTP client.

What this won't do (right now) is any kind of non-static programmatic elements like forms, views, agents, or Java elements. I guess you could in theory compile Java locally and push the results to WEB-INF/classes and WEB-INF/lib, which should work, but that would be an odd way to develop. This is primarily of use for writing or deploying static files, either manually edited or as built by a (freaking) JS transpiler toolchain.

It'd also be possible to do much the same thing with other storage "backends". The "NSF File Store" built-in type, for example, uses data documents with the form and views in the "filestore.ntf" template, storing the file data as attachments. One could use that template directly or make compatible views in another app and use that for deployment without requiring giving anyone Designer access to an NSF. It'd also be possible to write an entirely-different storage mechanism, but that'd require the fiddly task of implementing the VFS in Java, so it'd be for dedicated developers only. I think the WebContent mode would do the job nicely in most cases regardless.

In any event, give it a shot! I think it's a neat tool and likely has a potential place in a lot of workflows.

Notes/Domino 14.5 Fallout

Tue Jun 17 09:06:49 EDT 2025

  1. Oct 19 2018 - AbstractCompiledPage, Missing Plugins, and MANIFEST.MF in FP10 and V10
  2. Jan 07 2020 - Domino 11's Java Switch Fallout
  3. Jan 29 2021 - fontconfig, Java, and Domino 11
  4. Nov 17 2022 - Notes/Domino 12.0.2 Fallout
  5. Dec 15 2023 - Notes/Domino 14 Fallout
  6. Sep 12 2024 - PSA: ndext JARs on Designer 14 FP1 and FP2
  7. Dec 16 2024 - PSA: XPages Breaking Changes in 14.0 FP3
  8. Jun 17 2025 - Notes/Domino 14.5 Fallout

With Domino 14.5 out, it's time for me to do my now-traditional post about the release, covering the pertinent changes and bugs I've hit in the release version.

The good news with this release from a Java perspective is that it's pretty smooth sailing. Since Domino 14 already took the big bite of moving past Java 8, the move from Java 17 in 14 to 21 in 14.5 is not really disruptive at all. Hopefully, this trend will keep up - moving from one LTS release of Java to the next is much smoother than jumping over one, and admittedly moving from 8 to anything was more disruptive than any subsequent version bump. My hope is that Domino will remain more-or-less on top of current Java LTSes. The next one will be Java 25 in September, so Domino is current (LTS-wise) at the moment.

Most of the Java features we care about are of the quality-of-life type, which is great. Java has been on a real "let's make developers happy" kick lately, and I'm all for it.

Eclipse also got a bump from 2021-12 to 2023-12, which, while a year and a half old now, is nice. I'd like to see this track closer to current Eclipse, but this is at least much, much better than the bad old days of the 9.x era. I've had some luck installing some recent-ish upstream Eclipse plug-ins that I may make into an OpenNTF project, though some of the ones I want to use require a version newer than 2023-12.

Really, all the notes from my post about Domino 14 still apply here. There aren't any major new hurdles or workarounds to be aware of, so I can skip the main topic and focus just on the little things to know.

Domino

Domino got a bunch of new features, though most are outside my bailiwick. There are a few niceties that show up in my regular work that I'd like to mention, though.

Adminp Signing With One-Touch Setup

When you use One-Touch Setup for a Domino server, you can tell it to sign any DBs you create with it with adminp. I use this all the time for my test suites, since XPages and Java code needs to be properly signed to run. In previous versions, this would appear as tons of lines like "Adding sign bit to item $LargeSummary" on the console. Since my test suite has to wait for this to finish to run, I had to have the code scan for some number of these - while presumably predictable, I found it most practical to just pick a number that worked and go with it.

In 14.5, it will not emit "Database signed by Adminp: foo.nsf", which is much cleaner and also much more useful, since now I can check for the specific count of NSFs that it's signing. This is a huge relief.

Wink Chattiness is Fixed

Speaking of unnecessary console output, one of the things that has bugged me in recent versions is that JAX-RS resources registered with Wink spew a lot of INFO-level junk onto the console with no way to tell it otherwise. This was actually always the case with the Wink version in Domino, but it became more annoying once Verse (which still uses that old JAX-RS version) started coming pre-installed, leading to messages as soon as the first Java request came in every HTTP start. In 14.5, this is fixed. Whoo!

Designer

Most of the enhancements in Designer come from improvements to Java and the underlying Eclipse editors. One nicety - and I forget how much this was the case in 14 - is that Designer is making use of the Language-Server-based editors for JS and CSS more and more with each version, much to our benefit. The age of the Eclipse base means we don't get everything in newer versions (for example, the CSS editor doesn't know about CSS Nesting), but it's still a step up.

Modern JavaScript Syntax

Designer has adopted these LSP-based editors in most places where you edit client JavaScript. This is a great improvement, as the editor is much better and recognizes modern JavaScript syntax. However, while the editor works with it, editing a JavaScript Script Library design element doesn't let you save with legal syntax like let foo = (bar) => {}. If you try that, you'll get an error dialog (three times) saying there's a syntax error.

The workaround I've found for this is to write my JavaScript libraries as File Resources instead, which use the same newer editor but don't have the on-save old validation. These files presumably won't show up in GUI places that list script libraries, but that's a small price to pay.

ndext Annoyance

Unfortunately, the post about Designer's "ndext" behavior in the FPs still applies. Designer will still repeatedly re-add all the crud from the "ndext" directory to the main JRE on every launch, including the traitorous "jsdk.jar", so be on the lookout for that.

It seems like you can work around this by making a second JRE entry in the "Installed JREs" prefs, cleaning it up, and making it your default. Designer shouldn't mess with that one on launch.

Another way you could work around that is to move to the XPages JEE platform, since the current version of the Servlet classes in that project don't conflict with either of the primordial ones in Domino.

Project Explorer Workaround

My preferred project view in Eclipse is the "Project Explorer" view, which is like the older "Package Explorer" in most ways but generally a bit nicer. For example, you can have it show Working Sets as top-level elements with twisties, which is very handy when you're working with a lot of projects.

Designer has this view too and it works the same way, but there's a small bug: when you first launch Designer, this view will be empty even if you have projects in your workspace. You can make the contents appear by clicking the little filter icon and then hitting OK without changing anything.


All in all, 14.5 is a very solid release. I've been using the EA versions since the start for normal day-to-day development and plan to continue to do so. The Java updates alone mean that this is all the more reason to leave 12.x and below in the dust.

New Release: XPages Jakarta EE 3.4.0

Sat Jun 07 14:57:04 EDT 2025

Tags: jakartaee

Today, I published version 3.4.0 of the XPages JEE project. In addition to the usual spate of bug fixes and refinements, this release brings two significant features: a bump to Jakarta EE 11 (mostly) and a new type of pure Jakarta app within an NSF.

Jakarta EE 11

Jakarta EE 11 has been in the works for a good while but is now mostly released. There remain a few components that are slotting into place, and some of the implementations remain in beta form, but they're in a reasonable state to put into a release. I like to keep this project up to date, and there are some nice improvements in here.

  • It officially adds Jakarta Data as a spec, though we've had that in the project for a good while now
  • CDI has a bunch of cleanup changes and now lets you organize producers by @Priority, which can be handy in some cases
  • Faces also has a handful of improvements, cleaning up the API a bit and making events more consistent
  • Pages (which remains my HTML generation tool of choice in new apps) got some long-needed cleanup
  • REST gained some new methods for working with headers and processing matched resources
  • Expression Language gained proper support for records and Optional (though the latter is off by default in the spec, it's enabled in this project)
  • Servlet gained some methods to work with Charset and ByteBuffer objects, which I've shimmed into the older ones Domino internally supports
  • MVC made a few good but breaking changes, removing support for Facelets (Jakarta Faces pages) as a view type and making CSRF enabled by default
  • Concurrency has some nice new features, though unfortunately the currently-released implementation doesn't yet support the nifty @Asynchronous annotation. That should come in the future, though

To go with these improvements, I put in a handful of refinements:

  • There's a new @DocumentConfig annotation you can use with NoSQL @Entity-annotated classes to declare what the actual form name should be. This is useful for cases where you have entities in the same app representing documents in different databases that happen to use the same form
  • There's a new org.openntf.xsp.jakarta.el.ext.ELResolverProvider ServiceLoader interface to customize handling of Expression Language resolution per-app
  • MicroProfile Metrics is gone, as it was removed upstream. In a future version, I plan to implement MP Telemetry, which is more flexible and has integrations with more services

Jakarta Modules

The largest feature addition, though, is what I've deemed "Jakarta Modules". The "module" term here is in reference to ComponentModule, the system Domino's HTTP stack uses to manage individual applications at the Java level. I've talked about this before, and the idea here is that a Jakarta Module is a peer to NSFComponentModule (the way NSFs are normally run with XPages) and OSGi*Module (the way Equinox Servlets and OSGI WebContainer apps are run).

These app types still use an NSF and you develop them the same way using Designer, but there are some key differences:

  • The entire application is treated like a "normal" Jakarta web app, which means that it has fewer old-to-new shims and workarounds
  • These apps are configured with a new database - jakartaconfig.nsf - that allows you to specify a web path to reference an NSF. So, for example, you configure "/someapp" to read its data from "/apps/someapp.nsf", and then all URL references will be "/someapp/your/app/url". This means that the URLs don't include ".nsf" and don't require having "xsp" somewhere in there like they do with traditional apps. This also means you can configure REST to use the app root as its own root, which is particularly useful when using MVC
  • XPages and legacy design elements like forms and views are not supported for web access. While you can still freely use views programmatically, they aren't accessible by URL within the module's space. Web-friendly elements like file resources, style sheets, and images work as they do with traditional apps
  • These apps are initialized at HTTP start, which means you can reliably use things like ServletContextListener and CDI beans with methods like void init(@Observes Startup) to do app pre-load. CDI beans like that will have a NoSQL context running as the DB signer, so you can use those to load configuration data from the NSF, for example
  • The ability to hook into HTTP init also means you can use ManagedScheduledExecutorService for a predictable replacement for scheduled agents that run entirely in your app space
  • This also allows reliable use of HttpSessionListeners and ServletRequestListeners, which don't quite have proper hooks in XPages apps

It's possible to develop an application that will work in both "modes", and that's how I've written the test cases for this: I made it so that the non-XPages tests for most features will now access the NSF both in the traditional way and in this new way. Doing this means avoiding XPages-specific classes like ExtLibUtil and NotesContext, and I have some documentation that covers a few of the aspects for writing "portable" apps. In general, though, I imagine it'll be the case that you'll want to pick one type and go with it, since there's no particular reason to access the app both ways.

Since this feature is a complex undertaking, it's more likely than average to contain bugs, so I'd appreciate as much testing as possible. I plan to move a couple apps over to this format - I decided to bite the bullet for Magpie's sake, since I wanted scheduled tasks, but I also plan to dogfood it with other things I work on. I also expect I'll have some followup blog posts about it, as I had to solve a number of interesting technical problems to get it to this point.

Future Enhancements

With this one in the bag, I have some plans for future versions. For one, I've been lining up desired features for Jakarta Modules, but beyond that I'll want to bump the remaining JEE 11 laggards when their implementations are out, and there's the aforementioned MicroProfile Telemetry. I'd also at some point like to give the same Jakarta Module treatment to more-traditional webapps, potentially attaching a WAR file in jakartaconfig.nsf and using that. I imagine most of the code would be shared between the two - a lot of the NSF-specific code is encapsulated in a few classes, while all the app-lifecycle bits are independent of the actual storage of classes and resources. That'd be a fun one to do.