83

I am new to Spring. One thing confuses me is that sometimes I see XML configuration files with versioned schemas, yet sometimes with non-versioned ones. For example, sometimes I see something like

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
     <context:annotation-config/>
     <context:component-scan base-package="base.package"/>
    
</beans>

And sometimes like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:annotation-config/>
    <context:component-scan base-package="base.package"/>
    
</beans>

Note that the spring-beans and spring-context schemas are different in these two examples.

So, my question is, which style would you use and why? In particular, will the versioned schema become unavailable in the future, and will the non-versioned schema keep compatible with a current application when Spring updates the schema?

A side question is, where can I find a list of the versioned spring schemas?

SternK
  • 11,649
  • 22
  • 32
  • 46
JBT
  • 8,498
  • 18
  • 65
  • 104

6 Answers6

108

It is recommended to use the "versionless" XSDs, because they're mapped to the current version of the framework you're using in your application.

Applications and tools should never try to fetch those XSDs from the web, since those schemas are included in the JARs. If they do, it usually means your app is trying to use a XSD that is more recent than the framework version you're using, or that your IDE/tool is not properly configured.

To my knowledge, there's only one case where you'd want to use specific XSD versions: when trying to use a XML attribute that's been deprecated/modified in a more recent version. That doesn't happen often to say the least.

Anyway the Spring team should drop the versioned schemas for Spring 5.0, see SPR-13499.

More on "versionless == current version":

Those XSD files are included in Spring JARs - the "versionless" XSD is mapped to the latest version during the build (see the spring.schemas files that actually make that link). Also, the files available online are built the same way (see the "schemaZip" target in the gradle build).

Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
  • As we know, the information in the schemaLocation is provided as a "hint" to the xml processor. So when the xml processor analyze the xml it will find the xsd file accords to the spring.schemas definition. But one thing that I can't understand, for the xml editor, if we define the schemaLocation, it will auto complete when we type, so how it knows? It also references the definition in the spring.schemas? Or download the xsd file from remote server? If download the file from remote server, that say, if we don't specify the version, it references the latest version. – Rocky Hu Jan 25 '16 at 02:47
  • One case may occurs, if it downloads the file from remote server, so the xsd always be the latest version, so if a element be defined in the latest version but not the version which our project used(lower version), what will happened? The xml processor loads the xsd from the local jar, and can't recognize the element definition. – Rocky Hu Jan 25 '16 at 02:52
  • I have encountered a [situation](https://stackoverflow.com/questions/45957578/http-404-conflict-between-spring-security-url-filter-and-dispatcher-servlet-ur/45962007?noredirect=1#comment78896065_45962007) where versions caused me a HTTP 404... I mean after removing versions it worked fine. Do you know why ? – Bloomberg58 Aug 31 '17 at 22:10
  • I am not able to make sure eclipse 09-2018 won't ever fetch Spring schemas from web. As online `Spring Integration` XSDs without version in URL are of ancient version 1.0, this leads to sporadic error markers in my XMLs within Eclipse editor. See the `important note` in online XSD here: http://www.springframework.org/schema/integration/spring-integration.xsd or here: http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd – Selaron Dec 11 '18 at 10:33
4

I am not sure if their is a guidance, but my personal preference is to refer to the non-versioned schemas - in general if you are working against the more recent versions of the Spring projects(Spring core, integration etc), then you can refer to the unversioned schemas.

The unversioned schemas point to the latest version of the projects so it is possible that they may not be the correct grammar if you are using really old version of Spring (say version 2.5 against currently released 4.0 version), in such cases it may be better to point to the versioned schemas.

One more point to make here is that if possible it is better to avoid xml altogether and go with Java based @Configuration style to configure your Spring beans.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
1

I know that the question is over two years old, but my take is to proceed with caution.

In my case I was developing a stand-alone CLI tool, a jar of jars. And when my declared XSDs were versionless(sic), I would notice very strange errors. Consider the following xml fragment:

enter image description here

Without the versions, the value-separator attribute in the property placeholder will cause the following error:

org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 22 in XML document from class path resource [META-INF/slitools/sli-cli-applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'value-separator' is not allowed to appear in element 'context:property-placeholder'.
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:399)

One could try to see what on earth is being pulled via transitive dependencies (even though careful inspection showed we were pulling the right jars containing the right xsds (and ensured we were doing the right property merging with the shade plugin when we were building the uber-jars.)

Obviously YMMV. If it works for one project, the better. But if you ever start seeing strange errors that defy explanation and you do not have the bandwidth to chase them down to the root cause, better to be precise.

The counter-argument of this is that if you ever change the version of your spring dependencies, you need to make sure the explicit xsd version are correct. In software, it is all about trade-offs (and knowing what you get into with your decisions.)

luis.espinal
  • 10,331
  • 6
  • 39
  • 55
  • Good Point. I was thinking the same that configuration declared considering the lower version might break on higher versions. – Ankit Feb 01 '17 at 11:51
1

I have enroled for spring course on udemy. I followed every step that my instructor show me to do. So if you are using spring mvc and hibernate you may encounter this error Failed to read schema document 'http://www.springframework.org/schema/tx/spring-tx.xsd' etc for:

<mvc:annotation-driven/> and <tx:annotation-driven transaction-manager="myTransactionManager" /> elements

in my spring configuration file i had these two urls

    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd

    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd

in xsi:schemaLocation, which i replaced with

    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd

    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd

actually i visited these two sites http://www.springframework.org/schema/mvc/ and http://www.springframework.org/schema/tx/ and just added the latest version of spring-mvc and spring-tx i.e, spring-mvc-4.2.xsd and spring-tx-4.2.xsd

So, in my opinion specifying version no explicitly is a good practice. Hope this helps. Thank you.

Shafqat Shafi
  • 1,108
  • 17
  • 30
0

You will find META-INF/spring.schemas file in your Jar. That file defines all compatible xsd versions. If you point to URL without any version number, by default it would be compatible with your Jar file. As far as you don't have two different version of spring jar in classpath, your application will not have any runtime errors.

0

Consider using versionless xsd's. This will make the tooling pick up the version of the xsd matching the version of the spring jar you are using(look at the spring.schemas file in your jar). In case of any incompatibility when you upgrade your spring libraries(which should really be rare) you should be able to catch it during build.

This will provide an opportunity to decide whether there is a need to introduce versioned xsd for that one file or actually evolve from using an archaic and deprecated attribute/element. Hopefully it will be the later.

Else the risk is of using a possible deprecated attribute/element forever.

Abhijith Madhav
  • 2,748
  • 5
  • 33
  • 44