Spring配置报错:无法定位context命名空间的NamespaceHandler
Alright, let's break down what's causing your problem and walk through the solutions step by step:
Root Cause
Your hunch is exactly right — the missing META-INF/spring.handlers and META-INF/spring.schemas files in your shaded JAR are the core issue. Spring uses these files to map XML schema namespaces (like http://www.springframework.org/schema/context) to their corresponding NamespaceHandler implementations. When using the Maven Shade plugin without proper configuration, it overwrites these files from different Spring JARs instead of merging them, leaving only entries from one JAR and breaking others like the context namespace.
Step 1: Fix Maven Shade Plugin Configuration
Update your Shade plugin setup to explicitly merge Spring's META-INF resource files. Add the following resource transformers to your plugin configuration:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <!-- Use the latest stable version --> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- Keep your main class entry point --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>your.main.class.path.Here</mainClass> </transformer> <!-- Merge Spring's handler and schema files --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <!-- Optional: Merge spring.factories if you use auto-configuration features --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.factories</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
This setup tells the Shade plugin to append content from all JARs' Spring configuration files instead of overwriting them, ensuring all namespace handlers are properly registered.
Step 2: Verify Dependency Scopes
Double-check your pom.xml to ensure your Spring dependencies (spring-core, spring-context, spring-context-support) don't have a <scope> set to provided or test. These scopes prevent the JARs from being included in your shaded artifact, leaving necessary classes and configuration files missing in the test VM.
Example of a correct dependency declaration:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.1.RELEASE</version> <!-- No scope here, defaults to compile --> </dependency>
Step 3: Validate the Shaded JAR
After re-packaging with the fixed Shade plugin, open your JAR file and check the META-INF/spring.handlers file. It should contain an entry like this for the context namespace:
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
If this line exists, the namespace handler is properly registered and your configuration should load without errors.
Alternative: Use Maven Assembly Plugin
If you still run into issues with Shade, try the Maven Assembly plugin instead. Define an assembly descriptor that includes all your dependencies and merges the Spring META-INF files. It's a bit more verbose but sometimes more reliable for complex dependency merging scenarios.
内容的提问来源于stack exchange,提问作者Nirmalya

