-
Notifications
You must be signed in to change notification settings - Fork 122
Description
I have a test class that runs multiple scenarios for a validating SaxBuilder - some with a Catalog-based resolver, some without. During development, when I tested the individual test cases, everything was green. But when I run all tests in one go, then some tests reproducibly fail.
I eventually tracked this down to the fact that AbstractReaderXSDFactory caches the SchemaFactory returned by the SchemaFactoryProvider in a static thread-local variable. When multiple of my test cases are run subsequently in the same thread, they use the same SchemaFactory even though I passed a different SchemaFactoryProvider to the constructor.
The rationale given in the source code is as follows:
/**
* Use a Thread-Local system to manage SchemaFactory. SchemaFactory is not
* thread-safe, so we need some mechanism to isolate it, and thread-local is
* a logical way because it only creates an instance when needed in each
* thread, and they die when the thread dies. Does not need any
* synchronisation either.
*/
private static final ThreadLocal<SchemaFactory> schemafactl = new ThreadLocal<SchemaFactory>();I don't think this thread-local is needed, though: The thread-local is exclusively accessed in the private static method getSchemaFromSource(SchemaFactoryProvider sfp, Source ... sources). This method is only called (directly or indirectly) from the constructors; the constructors are executed in a single thread, respectively. The caller can easily make sure that different threads use different SchemaFactoryinstances.
The current implementation makes it impossible to use validating SaxBuilders with different schema factories if there is a chance that they are used in the same thread.