PluginServlet.servletConfig is null

  • Openfire 5.0.2
  • Java-21-OpenJDK-21.0.3.0.9-1.el9.alma.1
  • Bundled search plugin

I noticed on startup I am getting an error in the openfire.log:

2025-10-02T12:52:21.763Z DEBUG [PluginMonitorTask-2]: org.apache.jasper.servlet.JasperInitializer - Initializing Jasper for context [ROOT]
2025-10-02T12:52:21.764Z DEBUG [PluginMonitorTask-2]: org.apache.jasper.servlet.JasperInitializer - Tld pre-scan detected
2025-10-02T12:52:21.779Z DEBUG [PluginMonitorTask-2]: org.apache.jasper.servlet.TldScanner - No TLD files were found in resource path [/WEB-INF/].
2025-10-02T12:52:21.803Z DEBUG [PluginMonitorTask-2]: org.apache.jasper.servlet.JspServlet - Scratch dir for the JSP engine is: [/var/opt/openfire/tmp/jetty-__1-9090-webapp-_-any-5264178830726977181/jsp]
2025-10-02T12:52:21.803Z DEBUG [PluginMonitorTask-2]: org.apache.jasper.servlet.JspServlet - IMPORTANT: Do not modify the generated servlets
2025-10-02T12:52:21.840Z  INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.AdminConsolePlugin - Admin console listening at http://::1:9090
2025-10-02T12:52:21.840Z DEBUG [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginManager - Initialized plugin 'admin'.
2025-10-02T12:52:21.841Z  INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginManager - Successfully loaded plugin 'admin'.
2025-10-02T12:52:21.868Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginManager - Loading plugin 'search'...
2025-10-02T12:52:21.880Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found 2 servlet name(s): org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp, org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp
2025-10-02T12:52:21.881Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Loading servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp' of plugin 'search'...
2025-10-02T12:52:21.881Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found class name for servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp': org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp
2025-10-02T12:52:21.891Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Initializing servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp' of plugin 'search'...
2025-10-02T12:52:21.892Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found 0 init-params(s) for servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp'
2025-10-02T12:52:21.893Z  WARN [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Exception attempting to load servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp' (org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp) of plugin 'search'
java.lang.NullPointerException: Cannot invoke "javax.servlet.ServletConfig.getServletContext()" because "org.jivesoftware.openfire.container.PluginServlet.servletConfig" is null
        at org.jivesoftware.openfire.container.PluginServlet$1.getServletContext(PluginServlet.java:201) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.apache.jasper.runtime.TagHandlerPool.getOption(TagHandlerPool.java:162) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(TagHandlerPool.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp._jspInit(search_002dprops_002dedit_002dform_jsp.java:109) ~[?:?]
        at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServlet.java:193) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java:621) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.lambda$run$3(PluginMonitor.java:354) ~[xmppserver-5.0.2.jar:5.0.2]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
        at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
2025-10-02T12:52:21.915Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Loading servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp' of plugin 'search'...
2025-10-02T12:52:21.916Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found class name for servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp': org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp
2025-10-02T12:52:21.921Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Initializing servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp' of plugin 'search'...
2025-10-02T12:52:21.922Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found 0 init-params(s) for servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp'
2025-10-02T12:52:21.922Z  WARN [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Exception attempting to load servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp' (org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp) of plugin 'search'
java.lang.NullPointerException: Cannot invoke "javax.servlet.ServletConfig.getServletContext()" because "org.jivesoftware.openfire.container.PluginServlet.servletConfig" is null
        at org.jivesoftware.openfire.container.PluginServlet$1.getServletContext(PluginServlet.java:201) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.apache.jasper.runtime.TagHandlerPool.getOption(TagHandlerPool.java:162) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(TagHandlerPool.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp._jspInit(advance_002duser_002dsearch_jsp.java:120) ~[?:?]
        at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServlet.java:193) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java:621) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.lambda$run$3(PluginMonitor.java:354) ~[xmppserver-5.0.2.jar:5.0.2]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
        at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
2025-10-02T12:52:21.924Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.util.WebXmlUtils - Found 0 filter name(s):
2025-10-02T12:52:21.926Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.component.InternalComponentManager - InternalComponentManager: Registering component for domain: search
2025-10-02T12:52:21.933Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.component.InternalComponentManager - InternalComponentManager: Component registered for domain: search
2025-10-02T12:52:21.934Z DEBUG [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginManager - Initialized plugin 'search'.
2025-10-02T12:52:21.965Z  INFO [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginManager - Successfully loaded plugin 'search-1.8.0-SNAPSHOT'.
2025-10-02T12:52:21.966Z  INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Finished processing all plugins.
2025-10-02T12:52:21.966Z DEBUG [PluginMonitorTask-2]: org.jivesoftware.openfire.spi.ConnectionManagerImpl - Received plugin monitor event! Plugins should now be loaded.
2025-10-02T12:52:21.966Z DEBUG [PluginMonitorTask-2]: org.jivesoftware.openfire.spi.ConnectionManagerImpl - Received a request to start listeners. Have plugins been loaded?
2025-10-02T12:52:21.967Z DEBUG [PluginMonitorTask-2]: org.jivesoftware.openfire.spi.ConnectionManagerImpl - Starting listeners...

Tracing back the error, it is coming from:

Which the javadoc comment indicates the map can be empty, but not null. In the next function below it, which it calls, an empty map is created, but it seems line 229 is returning null when it gets back an empty map.

At first I thought it might have been something to do with the search plugin still using the Jetty 9.2.14.v20151106 jetty-jspc-maven-plugin, but when I replaced it with the Jetty 12.0.24 jetty-ee8-jspc-maven-plugin and set the xmppserver dependency to use Openfire 5.0.2 (to match the version in the xmppserver/pom.xml, per the plugin template comments), I still get the same error.

Java is not my primary language, so I could be way off in left field here, but I wonder if Openfire/xmppserver/src/main/java/org/jivesoftware/util/WebXmlUtils.java at 8b7759b5afcae75d3c0b6534974bb71279050b95 · igniterealtime/Openfire · GitHub needs to initialize a map before making the getInitParams call. Assign the call to the new map, then return that map. It feels like the empty map is getting implicitly changed to null in the passthrough of that call.

^^^^^^^^^^^^^^^^^^^
Scratch that. I tried it and I still get the same null reference passed back.

Huh, that’s weird. As the plugin is bundled with Openfire, every instance should see this. I’m not seeing this myself (and I’m building/installing Openfire multiple times a day), and you’re the first to report this. It doesn’t prove anything, but it may suggest that the problem is somehow local to you.

The last fix for the search plugin is OF-3096 and was included in Openfire 5.0.1. It updates the bundled search plugin from 1.7.4 to 1.7.5. Can you double-check what version you’re using? Maybe somehow, some old version is retained?

It is version 1.7.5. Weird you aren’t getting any errors due to the plugin using Jetty 9.2’s JSP. I wonder if it’s something in Java 21 that got deprecated causing the issue. In any case, I thought the plugin pom.xml would be updated similar to Upgrade to Openfire 5.0.0 · igniterealtime/openfire-exampleplugin@e73cda5 · GitHub

We don’t use the search plugin, so it’s not an issue for us. If I can get more details on how to replicate, I will update you.

@guus I had GitHub Copilot take a swing at figuring out the issue. I think the reason you are not seeing it is we compile on and run our build with Java 21. This looks to be an issue that is hidden in the Java 17 implementation, but is aggravated by Java 21. Here is it’s conclusion:

Root Cause : The issue is a timing/initialization order problem that’s more pronounced in Java 21. The PluginServlet.servletConfig was null when plugins tried to initialize their JSP servlets during startup.

Here is the copilot summary:

  • Problem: Java 17 code (upstream Openfire) running on Java 21 (your build environment) experiences different servlet initialization timing
  • Symptom: NullPointerException when JSP servlets try to access ServletConfig.getServletContext() during plugin loading
  • Root Cause: Java 21’s JVM initializes servlets in a slightly different order than Java 17

So, while it doesn’t seem to be easily reproducible in Java 17, it is still there. When you guys change your coding and builds to java 21, it will likely rear it’s head at that time.

That is a good find (I’ve not confirmed it yet myself, but this seems credible). I’ve raised a new ticket for this: OF-3140

We do use Java 21 in our integration tests, but that hasn’t picked up this issue. I do expect that the search plugin is part of the test fixture (as it’s installed by default), but I doubt that the tests explicitly verify the functionality.

@danc is it worth investing a bit in a more generic check? Thinking out loud: start Openfire, leave it running for an x-amount of seconds, then check if the log file contains something undesirable (things logged on level ERROR, occurrences of stack traces, or maybe the presence of certain keywords like NullPointerException?

Here are the stack traces:

2025-10-24T02:29:06.536Z  INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginManager - Successfully loaded plugin 'admin'.
2025-10-24T02:29:06.574Z  WARN [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Exception attempting to load servlet 'org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp' (org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp) of plugin 'search'
java.lang.NullPointerException: Cannot invoke "javax.servlet.ServletConfig.getServletContext()" because "org.jivesoftware.openfire.container.PluginServlet.servletConfig" is null
        at org.jivesoftware.openfire.container.PluginServlet$1.getServletContext(PluginServlet.java:201) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.apache.jasper.runtime.TagHandlerPool.getOption(TagHandlerPool.java:162) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(TagHandlerPool.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.plugin.search.advance_002duser_002dsearch_jsp._jspInit(advance_002duser_002dsearch_jsp.java:70) ~[?:?]
        at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServlet.java:193) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java:621) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.lambda$run$3(PluginMonitor.java:354) ~[xmppserver-5.0.2.jar:5.0.2]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
        at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
2025-10-24T02:29:06.577Z  WARN [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginServlet - Exception attempting to load servlet 'org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp' (org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp) of plugin 'search'
java.lang.NullPointerException: Cannot invoke "javax.servlet.ServletConfig.getServletContext()" because "org.jivesoftware.openfire.container.PluginServlet.servletConfig" is null
        at org.jivesoftware.openfire.container.PluginServlet$1.getServletContext(PluginServlet.java:201) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.apache.jasper.runtime.TagHandlerPool.getOption(TagHandlerPool.java:162) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(TagHandlerPool.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.plugin.search.search_002dprops_002dedit_002dform_jsp._jspInit(search_002dprops_002dedit_002dform_jsp.java:57) ~[?:?]
        at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:47) ~[apache-jsp-9.0.107.jar:9.0.107]
        at org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServlet.java:193) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java:621) ~[xmppserver-5.0.2.jar:5.0.2]
        at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.lambda$run$3(PluginMonitor.java:354) ~[xmppserver-5.0.2.jar:5.0.2]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
        at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
2025-10-24T02:29:06.599Z  INFO [PluginMonitorExec-3]: org.jivesoftware.openfire.container.PluginManager - Successfully loaded plugin 'search-1.7.5'.
2025-10-24T02:29:06.599Z  INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Finished processing all plugins.

I have tried, but am unable to reproduce this issue. Furthermore, I’ve analyzed code, and I can’t find a good reason why this would happen under normal usage of Openfire.

From what I found, I don’t think this problem relates directly to ‘a different order of events’ under Java 21. Maybe using Java 21 generates an error somewhere that causes things to fail? I have tried using Java 21 - there’s no problem on my end.

A detailed write-up was added as a comment to https://igniterealtime.atlassian.net/browse/OF-3140

I’m a bit at a loss how to proceed with this issue. Suggestions would be very welcome.

I haven’t tested it yet, but another developer identified an issue yesterday with our custom plugin after it was updated to support Openfire 5. If I had to hazard a guess, this might be a knock-on effect from that. The issue is the internal jar file was being uploaded to the plugins folder, not the parent jar file that contained all the other plugin files that get extracted to the plugin folder.

Thanks for the update, but can you elaborate? Specifically: is this an admin uploading an incorrect file, or is this Openfire not properly working with parent/child plugins?

I believe it is us packaging the wrong plugin jar file in our plugin deployment RPM. Go ahead and close this investigation for now. If I am able to get more details at a later time, I will update the ticket and this thread.

1 Like