Bug 64006 - MemoryUserDatabase in >=9.0.14 insists on statically set ConfigFileLoader ConfigurationSource
Summary: MemoryUserDatabase in >=9.0.14 insists on statically set ConfigFileLoader Con...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 9
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 9.0.14
Hardware: PC Mac OS X 10.1
: P2 normal (vote)
Target Milestone: -----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-12-16 11:27 UTC by Brett Randall
Modified: 2019-12-16 23:39 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brett Randall 2019-12-16 11:27:16 UTC
In Tomcat 9.0.13 and earlier, the following code:

package tomcat.embedded.test;

import org.apache.catalina.users.MemoryUserDatabase;

public class Main {

	public static void main(String[] args) throws Exception {
		MemoryUserDatabase database = new MemoryUserDatabase("foo");
		database.setPathname("file:///tmp/users.xml");
		database.open();
		System.out.println(database.findUser("both"));
		database.close();
	}

}

... with a standard/valid users.xml, runs without error, producing:

$ ./gradlew build run

> Task :run
User username="both", roles="tomcat,role1"
Dec. 16, 2019 10:14:01 PM org.apache.catalina.users.MemoryUserDatabase save
SEVERE: User database has been configured to be read only. Changes cannot be saved

BUILD SUCCESSFUL in 852ms

In the next version 9.0.14, the new ConfigFileLoader API is introduced.  In many parts of Tomcat this seems to be optional, but for the MemoryUserDatabase loaded from file, it is insisted-on ... failing to statically set first, the above code yields:

$ ./gradlew build run

> Task :run FAILED
Exception in thread "main" java.lang.IllegalStateException: No configuration source has been set using ConfigFileLoader.setSource.
        at org.apache.tomcat.util.file.ConfigFileLoader.getSource(ConfigFileLoader.java:40)
        at org.apache.catalina.users.MemoryUserDatabase.open(MemoryUserDatabase.java:426)
        at tomcat.embedded.test.Main.main(Main.java:10)

FAILURE: Build failed with an exception.

The above code is the minimal, trivial example to demonstrate the change, but similar code will run e.g. when a MemoryUserDatabase is loaded with naming enabled, from a resources file.

This seems like a regression, since code working in 9.0.13 no longer works in 9.0.14.  Was it intentional to make the ConfigFileLoader static set mandatory for some parts of Tomcat, or is this a bug?

This was found when revving Tomcat test version in Gretty https://github.com/gretty-gradle-plugin/gretty - an integration test starts failing due to the above problem.  In Gretty we need to decide whether we will have for forcibly adopt ConfigFileLoader for latest Tomcat (only, no good prior to 9.0.13), or whether this can be fixed in Tomcat.

Related commit https://github.com/apache/tomcat/commit/4a86837bcb25b3c3812577c63213b12209a96e1a
Comment 1 Remy Maucherat 2019-12-16 12:22:22 UTC
The individual components of Tomcat are usually not tested at all out of Tomcat standalone or embedded, except when marked otherwise. However, the idea was not to break existing code with the introduction of ConfigurationSource. Aa a result, a default source will now be used in Tomcat 9.0.31+.

This will likely be revisited in Tomcat 10, and the code will likely either break as it does in 9.0.30, or cause a very visible log message.
Comment 2 Brett Randall 2019-12-16 22:09:24 UTC
Thanks Remy.  So will the default config source in 9.0.31+ wrap any provided non-API file config ... so the above test would pass, finding the configured Users file to load?  If so that would be a good solution restoring compat with manual file configs.
Comment 3 Remy Maucherat 2019-12-16 23:39:03 UTC
Yes, your code posted above will work again.