Java Velocity 引擎初始化问题

4

我编写了一个包含邮件生成部分的库。这个邮件生成部分使用了Velocity。邮件生成器类如下--

public class mailBuilder {
 public void initialize() throws Exception
    {
            Properties props = new Properties();

            log.info("About to set the ClassPath for Velocity specific tasks");
            props.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath");
            props.setProperty("classpath." + VelocityEngine.RESOURCE_LOADER + ".class", ClasspathResourceLoader.class.getName());

            try
            {
                log.info("Just before");
                Velocity.init(props);
                log.info("Just after");
            }
            catch ( Exception e )
            {
                log.error( "Caught Execption on velocityEngine init", e );
                throw new Exception( "Caught Execption on velocityEngine init", e );
            }
            log.info("Completed initializing Velocity Engine");

    }

public String returnMailstring() throws Exception {
initialize();
....
....
}

}

现在当我从eclipse运行和测试这个库时,结果与预期相符,一切看起来都很好。 我有一个Web应用程序,它从UI接收请求,并使用ExecutorService(newSingleThreadExecutor)在后台静默地逐个服务这些用户请求。
我注意到我的对上述库的调用在邮件构建部分特别是Velocity.init(props)处被挂起。没有异常抛出,但线程似乎在VelocityEngine初始化时挂起。我已经在线上进行了搜索,但没有找到解决问题的方法。 希望能得到关于如何解决这个问题的任何帮助。
谢谢, p1ng
2个回答

10

使用速度的两种模式:

  1. 单例模式,即Velocity.init(..),在这种情况下,您的应用程序中只有一个速度配置。您应该通过监听器或任何类型的初始化bean在应用程序启动时仅调用一次init。
  2. 自1.2版本开始的多模型,您可以使用多个配置来使用多个速度引擎。该模型如下所示:
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;

...


//  create a new instance of the engine
 VelocityEngine ve = new VelocityEngine();


//  configure the engine.  In this case, we are using
//  ourselves as a logger (see logging examples..)


ve.setProperty(
    VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this);

//  initialize the engine
ve.init();

...

Template t = ve.getTemplate("foo.vm");

只需选择您希望使用的模型并按照其进行操作。但以线程方式调用Velocity.init()肯定会产生不良行为。


我已经尝试过使用VelocityEngine对象进行工作。我得到了相同的结果,线程在ve.init()处挂起。 - ping
你能尝试在应用启动时进行单次初始化吗? - MahdeTo
尝试了单例模式,但遇到了相同的问题,线程在Velocity.init(prop)处挂起。我还尝试使用FileResourceLoader而不是ClasspathResourceLoader,但无济于事。我开始认为问题可能出在我传递给VelocityEngine的Properties对象上。 - ping
我会通过获取进程的堆栈跟踪来分析代码挂起的具体位置。使用“jstack <pid>”或类似VisualVM的工具来获取堆栈跟踪。 - centic

1
这个问题是因为我的代码不是线程安全的,使其线程安全后问题得到了解决。我仍在理解在SingleThreadExecutor使用情况下需要代码线程安全的原因。 这就是导致答案的原因 - 使用ExecutorService执行异步任务时出现问题

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接