0

以前 、ExecutorServiceとApacheVelocityの初期化について質問しました。簡単に要約すると、ユーザーリクエストを受け入れるJava EEフロントエンドがあり、これらのリクエストごとに、ExecutorService(デーモンとして設定されたSingleThreadedExecutor)を使用して、長いワークフローを開始します。このワークフローはライブラリに含まれており、機能します。 Eclipseを介してスタンドアロンモードで実行すると、予想どおりになります。Webサイト(サーブレット)から呼び出されたとき、Velocity Engineが初期化されている時点(Velocity.init()またはve.init())でワークフローが一貫してハングしていることを確認しました。したがって、私の前述の質問。

答えや提案がうまくいかなかったとき、これはVelocityの起動方法と関係があると推測し、FreeMarkerに移行することにしました。これで、FreeMarkerの実装でもワークフローがまったく同じ場所でハングしていることがわかります。この「場所」は、渡されたデータオブジェクトのクーペルに対してテンプレートを評価し、メール文字列を返すメール作成部分です。Freemark'ingクラスとFreeMarkクラスを呼び出すクラスは次のとおりです。

   public class mailBuilder {

    private static final Logger log = Logger.getLogger( mailBuilder.class );    
    static String a;
    static String b;

    public mailBuilder(CustomDataStructure input)
    {
        a = input.getA();
        b = input.getB(); 
    }
    public static String returnMailstring() throws Exception
    {
        log.info("Gathering elements to construct email.");
        String mailText=null;
        Map context = new HashMap();
        context.put("a",a);
        context.put("b",b);
        log.info("Calling Freemarker");
        mailText=FreeMarkIT.ReturnReportString(context);
        log.info("Freeemarker returned string");

        return mailText;
    }
}

FreeMarkITクラスは次のとおりです-

    public class FreeMarkIT {
        private static final Logger log = Logger.getLogger( FreeMarkIT.class );
        private static Configuration config;
        private static Template template;

        public static String ReturnReportString(Map model) throws IOException, TemplateException
        {
            StringWriter sw = new StringWriter();
            try 
            {
               log.info("Going to get the template");
               config= new Configuration();
               log.info("Now really");
               template=config.getTemplate("src/resource/email_template.vm");
               log.info("Done initializing template");
               template.process(model, sw);
               sw.flush();
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
            }

            return sw.getBuffer().toString();
        }
    }

さて、私のロギングから、ワーカースレッドが行にぶら下がっているように見えます config=new Configuration()

繰り返しますが、これはEclipseから実行するとスタンドアロンモードで期待どおりに機能しますが、ExecutorServiceを使用してサーブレットから呼び出されるとハングします。

これはVelocityまたはFreeMarkerのいずれとも関係がなく、ExecutorServiceと関係がある可能性があることを考え始めています。アドバイスや提案は非常に役立ちます。

ありがとう

4

1 に答える 1

3

あなたのコードはスレッドセーフではありません。なぜなら、あなたはすべてのスレッドインスタンスを共有configtemplateている (そしてそれらを継続的に再設定している) からです。スレッドセーフにする最も簡単な方法は、静的メンバーの代わりにメソッド内でローカル変数configを作成することです。template@JBNizet がコメントで指摘したように、 と で同様の問題がmailBuilderありaますb。最初にオブジェクト指向プログラミングの基礎に関するいくつかのチュートリアルを確認してから、この問題に戻ることをお勧めします (ヒント、通常、定数以外の静的メンバー変数は避ける必要があります)。

于 2012-01-01T14:00:00.817 に答える