Spring MVC and Tiles Integration Issue

6.4k Views Asked by At

I am trying to create a simple Spring 3 MVC app with tiles integration.

When I try to build the app I get this error message (truncated for brevity):

java.lang.NullPointerException
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:1058)
at org.apache.commons.digester.Digester.parse(Digester.java:1887)
at org.apache.tiles.definition.digester.DigesterDefinitionsReader.read(DigesterDefinitionsReader.java:329)
at org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO.loadDefinitionsFromURL(BaseLocaleUrlDefinitionDAO.java:276)
at org.apache.tiles.definition.dao.CachingLocaleUrlDefinitionDAO.loadDefinitionsFromURLs(CachingLocaleUrlDefinitionDAO.java:251)

Am I missing some required library?

I have the following jars in WEB-INF/lib folder.

commons-beanutils-1.8.0.jar
commons-digester-2.0.jar

org.springframework.asm-3.1.1.RELEASE.jar
org.springframework.beans-3.1.1.RELEASE.jar
org.springframework.context-3.1.1.RELEASE.jar
org.springframework.core-3.1.1.RELEASE.jar
org.springframework.expression-3.1.1.RELEASE.jar
org.springframework.web.servlet-3.1.1.RELEASE.jar
org.springframework.web-3.1.1.RELEASE.jar
tiles-api-2.2.2.jar
tiles-core-2.2.2.jar
tiles-jsp-2.2.2.jar
tiles-servlet-2.2.2.jar
tiles-template-2.2.2.jar
log4j-1.2.16.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar

WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>SpringMVC</display-name>
  <servlet>
<servlet-name>spring</servlet-name>  
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>  
</servlet>

<servlet-mapping>  
<servlet-name>spring</servlet-name>  
<url-pattern>*.html</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

WEB-INF/spring-servlet.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Scans within the base package of the application for @Components to configure as beans -->
<!-- @Controller, @Service, @Configuration, etc. -->
<context:component-scan base-package="xyz.sample.baremvc" />

<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean> 

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>

WEB-INF/tiles.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC 
 "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" 
 "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
    <definition name="base.definition" template="/WEB-INF/views/layout.jsp">
    <put-attribute name="title" value="" />
    <put-attribute name="header" value="/WEB-INF/views/header.jsp" />
    <put-attribute name="menu" value="/WEB-INF/views/menu.jsp" />
    <put-attribute name="body" value="" />
    <put-attribute name="footer" value="/WEB-INF/views/footer.jsp" />
    </definition>

    <definition name="contact" extends="base.definition">
    <put-attribute name="title" value="Contact Manager" />
    <put-attribute name="body" value="/WEB-INF/views/contact.jsp" />
    </definition>
</tiles-definitions>

Thanks

3

There are 3 best solutions below

2
On

use commons-digester-1.8.jar with tiles 2.2.2, the version 2.0 of commons-digester is buggy regarding sax.

Edit: extra of the pom I used to solve the issue it's to solve the initial http request which is a know issue (note i am using the jdk 1.6) here is an extra of my pom to make it work:

        <!-- Note: tiles 2.2 uses commons-digester 2.0 which is buggy with sax 
            (http request will fail the first time) using version 1.8 to solve the issue -->
        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-servlet</artifactId>
            <version>${apacheTiles.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-digester</groupId>
                    <artifactId>commons-digester</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>${apacheTiles.version}</version>
        </dependency>

with ${apacheTiles.version} being 2.2.2 and the version of spring being 3.0.5.RELEASE

2
On

I am assuming the com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl is being referred from a third party library. Make sure it is being referred from Sun's jre library.

If you are using maven, try excluding any unwanted libraries from class path.

or refer to this post

EDIT:

Look at this piece of code from org.apache.commons.digester.parser.XercesParser

 public static SAXParser newSAXParser(Properties properties) 
        throws ParserConfigurationException, 
              SAXException,
               SAXNotSupportedException {

   SAXParserFactory factory =  
                    (SAXParserFactory)properties.get("SAXParserFactory");

    if (versionNumber == null){
      versionNumber = getXercesVersion();
        version = new Float( versionNumber ).floatValue();
   }

   // Note: 2.2 is completely broken (with XML Schema). 
    if (version > 2.1) {

       configureXerces(factory);
       return factory.newSAXParser();
   } else {
        SAXParser parser = factory.newSAXParser();
       configureOldXerces(parser,properties);
       return parser;
    }
   }
1
On

replace commons-digestor-2.0 with commons-digestor-1.7 for tiles 2.2.2 to resolve this issue.