This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 11.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit fdb5e69c96d7763753206b5fc0132eba4f2bb44c Author: opencode <[email protected]> AuthorDate: Fri Oct 9 10:29:21 2026 +0200 Report failure when storing a context class without store description StoreConfig.store(Context) is the MBean operation behind the Manager webapp "save" action. It returned true even when the store registry had no description for the context's class and nothing was stored, so the manager reported the configuration as saved when it was not. The registry lookup is keyed by the exact class with only a limited set of interfaces as fallback, and Context is not among them, so any custom context implementation hit this path. Return false and log a factory.storeNoDescriptor warning when the description is missing, and log the same warning in the storeContext(ObjectName,...) operation which silently did nothing in that case. --- .../org/apache/catalina/storeconfig/StoreConfig.java | 20 ++++++++++++-------- .../apache/catalina/storeconfig/TestStoreConfig.java | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/java/org/apache/catalina/storeconfig/StoreConfig.java b/java/org/apache/catalina/storeconfig/StoreConfig.java index bb861281db..8290e02082 100644 --- a/java/org/apache/catalina/storeconfig/StoreConfig.java +++ b/java/org/apache/catalina/storeconfig/StoreConfig.java @@ -185,6 +185,8 @@ public class StoreConfig implements IStoreConfig { desc.setBackup(oldBackup); desc.setExternalAllowed(oldExternalAllowed); } + } else { + log.warn(sm.getString("factory.storeNoDescriptor", aContext.getClass())); } } else { log.error(sm.getString("config.missingContextFile", aContext.getPath())); @@ -223,14 +225,16 @@ public class StoreConfig implements IStoreConfig { public synchronized boolean store(Context aContext) { try { StoreDescription desc = getRegistry().findDescription(aContext.getClass()); - if (desc != null) { - boolean old = desc.isStoreSeparate(); - try { - desc.setStoreSeparate(true); - desc.getStoreFactory().store(null, -2, aContext); - } finally { - desc.setStoreSeparate(old); - } + if (desc == null) { + log.warn(sm.getString("factory.storeNoDescriptor", aContext.getClass())); + return false; + } + boolean old = desc.isStoreSeparate(); + try { + desc.setStoreSeparate(true); + desc.getStoreFactory().store(null, -2, aContext); + } finally { + desc.setStoreSeparate(old); } return true; } catch (Exception e) { diff --git a/test/org/apache/catalina/storeconfig/TestStoreConfig.java b/test/org/apache/catalina/storeconfig/TestStoreConfig.java index cfb0de62ee..5f922cdd2c 100644 --- a/test/org/apache/catalina/storeconfig/TestStoreConfig.java +++ b/test/org/apache/catalina/storeconfig/TestStoreConfig.java @@ -644,6 +644,26 @@ public class TestStoreConfig extends TomcatBaseTest { Assert.assertTrue(dump, dump.contains("type=\"EC\"")); } + /** + * Verify that storing a Context whose class has no store description is reported as a failure rather than as a + * success, since nothing is persisted for it. + * + * @throws Exception if the test experiences an unexpected error + */ + @Test + public void testStoreContextWithoutDescriptionFails() throws Exception { + StoreLoader loader = new StoreLoader(); + loader.load(null); + StoreConfig storeConfig = new StoreConfig(); + storeConfig.setRegistry(loader.getRegistry()); + + Context context = new StandardContext() { + // Sub-class that the store registry does not know + }; + Assert.assertNull(loader.getRegistry().findDescription(context.getClass())); + Assert.assertFalse(storeConfig.store(context)); + } + private static String storeToString(StoreDescription desc, Object element) throws Exception { StringWriter buffer = new StringWriter(); desc.getStoreFactory().store(new PrintWriter(buffer), -2, element); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
