I had asked a question earlier regarding ExecutorService and Apache Velocity initialization. To give a quick recap -- I have a Java EE frontend which accepts user requests and then for each of these requests, uses ExecutorService(SingleThreadedExecutor set as a daemon) to kick off a lengthy workflow.This workflow is contained in a library and works well and as expected when run in a standalone mode through eclipse. When called from the website(servlet) I observed that the workflows were consistently getting hung at the point where the Velocity Engine was being initialized (Velocity.init() or ve.init()). Hence my aforementioned question.
When none of the answers/suggestions worked i inferred that this was something to do with the way Velocity started up and decided to shift to FreeMarker. Now i see that the workflow is getting hung in the exact same place for the FreeMarker implementation as well. This 'place' is the mail-building part which evaluates a template against a coupel of passed data objects and returns the mail string.The class that calls the Freemark'ing class and the FreeMark class are as follows --
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 class is as follows --
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();
}
}
Now, from my logging it looks like the worker thread hangs at the line
config=new Configuration()
Again, this works as expected in a standalone mode when run from eclipse but however hangs when called from the servlet using ExecutorService.
Im beginning to think/realize that this may have nothing to do with either of Velocity or FreeMarker and have something to do with ExecutorService. Any advice or suggestion would be of immense help.
Thanks
your code is not thread-safe since you are sharing
config
andtemplate
across all thread instances (and continuously re-setting them). the easiest way to make it thread safe would be to makeconfig
andtemplate
local variables in the method instead of static members. as @JBNizet pointed out in the comments, you have a similar problem inmailBuilder
witha
andb
. you might want to first check out some tutorials on object oriented programming fundamentals and then circle back to this issue (hint, in general you should avoid static member variables except for constants).