今天在按照配置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 slashtemplatePathLoader = 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中加入
TemplatePath /osgi/admin
程序就跑起来了。
其实TemplatePath不论填什么值程序都能过的去,要接着看一下是不是理解有误。