2011-12-29 33 views
4

私はmailbuildingの部分を持つライブラリを書いてあります。この郵便物はVelocityを使用しています。私は実行し、日食からであるとして、このライブラリをテストするときには結果が期待されているように、今Java 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(); 
.... 
.... 
} 

} 

と物事は罰金だ - 次のようにmailbuilderクラスです。 私は、UIからのリクエストを受け取り、ExecutorService(newSingleThreadExecutor)を使ってこれらのユーザーリクエストをバックグラウンドで1つずつ静かに処理するWebアプリケーションを持っています。

私は前述のライブラリへの呼び出しがmailbuildingの部分に特に掛かっていることに気付いています。Velocity.init(props)例外はスローされませんが、VelocityEngineの初期化時にスレッドがハングアップしているようです。 私はオンラインで検索し、問題の可能性はありませんでした。 問題がどのように巨大になるかについてのヘルプ。速度の使用のための2つのモデルがあります

答えて

1

この問題は、コードがスレッドセーフではなかったためです。問題をそれほど修正しました。 SingleThreadExecutorユースケースでコードがスレッドセーフである必要性をまだ理解しています。 これは、答えにつながるものです。 Issue when executing asynchronous tasks using ExecutorService

9

おかげ p1ng:

  1. シングルトンモデル、すなわちVelocity.init(..)は、ここにあなたのアプリで唯一の単一速度の構成を有しています。この場合、アプリケーションの起動時にリスナーまたは任意の種類の初期化Beanを介してinitを1回だけ呼び出す必要があります。
  2. マルチモデルの出発バージョン1.2
  3. あなたはモデルのような使用されている複数の構成を使用して、複数の速度エンジンを持つことができます。
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()を呼び出すことは、望ましくない動作をするはずです。

+0

私は既にVelocityEngineの問題を扱っています。同じ結果が得られ、ve.init()にスレッドがぶら下がっています。 – ping

+0

アプリの起動時に1回の初期化を試すことができますか? – MahdeTo

+0

シングルトンアプローチを試みて、同じ問題に直面したとき、スレッドはVelocity.init(prop)にぶら下がっていました。私はまた、ClasspathResourceLoaderのInstaed FileResourceLoaderを使用して無駄にしようとしました。 VelocityEngineに渡すPropertiesオブジェクトに問題があると考え始めました。 – ping