[Building Sakai] Using spring-mvc and free marker templates in a sakai tool
Jim Eng
jimeng at umich.edu
Mon Jul 22 11:17:21 PDT 2013
I'm having a problem. I hope someone has a suggestion. I am trying to write a sakai tool that will use freemarker templates to render views. I have defined web.xml to use the sakai ToolListener and ContextListener to get requests within the site. I am using sakai's RequestFilter to supply various context variables. With that servlet defined by web.xml, I am trying to use freemarker's view resolver to find templates. That all looks good to me, but when I deploy the tool into sakai, if fails with an error message saying a critical freemarker class cannot be found.
I think the problem is with the class loader. Some of the required spring support is in shared, and (of course) my app is in web apps.
I will show web.xml [1], the servlet file [2] and the error message from catalina.out when I try to load the first page [3]. I'll also show what's in the webapp war's /WEB-INF/lib/ folder [4].
I'd be glad to post other info or send it privately to avoid spamming this list.
Suggestions appreciated.
Jim
[1] web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Files</display-name>
<!-- Sakai Request Filter -->
<filter>
<filter-name>sakai.request</filter-name>
<filter-class>org.sakaiproject.util.RequestFilter</filter-class>
<!-- If you need to do uploads you will need this
<init-param>
<param-name>upload.enabled</param-name>
<param-value>true</param-value>
</init-param>
-->
</filter>
<filter-mapping>
<filter-name>sakai.request</filter-name>
<servlet-name>repo-tool</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<!-- This application's servlet class -->
<servlet>
<servlet-name>repo-tool</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>main-page</param-name>
<param-value>/index.html</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Sakai Tool Listener -->
<listener>
<listener-class>org.sakaiproject.util.ToolListener</listener-class>
</listener>
<!-- Sakai Spring Listener -->
<listener>
<listener-class>org.sakaiproject.util.ContextLoaderListener</listener-class>
</listener>
</web-app>
[2] repo-tool-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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="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">
<bean id="templateLoader" class="org.sakaiproject.repo.ftl.RepoTemplateLoader">
</bean>
<!-- freemarker config -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl"/>
</bean>
<!--
View resolvers can also be configured with ResourceBundles or XML files. If you need
different view resolving based on Locale, you have to use the resource bundle resolver.
-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value=""/>
<property name="suffix" value=".ftl"/>
</bean>
<context:component-scan
base-package="org.sakaiproject.repo.tool" />
</beans>
[3] Beginning of stack trace when trying to get to first page in the app:
org.sakaiproject.portal.api.PortalHandlerException: org.sakaiproject.tool.api.ToolException: javax.servlet.ServletException: Servlet.init() for servlet repo-tool threw exception
at org.sakaiproject.portal.charon.SkinnableCharonPortal.doGet(SkinnableCharonPortal.java:900)
caused by: org.sakaiproject.tool.api.ToolException: javax.servlet.ServletException: Servlet.init() for servlet repo-tool threw exception
at org.sakaiproject.portal.charon.SkinnableCharonPortal.forwardTool(SkinnableCharonPortal.java:1494)
caused by: javax.servlet.ServletException: Servlet.init() for servlet repo-tool threw exception
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1147)
caused by: java.lang.NoClassDefFoundError: freemarker/cache/TemplateLoader
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2437)
caused by: java.lang.ClassNotFoundException: freemarker.cache.TemplateLoader
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2437)
at java.lang.Class.getDeclaredConstructors(Class.java:1863)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:230)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:972)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:945)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1228)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1147)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:836)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:657)
[4] jars in /WEB-INF/lib:
$ ls -la ../webapps/repo/WEB-INF/lib/
total 4968
drwxr-xr-x 10 jimeng staff 340 Jul 22 14:03 .
drwxr-xr-x 9 jimeng staff 306 Jul 22 14:03 ..
-rw-r--r-- 1 jimeng staff 73098 May 23 2012 commons-codec-1.5.jar
-rw-r--r-- 1 jimeng staff 931168 Jun 25 19:23 freemarker-2.3.19.jar
-rw-r--r-- 1 jimeng staff 20682 May 23 2012 jstl-1.1.2.jar
-rw-r--r-- 1 jimeng staff 367444 May 23 2012 log4j-1.2.14.jar
-rw-r--r-- 1 jimeng staff 8391 Jun 25 19:20 sakai-jsp-adapter-0.10-K1.jar
-rw-r--r-- 1 jimeng staff 93500 Jul 19 13:58 sakai-kernel-util-1.4.0-20130718.171752-155.jar
-rw-r--r-- 1 jimeng staff 636659 Jul 5 12:33 spring-webmvc-3.2.3.RELEASE.jar
-rw-r--r-- 1 jimeng staff 393259 May 23 2012 standard-1.1.2.jar
$
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://collab.sakaiproject.org/pipermail/sakai-dev/attachments/20130722/6c8aa7cd/attachment.html
More information about the sakai-dev
mailing list