Memory leak tomcat 7 - memory-leaks

when I run my Tomcat 7 I get this error message :
Aug 04, 2015 12:53:47 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/sample] appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#5_Worker-9] but has failed to stop it. This is very likely to create a memory leak.

You should gracefully shutdown quartz within a ServletContextListener like this one:
public class AppListener implements ServletContextListener
{
#Override
public void contextDestroyed(ServletContextEvent arg0)
{
try
{
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
Scheduler scheduler = (Scheduler) context.getBean("quartzSchedulerFactory");
scheduler.shutdown(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void contextInitialized(ServletContextEvent arg0)
{
}
You have to add these ServletContextListener in your web.xml. You should place your listener at the first position in your web.xml because on tomcat runs the listeners in a reverse order on shutdown.
<listener>
<listener-class>yourpackage.AppListener</listener-class>
</listener>
Alternatively you could shutdown the scheduler within a method annotated with #PreDestroy

SchedulerFactoryBean has had a flag to tell it to wait for jobs to complete since at least Spring 3.0. Set the flag and make sure the destroy method will be called at shutdown:
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
destroy-method="destroy">
<property name="waitForJobsToCompleteOnShutdown" value="true" />
....
See: https://docs.spring.io/spring-framework/docs/3.0.0.RELEASE/javadoc-api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html#setWaitForJobsToCompleteOnShutdown(boolean)

Related

Capture and log / notify unhandled exceptions in a JSF based application

I would like to check and log all unhandled exceptions in my JSF web application using log4j. I read this post Log runtime Exceptions in Java using log4j and add a class that implements Thread.UncaughtExceptionHandler. but the method is not fired.
What is the correct way to achieve this?
add a class that implements Thread.UncaughtExceptionHandler. but the method is not fired
There's usually no means of an uncaught exception in the HTTP request thread managed by a Java EE web application as the server ultimately catches any exception coming from the web application and displays it in case of synchronous HTTP requests in a HTTP 500 error page (in case of asynchronous (ajax) requests, this is in turn framework-dependent). Moreover, if there was really an uncaught exception which escaped the server's attention, it would have killed the server's runtime thread causing the whole server to stop. This is clearly not an ideal real world scenario.
JSF offers you the ExceptionHandler API to get hand of those exceptions and if necessary control them.
Here's a kickoff example:
public class YourExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public YourExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public void handle() throws FacesException {
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException(); // There it is!
// Now do your thing with it. As per the question, you want to log it using log4j.
logger.error("An exception occurred!", exception);
}
getWrapped().handle();
}
#Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
In order to get it to run, create a custom ExceptionHandlerFactory as follows:
public class YourExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public YourExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
#Override
public ExceptionHandler getExceptionHandler() {
return new YourExceptionHandler(parent.getExceptionHandler());
}
}
Which needs to be registered in faces-config.xml as follows:
<factory>
<exception-handler-factory>com.example.YourExceptionHandlerFactory</exception-handler-factory>
</factory>
See also:
Exception handling in JSF ajax requests

AbortProcessingException leaves stack trace in server log, how to disable this?

There is a commandButton on a page that asynchronously invokes some service, and when user clicks a button I want to verify service availability by checking special config from database. This config can be updated every minute. So if the service is not available, action of commandButton should not be executed.
So, as per Differences between action and actionListener, I'm checking service availability in actionListener and throw AbortProcessingException in case service is not available. So action will be skipped.
This works fine, but it leaves a stack trace in server's log. I don't want such behavior. Is it possible to handle the exception in such way that this will not leave mark in server logs, just like when ValidatorException is thrown? I'm using OmniFaces FullAjaxExceptionHandler, if that's relevant.
You can suppress the logging with a custom exception handler. As you're currently using OmniFaces FullAjaxExceptionHandler, you'd better extend it. In the handle() method, check if there's an exception and if it's an instance of AbortProcessingException. If so, then just ignore it and return directly from the exception handler.
public class YourExceptionHandler extends FullAjaxExceptionHandler {
public YourExceptionHandler(ExceptionHandler wrapped) {
super(wrapped);
}
#Override
public void handle() throws FacesException {
Iterator<ExceptionQueuedEvent> events = getUnhandledExceptionQueuedEvents().iterator();
if (events.hasNext() && events.next().getContext().getException() instanceof AbortProcessingException) {
return; // Ignore (and don't log).
}
super.handle(); // Continue to FullAjaxExceptionHandler.
}
}
Create a factory around it:
public class YourExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory wrapped;
public YourExceptionHandlerFactory(ExceptionHandlerFactory wrapped) {
this.wrapped = wrapped;
}
#Override
public ExceptionHandler getExceptionHandler() {
return new YourExceptionHandler(getWrapped().getExceptionHandler());
}
#Override
public ExceptionHandlerFactory getWrapped() {
return wrapped;
}
}
In order to get this to run, register it as factory in faces-config.xml the usual way, replacing the FullAjaxExceptionHandlerFactory:
<factory>
<exception-handler-factory>com.example.YourExceptionHandlerFactory</exception-handler-factory>
</factory>

Access ApplicationScoped bean through ServletContext

I have an ApplicationScoped bean that I'd like to access in a quartz job implementation.
That bean holds a hashmap through run-time and I'd like to populate the hashmap when the job runs.
However, the FacesContext is out of context inside the job.
I have access to the ServletContext. Is it possible to access my bean through the ServletContext?
My code to access the Servlet Context:
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
SchedulerContext schedulerContext=null;
try {
schedulerContext=context.getScheduler().getContext();
}
catch (SchedulerException e) {
e.printStackTrace();
}
ServletContext servletContext=(ServletContext)schedulerContext.get("QuartzServletContext");
BOCacheM bOCacheM = (BOCacheM) servletContext.getAttribute("bOCacheM");
}
My QuartzServletContext is defined in web.xml as:
<context-param>
<param-name>quartz:scheduler-context-servlet-context-key</param-name>
<param-value>QuartzServletContext</param-value>
</context-param>
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
Yes, it's stored as an attribute in ServletContext. Obtain it like any other attribute:
YourApplicationScopedBean bean = servletContext.getAttribute("yourApplicationScopedBeanName");
//use it...
If bean is null then looks like your bean wasn't created when the quartz job started. Make sure the bean is created by adding eager=true to its definition:
#ManagedBean(eager=true)
#ApplicationScoped
public class YourApplicationScopedBean {
//...
#PostConstruct
public void init() {
//initialize your shared resources here...
}
}
Note that eager=true only applies for #ApplicationScoped beans.
If this still doesn't work, seems like your quartz job is being fired even before the bean is created and stored in the application context. It would be better to initialize this resource in the ServletContextListener rather than in an #ApplicationScoped bean and provide access to this resource through another component.

Can I look up a web app context url from a eager ApplicationScoped managed bean?

I want to get a web application context url (ex.: http://myserver:8080/myApp) and store it in the database at startup.
I know how to hook a method call in the startup by using: #ApplicationScoped combined with #ManagedBean(eager=true) and #PostConstruct
And ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath() will give me the context path.
However, since the method annotated with #PostConstruct is not being triggered by a request (since it's eager) getRequestContextPath() is giving me null.
As stated in your question, eager #ApplicationScoped bean cannot access to the context in #PostConstruct since there's no request-response cycle. Instead, use ServletContextListener to listen when the application is deployed/undeployed.
public class MyAppListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
//here the application has been deployed
ServletContext servletContext = sce.getServletContext();
String contextPath = servletContext.getContextPath();
//do what you want/need with context path
//...
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
//here the application is being undeployed
}
}
Then just configure the listener properly in web.xml
<listener>
<listener-class>the.package.of.your.MyAppListener</listener-class>
</listener>

Spring equivalent of CompletionService?

In my app I have to process multiple jobs asynchronously from the main application thread and collect the result of each job. I have a plain Java solution that does this using a ExecutorService and a ExecutorCompletionService that collects the job results.
Now I would like to convert my code to a Spring solution. The docs show me how the use the ExecutorService and the #Async annotation, but I am not sure how and if I can collect the results of multiple jobs.
In other words: I am looking for the Spring equivalent of the CompletionService. Is there such a thing?
My current code:
class MyService {
private static ExecutorService executorService;
private static CompletionService<String> taskCompletionService;
// static init block
static {
executorService = Executors.newFixedThreadPool(4);
taskCompletionService = new ExecutorCompletionService<String>(executorService);
// Create thread that keeps looking for results
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Future<String> future = taskCompletionService.take();
String s = future.get();
LOG.debug(s);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}).start();
}
// This method can and will be called multiple times,
// so multiple jobs are submitted to the completion service
public void solve(List<Long> ids) throws IOException, SolverException {
String data = createSolverData(ids);
taskCompletionService.submit(new SolverRunner(data, properties));
}
}
You need to consider what's your main goal, because your current code will work fine alongside other Spring-associated classes. Spring provides support for native Java ExecutorService as well as other popular 3rd party library such as Quartz
Probably what you're after is setting up the executor service on the spring container (eg: using following config on your spring beans xml)
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
And decorate your MyService class with #Service annotation and inject the reference to the executor service
I ended up defining my beans in the Spring application context and injection the completionservice into MyService. Works as a charm.
<task:executor id="solverExecutorService" pool-size="5" queue-capacity="100" />
<spring:bean id="solverCompletionService" class="nl.marktmonitor.solver.service.SolverCompletionService" scope="singleton">
<constructor-arg name="executor" ref="solverExecutorService"/>
</spring:bean>

Resources