Saturday, August 8, 2015

cvc-elt.1: Cannot find the declaration of element 'beans'-Part1

Generally when working with spring applications,we get the exception cvc-elt.1: Cannot find the declaration of element 'beans'.There are various reasons for this.Usually we get the exception when we run this application in a machine where internet connection is not there.Now we identify some of the cases here and find out the root cause for this.And steps to take to avoid this exception.

To know what the error exactly is we need to know some more terms and definitions.Let's starts with an sample configuration that is a part of the application context.

Sample xml configuration:


<?xml version="1.0" encoding="UTF-8"?>

&ltbeans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

    xmlns:task="http://www.springframework.org/schema/task" 

    xsi:schemaLocation="http://www.springframework.org/schema/beans 

                    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

                    http://www.springframework.org/schema/task

                    http://www.springframework.org/schema/task/spring-task-3.1.xsd

                  http://www.springframework.org/schema/context

                  http://www.springframework.org/schema/context/spring-context-3.1.xsd ">

Xml Namespace:

We can say an XML namespace declaration is a key-value pair.The key part of  the  XML namespace is declared using the reserved XML attribute xmlns or xmlns:prefix  and the value part is a URI(Uniform Resource Identifier). Here key part is called namespace prefix and value part is called namespace URI.
Let's analyze some examples of  XML namespace.

Let's consider the second line of the above xml snippet.

 xmlns:beans="http://www.springframework.org/schema/beans"
The above line defines a XML namespace.In our example here  "bean" is the namespace prefix which is a key part and  "http://www.springframework.org/schema/beans" is the namespace URI , which is the value part.

Similary in line

xmlns:context="http://www.springframework.org/schema/context"

"context" is the namespace prefix which is a key part and  "http://www.springframework.org/schema/context"  is the namespace URI , which is the value part.

Similarly in line

xmlns:security="http://www.springframework.org/schema/security"

 "security" is the namespace prefix which is a key part and  "http://www.springframework.org/schema/security"   is the namespace URI , which is the value part.

Ideas behind use of xml namespace:

1.XML namespace is used to group together elements having a common idea.
2.And to distinguish between different  elements  having the same name featuring different semantics.

For example consider a student having name and roll no and some other fields and the college  having name and location and some other fields.How can we distinguish here the name element,as name is available for both the tags student and college?For example

<student>
    <name>Alok</name>
    <rollno>17</rollno>
    <college>
        <name>DKL</name>
        <location>Delhi</location>
    </college>
</student>

We can distinguish between them by creating two unique namespace declaration for each.

Here

<studentxml:student 
xmlns:studentxml="http://www.my.student.com/xml/student" 
xmlns:collegexml="http://www.my.college.com/xml/college">
    <studentxml:name>Alok </studentxml:name>
    <studentxml:rollno>17 </studentxml:rollno>
    <collegexml:college>
        <collegexml:name>DKL</collegexml:name>
        <cityxml:locatio>Delhi</collegexml:location>
        </collegexml:college>
</studentxml:student>
Now there is no ambiguity between two name elements.So in our example xmlns:beans="http://www.springframework.org/schema/beans"  the namespace prefix is beans and namespace URI is http://www.springframework.org/schema/beans.
We can think of namespace prefix  is a short name(or can say an alias) for the complete namespace uri.
Any element or attribute whose name starts with the prefix "beans:" is considered to be in the beans namespace.
Also it is possible to declare a default namespace. This default namespace is like to declare a complete namespace uri without a namespace prefix as follows.
xmlns="http://www.springframework.org/schema/beans"
you can see this line is same as the second line of  the heading sample xml configuration.
In this case, any element without a namespace prefix is considered to be in the beans namespace.

Attributes are never come under the umbrella of  the default namespace. An attribute without an explicit namespace prefix is considered not to be in any namespace.

 By the time we have got a fair understanding of namespace prefix and namespace uri.Now we proceed  to the exception of type 1.

Exception Category 1:

 If we define the namepace prefix and namespace uri in below manner like

<?xml version="1.0" encoding="UTF-8"?>
&ltbeans xmlns:beans="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:task="http://www.springframework.org/schema/task"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                   http://www.springframework.org/schema/task
                  http://www.springframework.org/schema/task/spring-task-3.1.xsd
                 http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.1.xsd ">

                   <!-- some more bean declarations goes here -->
       </beans>
We will get the below exception.

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 11 in XML document from class path resource [META-INF/spring/app-context.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 78; cvc-elt.1: Cannot find the declaration of element 'beans'.
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
    at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
    at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:527)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:441)
    at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
    at com.one97.EsmeSimulator.Main.MainClass.main(MainClass.java:8)
Caused by: org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 78; cvc-elt.1: Cannot find the declaration of element 'beans'.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
    ... 14 more

Solution to the Exception Category 1:

Notice here in line no 2 of the namespace declaration, we declare the namespace prefix like
beans xmlns:beans="http://www.springframework.org/schema/beans"
Here we have bounded the relevant namespace uri to a prefix.But we are using the beans tag like.
  </beans>.Here we are using an unprefixed name for the beans element.

This problem has two solutions

solution:1 

Since the uri here is prefixed with namespace prefix bean,so we need to prefix the beans element as 
</beans:beans>.And also we need to do this for all the child elements of bean elements.

solution:2 

As  discussed above , we can declare the beans element as default namespace without any namespace prefix as follows
 beans xmlns="http://www.springframework.org/schema/beans" 
Then no need to add the prefix for beans element and for all it's child elements.

If you find it useful, please follow  the part 2 of the series  to find solutions for this kind of exceptions

2 comments: