Проблема инициализации движка Java Velocity
У меня есть написанная библиотека, в которой есть часть создания почты. Эта часть создания почты использует 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, она дает ожидаемые результаты, и все выглядит хорошо. У меня есть веб-приложение, которое принимает запрос от пользовательского интерфейса и использует ExecutorService (newSingleThreadExecutor) для обслуживания этих пользовательских запросов один за другим в фоновом режиме.
Я замечаю, что мои звонки в вышеупомянутую библиотеку зависают в части создания почты, особенно в Velocity.init(props)
Исключений нет, но поток, кажется, зависает при инициализации VelocityEngine. Я посмотрел в Интернете, и мне не повезло с проблемой. Любая помощь в том, как проблема будет огромной.
Спасибо p1ng
2 ответа
Эта проблема была, потому что мой код не был потокобезопасным. Сделать это так, чтобы решить проблему. Я все еще понимаю необходимость того, чтобы код был потокобезопасным в случае использования SingleThreadExecutor. Вот что приводит к ответу - проблема при выполнении асинхронных задач с использованием ExecutorService
Есть две модели для использования скорости:
- Синглтон модель т.е.
Velocity.init(..)
здесь у вас есть только одна конфигурация скорости в вашем приложении. Вы должны вызывать init только один раз в этом случае при запуске приложения через прослушиватель или любой другой компонент инициализации. - В многомодельной стартовой версии 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() многопоточным способом, безусловно, должен иметь нежелательное поведение.