Harshit
Harshit

Reputation: 5157

Spring Web MVC Tiles exception

I am trying to use tiles library in my Spring MVC project. Here is the code:

wel-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd"
    xmlns:mvc="http://www.springframework.org/schema/mvc">

    <context:annotation-config />
    <context:component-scan base-package="com.smart" />
    <mvc:annotation-driven />
    <tx:annotation-driven transaction-manager="myTransactionManager" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/view/" />
        <property name="suffix" value=".jsp" />
    </bean>


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

</beans>

tiles.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">

<tiles-definitions>
    <definition name="base.definition" template="/view/home.jsp">
        <put-attribute name="header" value="/view/header.jsp" />
    </definition>
</tiles-definitions>

home.jsp

<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>

<tiles:insertAttribute name="header" ignore="true" />

Error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tilesConfigurer' defined in ServletContext resource [/WEB-INF/welcome-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:664)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:630)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:678)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:549)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:490)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:744)

root cause

java.lang.NoClassDefFoundError: org/springframework/web/servlet/view/tiles3/SpringWildcardServletTilesApplicationContext
    org.springframework.web.servlet.view.tiles3.TilesConfigurer.afterPropertiesSet(TilesConfigurer.java:267)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:664)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:630)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:678)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:549)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:490)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:744)

Tiles Libraries used

tiles-core-3.0.5.jar
tiles-request-api-1.0.6.jar
tiles-api-3.0.5.jar
tiles-jsp-3.0.5.jar
commons-beanutils-1.8.0.jar
commons-digester-2.0.jar

I am using Spring MVC 4.

How to solve this problem?

Upvotes: 0

Views: 1911

Answers (1)

QGA
QGA

Reputation: 3192

First of all you cannot have two resolvers when using tiles. Please remove the code below from your configuration

   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/view/" />
        <property name="suffix" value=".jsp" />
    </bean>

This conflicts with apache tiles since it does the rendering of your definitions as defined in your tiles.xml file.

Regarding the initialization of tiles you are still using a mix of apache tiles 2 and 3

Please change the configuration to be as follow

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

Finally, in order to use apache tiles you need to have two components:

  • A base definition which defines a website template
  • A list of pages that extend the defined template

Therefore if we assume for a second that the following definition represents your template

<definition name="base.definition" template="/view/template.jsp">
    <put-attribute name="header" value="/view/header.jsp" />
    <put-attribute name="body" value="/view/body.jsp" />
    <put-attribute name="footer" value="/view/footer.jsp" />
</definition>

You can now create pages that extend your template

For instance let's assume you want a page called home that inherites the same layout from the template called base.definition. In this case you need to create a new definition as below

<definition name="home" extends="base.definition">
        <put-attribute name="body" value="/view/home.jsp" />
</definition>

As you can see I have overridden the body definition so the page home will have header and footer of the basic template and the body contained in the home.jsp page

Of course you need to give a structure to your template as explained in the documentation here

Hope this is of help

Upvotes: 1

Related Questions