【问题标题】:Java Velocity engine initialization issueJava Velocity 引擎初始化问题
【发布时间】:2011-12-29 14:06:32
【问题描述】:

我编写了一个包含邮件构建部分的库。这个邮件构建部分使用了 Velocity。 mailbuilder类如下--

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

【问题讨论】:

    标签: java initialization velocity


    【解决方案1】:

    速度使用有两种模型:

    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()。
    • 您可以尝试在应用启动时进行一次初始化吗?
    • 尝试了单例方法并面临同样的问题,线程挂在 Velocity.init(prop)。我也尝试使用 ClasspathResourceLoader 的 FileResourceLoader 无济于事。我开始认为问题可能出在传递给 VelocityEngine 的 Properties 对象上。
    • 我会通过对进程的堆栈跟踪进行分析,以查看代码究竟挂在哪里。使用“jstack ”或 VisualVM 之类的工具来获取堆栈跟踪。
    【解决方案2】:

    这个问题是因为我的代码不是线程安全的。让它如此解决了这个问题。我仍然理解在 SingleThreadExecutor 用例中代码需要是线程安全的。 这就是导致答案的原因—— Issue when executing asynchronous tasks using ExecutorService

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 2014-03-16
      • 2012-07-07
      • 1970-01-01
      相关资源
      最近更新 更多