diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
index b09bb7b1c..9373665bb 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
@@ -37,4 +37,5 @@ public class CoreNamespaceHandler extends NamespaceHandlerSupport {
this.registerBeanDefinitionParser("job-listener", new TopLevelJobListenerParser());
this.registerBeanDefinitionParser("step-listener", new TopLevelStepListenerParser());
}
+
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
index e08c2d3eb..aac11cf2a 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
@@ -58,6 +58,14 @@ public class JobParser extends AbstractSingleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ if (!namespaceMatchesVersion(element)
+ || !namespaceMatchesVersion(element.getOwnerDocument().getDocumentElement())) {
+ parserContext.getReaderContext().error(
+ "You cannot use spring-batch-2.0.xsd with Spring Batch 2.1. Please upgrade your schema declarations "
+ + "(or use the spring-batch.xsd alias if you are feeling lucky).", element);
+ return;
+ }
+
CoreNamespaceUtils.autoregisterBeansForNamespace(parserContext, parserContext.extractSource(element));
String jobName = element.getAttribute("id");
@@ -107,7 +115,7 @@ public class JobParser extends AbstractSingleBeanDefinitionParser {
}
Element description = DomUtils.getChildElementByTagName(element, "description");
- if (description!=null) {
+ if (description != null) {
builder.getBeanDefinition().setDescription(description.getTextContent());
}
@@ -134,4 +142,21 @@ public class JobParser extends AbstractSingleBeanDefinitionParser {
}
+ /**
+ * Check that the schema location declared in the source file being parsed
+ * matches the Spring Batch version. (The old 2.0 schema is not 100%
+ * compatible with the new parser, so it is an error to explicitly define
+ * 2.0. It might be an error to declare spring-batch.xsd as an alias, but
+ * you are only going to find that out when one of the sub parses breaks.)
+ *
+ * @param element the element that is to be parsed next
+ * @return true if we find a schema declaration that matches
+ */
+ private boolean namespaceMatchesVersion(Element element) {
+ String schemaLocation = element.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
+ return schemaLocation.matches("(?m).*spring-batch-2.1.xsd.*")
+ || schemaLocation.matches("(?m).*spring-batch.xsd.*")
+ || !schemaLocation.matches("(?m).*spring-batch.*");
+ }
+
}
diff --git a/spring-batch-core/src/main/resources/META-INF/spring.schemas b/spring-batch-core/src/main/resources/META-INF/spring.schemas
index 63bf58424..17fec72a7 100644
--- a/spring-batch-core/src/main/resources/META-INF/spring.schemas
+++ b/spring-batch-core/src/main/resources/META-INF/spring.schemas
@@ -1,2 +1,3 @@
http\://www.springframework.org/schema/batch/spring-batch.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd
-http\://www.springframework.org/schema/batch/spring-batch-2.1.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd
\ No newline at end of file
+http\://www.springframework.org/schema/batch/spring-batch-2.1.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd
+http\://www.springframework.org/schema/batch/spring-batch-2.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.0-error.xsd
\ No newline at end of file
diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0-error.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0-error.xsd
new file mode 100644
index 000000000..2ec0ea03b
--- /dev/null
+++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0-error.xsd
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserExceptionTests.java
index 25600f80c..3c17970da 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserExceptionTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserExceptionTests.java
@@ -5,6 +5,7 @@ import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -48,4 +49,20 @@ public class JobParserExceptionTests {
}
}
+ @Test
+ public void testWrongSchemaInRoot() {
+ try {
+ new ClassPathXmlApplicationContext(
+ "org/springframework/batch/core/configuration/xml/JobParserWrongSchemaInRootTests-context.xml");
+ fail("Error expected");
+ }
+ catch (BeanDefinitionParsingException e) {
+ String message = e.getMessage();
+ assertTrue("Wrong message: "+message, message.matches("(?s).*You cannot use spring-batch-2.0.xsd.*"));
+ } catch (BeanDefinitionStoreException e) {
+ // Probably the internet is not available and the schema validation failed.
+ // We don't want an automated build to fail if that happens.
+ }
+ }
+
}
diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserWrongSchemaInRootTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserWrongSchemaInRootTests-context.xml
new file mode 100644
index 000000000..3da70a6d7
--- /dev/null
+++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserWrongSchemaInRootTests-context.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+