简体   繁体   English

使用速度,发生“ java.lang.NullPointerException”

[英]use velocity ,occur “java.lang.NullPointerException”

( version :velocity-1.7,commons-collections-3.2) 版本 :velocity-1.7,commons-collections-3.2)

I use velocity to parse vm template,and set value in request scope ,show in jsp 我使用速度来解析vm模板,并在request范围内设置值,在jsp中显示

My app work normaly a period of time , but When users access a period of time after, this jsp show error,cannot access 我的应用work normaly a period of time ,但是当用户访问一段时间后,此jsp显示错误,无法访问

here is log : 这是日志

Mar 8, 2013 11:40:54 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet spring threw exception
java.lang.NullPointerException
    at org.apache.commons.collections.ExtendedProperties.clearProperty(ExtendedProperties.java:797)
    at org.apache.commons.collections.ExtendedProperties.setProperty(ExtendedProperties.java:722)
    at org.apache.commons.collections.ExtendedProperties.combine(ExtendedProperties.java:783)
    at org.apache.velocity.runtime.RuntimeInstance.setProperties(RuntimeInstance.java:657)
    at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:645)
    at org.apache.velocity.runtime.RuntimeSingleton.init(RuntimeSingleton.java:226)
    at org.apache.velocity.app.Velocity.init(Velocity.java:97)
    at com.feilong.tools.velocity.VelocityUtil.parseVMTemplateWithClasspathResourceLoader(VelocityUtil.java:67)
    at com.feilong.taglib.display.pager.PagerUtil.getPagerContent(PagerUtil.java:107)
    at com.feilong.taglib.display.pager.PagerTag.writeContent(PagerTag.java:48)
    at com.feilong.taglib.display.pager.PagerTag.writeContent(PagerTag.java:13)
    at com.feilong.taglib.base.AbstractCommonTag.doStartTag(AbstractCommonTag.java:19)
    at org.apache.jsp.pages.product.product_005flist_jsp._jspx_meth_feilongDisplay_005fpager_005f0(product_005flist_jsp.java:762)
    at org.apache.jsp.pages.product.product_005flist_jsp._jspx_meth_c_005fotherwise_005f1(product_005flist_jsp.java:433)
    at org.apache.jsp.pages.product.product_005flist_jsp._jspx_meth_c_005fchoose_005f1(product_005flist_jsp.java:243)
    at org.apache.jsp.pages.product.product_005flist_jsp._jspService(product_005flist_jsp.java:116)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

here is my util codes : (two public method:sometimes i use to parse vm template ,sometimes i use to parse string) 这是我的效用代码 :(两个公共方法:有时我用来解析虚拟机模板,有时我用来解析字符串)

/**
 * VelocityUtil
 * 
 * @author feilong
  */
public final class VelocityUtil{

    private static String   RUNTIME_LOG_LOG4J_LOGGER        = "feilongVelocityLogger";

    private static String   RUNTIME_LOG_LOG4J_LOGGER_LEVEL  = "debug";

    public static String parseVMTemplateWithClasspathResourceLoader(String templateInClassPath,Map<String, Object> contextKeyValues){
        String resource_loader = "class";
        Properties properties = new Properties();
        properties.put(Velocity.RESOURCE_LOADER, resource_loader);
        properties.put(resource_loader + ".resource.loader.class", ClasspathResourceLoader.class.getName());
        properties.put(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
        properties.put(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER, RUNTIME_LOG_LOG4J_LOGGER);
        properties.put(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER_LEVEL, RUNTIME_LOG_LOG4J_LOGGER_LEVEL);
        properties.put(Velocity.INPUT_ENCODING, CharsetType.UTF8);
        properties.put(Velocity.OUTPUT_ENCODING, CharsetType.UTF8);

        Velocity.init(properties);
        return parseVMTemplateAfterInitVelocity(templateInClassPath, contextKeyValues);
    }


    public static String parseVMContentWithStringResourceLoader(String vmContent,Map<String, Object> contextKeyValues){
        String resource_loader = "string";
        Properties properties = new Properties();
        properties.put(Velocity.RESOURCE_LOADER, resource_loader);
        properties.put(resource_loader + ".resource.loader.class", StringResourceLoader.class.getName());
        properties.put(Velocity.INPUT_ENCODING, CharsetType.UTF8);
        properties.put(Velocity.OUTPUT_ENCODING, CharsetType.UTF8);

        Velocity.init(properties);

        String templateName = "feilongStringVelocity";
        StringResourceRepository stringResourceRepository = StringResourceLoader.getRepository();
        stringResourceRepository.putStringResource(templateName, vmContent);
        return parseVMTemplateAfterInitVelocity(templateName, contextKeyValues);
    }


    private static String parseVMTemplateAfterInitVelocity(String templateName,Map<String, Object> contextKeyValues){
        Template template = Velocity.getTemplate(templateName, CharsetType.UTF8);
        VelocityContext velocityContext = new VelocityContext();
        if (null != contextKeyValues){
            for (Map.Entry<String, Object> entry : contextKeyValues.entrySet()){
                velocityContext.put(entry.getKey(), entry.getValue());
            }
        }
        Writer writer = new StringWriter();
        template.merge(velocityContext, writer);
        try{
            writer.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
        return writer.toString();
    }
}

If you are initializing Velocity every time you render the jsp (and it looks like you are from the code you posted) this could be the issue. 如果每次渲染jsp时都要初始化Velocity(看起来就像是来自发布的代码),则可能是问题所在。

I've had this issue before and resolved it by initializing the VelocityEngine once and storing it for future use. 我以前遇到过此问题,并通过一次初始化VelocityEngine并将其存储以供将来使用来解决它。

Taken from here (credit to 'Will Glass-Husain-2' from the Velocity forum on nabble.com): 此处获取 (nabble.com上Velocity论坛上的“ Will Glass-Husain-2”信用):

Here's the general pattern. 这是一般模式。 On app start up, initialize a VelocityEngine. 在应用启动时,初始化VelocityEngine。 Store it somewhere. 存放在某个地方。 Every time you need to process a template, get the template, create and populate a context, using the velocity engine merge the template (with the context). 每次需要处理模板时,请使用速度引擎将模板(与上下文)合并,以获取模板,创建并填充上下文。

In your code above, you could try moving the Velocity.init call to another method (called initialize, for example) which only gets called on first use of a method in your utils class. 在上面的代码中,您可以尝试将Velocity.init调用移至另一个方法(例如,称为initialize),该方法仅在utils类中首次使用该方法时才被调用。 After initialize is called once, store that in a boolean and don't call initialize again. 初始化调用一次后,将其存储在布尔值中,不要再次调用初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM