今天在按照http://www.ibm.com/developerworks/cn/web/1007_shaobing_flexosgi/index.html?ca=drs配置web项目时,发现按步骤配置好环境后,启动tomcat报以下错误


java.lang.NullPointerException
    org.apache.struts2.osgi.BundleFreemarkerManager.createTemplateLoader(BundleFreemarkerManager.java:52)
    org.apache.struts2.views.freemarker.FreemarkerManager.init(FreemarkerManager.java:292)
    org.apache.struts2.views.freemarker.FreemarkerManager.getConfiguration(FreemarkerManager.java:254)
    org.apache.struts2.views.freemarker.FreemarkerResult.getConfiguration(FreemarkerResult.java:235)
    org.apache.struts2.views.freemarker.FreemarkerResult.doExecute(FreemarkerResult.java:162)
    org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)



刷一下又会出现下列错误


java.io.FileNotFoundException: Template /osgi/admin/viewBundles.ftl not found.
    freemarker.template.Configuration.getTemplate(Configuration.java:580)
    freemarker.template.Configuration.getTemplate(Configuration.java:550)
    org.apache.struts2.views.freemarker.FreemarkerResult.doExecute(FreemarkerResult.java:173)
    org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)


先从第一问题开始找原因。

查看源码,找到

org.apache.struts2.osgi.BundleFreemarkerManager.createTemplateLoader

报错的地方为

try{
if(templatePath.startsWith("class://")) {
// substring(7) is intentional as we "reuse" the last slash
templatePathLoader = newClassTemplateLoader(getClass(), templatePath.substring(7));
} elseif(templatePath.startsWith("file://")) {
templatePathLoader = newFileTemplateLoader(newFile(URI.create(templatePath)));
}
} catch(IOException e) {
LOG.error("Invalid template path specified: "+ e.getMessage(), e);
}


这里templatePath为NULL,造成异常抛出。这个方法是在

org.apache.struts2.views.freemarker.FreemarkerManager.init

中调用,查看调用情况

// Process TemplatePath init-param out of order:
templatePath = servletContext.getInitParameter(INITPARAM_TEMPLATE_PATH);
if(templatePath == null) {
templatePath = servletContext.getInitParameter("templatePath");
}
config.setTemplateLoader(createTemplateLoader(servletContext, templatePath));

发现templatePath是从web.xml中的TemplatePath属性中拿取的,拿不到从templatePath中拿出,而两个地方都拿不到,就不再判断,调用templatePath.startsWith时就出现异常了。而在方法最后却又对TemplateLoader为NULL时制定了一个返回值,暂不明白为什么要这么设计。

找到问题改起来就容易多了

在web.xml中加入

<context-param>
        <param-name>TemplatePath</param-name>
        <param-value>/osgi/admin</param-value>
</context-param>

程序就跑起来了。

配置struts2.3.15+felix网站项目时遇到Template /osgi/admin/viewBundles.ftl not found解决方案_struts2.3.5 felix  a

其实TemplatePath不论填什么值程序都能过的去,要接着看一下是不是理解有误。