【问题标题】:Velocity Throwing NPE when getting template获取模板时速度抛出 NPE
【发布时间】:2013-07-24 08:47:15
【问题描述】:

我有一些在本地运行良好的代码,但是当我尝试在远程服务器上运行它时,它会引发空指针异常。它在尝试从 Velocity 获取模板时这样做。它第一次失败,之后每次都失败。

有问题的代码是这样的:

    URL location = Thread.currentThread().getContextClassLoader().getResource("velocity.properties");
    String fullPath = location.getPath();
    log.debug("Path: " + fullPath);
    Velocity.init(fullPath);
    Template tmplt = Velocity.getTemplate( "template.html" );  //This line throws the error

日志显示路径正确,我可以验证文件是否存在。

用于初始化velocity的属性文件包含:

resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html
file.resource.loader.cache = true

input.encoding=UTF-8
output.encoding=UTF-8

错误的堆栈跟踪如下所示:

SEVERE: Servlet.service() for servlet Jersey REST Service threw exception
java.lang.NullPointerException
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
at org.apache.velocity.runtime.RuntimeSingleton.getTemplate(RuntimeSingleton.java:299)
at org.apache.velocity.app.Velocity.getTemplate(Velocity.java:358)
at ca.company.ipservice.models.MyClass.toHTML(MyClass.java:48)

我在 Google 上四处搜索并搜索了 StackOverflow,但找不到任何答案。有什么想法吗?

【问题讨论】:

  • 顺便说一句,我在多线程环境中使用 Velocity 并多次调用 init() 时遇到过类似的错误消息,但它在数百次执行中只出现一次,但似乎很少见竞争条件虽然 RuntimeInstance.init() 是同步的,所以不确定它是如何发生的......

标签: java apache tomcat jersey velocity


【解决方案1】:

属性file.resource.loader.path 应该指向一个目录。尝试将其设置为目录/var/lib/tomcat6/webapps/geoip/WEB-INF/templates

file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates

而不是

file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html

您似乎也有一个网络应用程序。在这种情况下,最好使用velocity tools 中的WebappResourceLoader

resource.loader = webapp
webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path = templates
webapp.resource.loader.cache = false

并在初始化之前设置 servlet 上下文属性

VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setApplicationAttribute("javax.servlet.ServletContext", context);

其中contextServletContext。目录 templates 应该位于您的 Web 根目录中,因此与 WEB-INF 位于同一位置。

编辑

如果您将应用程序打包成一个war 文件并将其部署到不解包它的应用服务器上,以便您可以直接访问文件系统,那么您可以考虑使用ClasspathResourceLoader。为此,您必须将模板打包到自己的 jar 文件中,然后将其放入WEb-INF/libgetTemplate(...) 的参数必须遵循检索位于类路径中的资源的规则(请参阅 ClassLoader#getResourceAsStream)。

resource.loader = classpath
classpath.resource.loader.description = Velocity Classpath Resource Loader
classpath.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
classpath.resource.loader.cache = false

Here你可以找到更多关于如何加载模板(又名资源)的信息。

【讨论】:

  • 我尝试了你所有的建议,它们在本地运行得很好。可悲的是,他们仍然无法在服务器上工作。不过感谢您的出色建议!
  • 感谢您的帮助!除了将此行添加到我的 velocity.properties 文件之外,使用您的建议可以让它在所有环境中工作!您的更改使我超越了初始错误到辅助速度记录错误,通过将其添加到属性中解决了该错误: 'runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem' 。非常感谢您的所有帮助,我真的很感激。它让我摆脱了束缚!
【解决方案2】:

我认为这段代码[1] 应该更健壮。当配置日志记录出现任何错误时,速度引擎最终会处于奇怪的状态,在您的应用程序的整个生命周期中,initialized=false 和 initializing=true。我也不确定为什么 Logging 比资源管理器先初始化。我正在考虑为项目打开一个错误。

[1]http://grepcode.com/file/repository.springsource.com/org.apache.velocity/com.springsource.org.apache.velocity/1.6.2/org/apache/velocity/runtime/RuntimeInstance.java#RuntimeInstance.init%28%29

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-20
    • 2019-01-06
    • 2021-01-19
    • 1970-01-01
    • 2018-09-17
    • 2018-01-02
    • 2020-11-05
    • 1970-01-01
    相关资源
    最近更新 更多