Web app and Tomcat 7 Memory Leak - java

I am (test) running my web app in Tomcat 7 and using their "Find Leak" button and of course it complains about memory leak when I stop / undeploy.
The following web applications were stopped (reloaded, undeployed),
but their classes from previous runs are still loaded in memory, thus
causing a memory leak (use a profiler to confirm):
/LeakyWebApp
So I used Java VisualVM (my first time trying this out)
on Tomcat startup with no deployment:
http://img15.imageshack.us/img15/4441/tomcatstartup.jpg
My web app involves:
Quartz 1.8.5
Hibernate 3.6.3
JAXB 2.2.4
Salesforce API
log4j
Immediately after deployment: http://img850.imageshack.us/img850/2951/tomcatafterdeployment.jpg
So I noticed it complains about Quartz and I also read somewhere to close Hibernate Session Factory on servlet destroy.
On stop / undeploy, The Visual VM does show the Quartz thread stopped, but the tomcat log says
"appears to have start a thread named ... and has failed to stop it"
So I created a new ServletContextListener and on contextDestroyed I call to Quartz factory scheduler to shutdown and also call close on Hibernate Session Factory. and doing another deploy/undeploy, there's no more complain from the tomcat log about Quartz thread problem as above.
However, when I use "find leaks" it still complains about the same thing
The following web applications were stopped (reloaded, undeployed),
but their classes from previous runs are still loaded in memory, thus
causing a memory leak (use a profiler to confirm):
/LeakyWebApp
Then i found another complain about JDBC driver (I have mysql connector jar in my war), so I tried removing that, the complain from tomcat log disappear but the "Find Leaks" still say the same thing that my web app has memory leaks
So my question would be - what else should I be looking at? and/or how can I use the Visual VM better to detect what's going?
Thanks
EDIT:
I fixed the issue with Quartz based on the post by David Feitosa, I was missing
<init-param>
<param-name>wait-on-shutdown</param-name>
<param-value>true</param-value>
</init-param>
from the Quartz properties in web.xml.
However - I still have issue with the JDBC driver - I need it for my web app, and seems like I have 2 solutions based on the answers from: To prevent a memory leak, the JDBC Driver has been forcibly unregistered
Put the mysql-connector jar in the tomcat/lib
Manually un-register the driver in the contextDestroyed.
Which way should I go and what's the best practice for this?

Most of the problems with memory leaks that I found in this kind of web app is related to Quartz. In order to solve this, try to use the proper Quartz Servlet to init the factory: http://quartz-scheduler.org/api/2.0.0/org/quartz/ee/servlet/QuartzInitializerServlet.html
As in the Quartz doc, try to use:
<servlet>
<servlet-name>
QuartzInitializer
</servlet-name>
<display-name>
Quartz Initializer Servlet
</display-name>
<servlet-class>
org.quartz.ee.servlet.QuartzInitializerServlet
</servlet-class>
<load-on-startup>
1
</load-on-startup>
<init-param>
<param-name>config-file</param-name>
<param-value>/some/path/my_quartz.properties</param-value>
</init-param>
<init-param>
<param-name>shutdown-on-unload</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>wait-on-shutdown</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>start-scheduler-on-load</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
Hope this can help you.

Related

Vaadin 19/20 + official gradle plugin - custom servlet subpath to run within existing legacy web application along another Java framework

Environment
Spring 4.3 (no Spring Boot!), JDK 8/11, Tomcat 8.5.x, Vaadin 19/20-SNAPSHOT
I have a legacy webapp running another servlet-api-driven web framework at http://app.com. I want to add a path that adds a Vaadin-driven UI to this application - let's say at http://app.com/vaaadin-app . I'm using the newly developed official Gradle plugin. (Both Vaadin and non-Vaadin web applications should be run from single WAR, effectively sharing single classloader for shared state access, so no proxy/rewrite/etc solutions will help here).
Problem
After adding dependencies the Vaadin app is properly built and war created. Yet as soon as I call http://app.com (not http://app.com/vaadin-app) it looks like Vaadin servlet/whatever is taking over all requests. It looks like it is automatically initialized by (I guess) servlet 3.0 annotations.
Question
How can I enable Vaadin only for http://app.com/vaadin-app and keep it away from altering requests not directed there? I know with Vaadin 8 it was possible to achieve this with:
<servlet>
<servlet-name>vaadinServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>app.vaadin.additem.AddItemUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/vaadin-app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
In other words: how to prevent Vaadin 19/20 from spawning itself automatically for /* but to serve application only when user hits the /vaadin-app/* servlet path???
I think in case of maven plugin there was the "disable.automatic.servlet.registration" option to achieve this? But I don't see anything like this in case of Gradle plugin.
Thanks!
The servlet registration in Vaadin should have nothing related to Gradle, so applying the generic instructions should work. The automatic servlet registration is omitted if you define a VaadinServlet manually (extend it and map the servlet to your location of choice using #WebServlet).
Check this part of the documentation for more details: https://vaadin.com/docs/latest/flow/advanced/application-lifecycle/#automatic-servlet-registration

!asyncSupported exception when switch from Jetty 7 to Jetty 9

we recently upgraded our jetty version. when we did this both of our legacy gui war files, which no one has modified in some time, stopped working correctly. I believe I hunted the root cause to the proxy (used to proxy to a restful interface on another port), any call to the proxy throws the exception:
IllegalStateException: !asyncSupported
I'm not sure why this would occure with 1.9 but not with the old jetty. I can't build the war file currently, it was a mess that only one developer could ever build, but I trid unzipping it with jetty -x and ading to the servlet section of the web.xml file this:
<async-supported>true</async-supported>
and then rezipping it with jar c command. that didn't seem to help, though now i get exceptions in my jetty log fhile while before they would only show in the browser.
can anyone tell me what to do to activate async support and/or why the switch in jetty would cause this?
Ah, the evolution of the spec ...
Jetty 7 was Servlet 2.5 (no async there)
Jetty 8 was Servlet 3.0 (async introduced) - spec was vague on what was default, so Jetty defaulted to async-supported == true
Jetty 9 is Servlet 3.1 (even more async) - the spec was clarified, and jetty chose its default poorly. The default according to the spec is async-supported == false
That's why you didn't have to specify async-supported in the past, but now you do.
Bug about this bugs.eclipse.org/410893
Commit: 9bf7870c7c8a209f2660f63c14dd4acb62b07533
My exception is the same to you. then I put "<async-supported>true</async-supported>" append to every servlet and filter. it work well.
For excample
<filter>
<filter-name>continuation</filter-name>
<filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.annotation.AnnotationCometdServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
the other hand. if you used jetty9.x. you'd better update your comet jar to version 3.0.x or later. I hope it will help you.
I can't (yet) put this as a comment, but I'd like to add: If you are having this trouble and have added the async-supported tag as appropriate (or are using Jetty 8), make sure your filters also support async or are not used with the servlet in question.
For Java based config you may use
#javax.servlet.annotation.WebServlet(name = "HelloWorld",urlPatterns = { "/MyServlet" },asyncSupported =true)

How do I update my .jsp files without restarting the whole JBoss server?

How do I update minor, tiny changes I've just made in a .jsp file, without restarting the whole JBoss server? This is just a private server on my (pretty slow) PC. Up until now, I've been able to click this little icon that says "restart module". Now, this icon is grayed out.
Just replace your .jsp or the .war file for that matter. JBoss does a great job at detecting updated files and will redeploy and recompile your jsps.
Oh keep in mind your browser might be set to cache your files. in that case make sure to hit the refresh button or just open a fresh instance of your browser or tab.
I found that it does also help to configure the JSP Servlet to recompile on any change. This is not something you want in production, but it does speed-up development:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>checkInterval</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>modificationTestInterval</param-name>
<param-value>1</param-value>
</init-param>
</servlet>
as shown in answer to 'JSP deployment without war file'
Most of the Web Servers support Hot deployment and dynamic reloading. Which extracts the WAR file within the server working directory. You can replace your Modified JSP there to get picket at runtime.
Possible duplicate . Look here

How to dynamically configure the WebLogicCluster property outside of web.xml

I have a web application deployed as war file in weblogic 10.3.3. Now I want to make this application clusterable. For this I'm using the HttpClusterServlet from Weblogic as a load balancer. According to the documentation I can put this servlet configuration into the web.xml
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>server-1:7122|server-1:7123</param-value>
</init-param>
</servlet>
The problem is that this configuration is hard wired at build time and can't be reconfigured at runtime. For instance I would like to be able to add 5 more servers dynamically. I had several ideas to solve that problem:
Extend the weblogic.servlet.proxy.HttpClusterServlet with an own servlet implentation. This is not possible, the class is final.
Use a servlet filter to reconfigure the servlet. The servlet is not accessible anymore through ServletContext().getServlet(String) since Java Servlet API 2.1, with no direct replacement.
Reflection might be an option, but I couldn't figure out a reliable way to access the configuration
All of my attempts to reconfigure this init-param externally failed so far. I'm open to any solutions.
This might help How to externalize web.xml servlet init-param? Spring DelegatingFilterProxy for Servlets? Even if your not using Spring it wouldn't be too hard to port that servlet to another IoC container.

Scheduled task in a web application? [duplicate]

This question already has answers here:
What is recommended way for spawning threads from a servlet in Tomcat
(5 answers)
Closed 8 years ago.
I'm building a statistics apps for an online game, built using the servlet API in Java (to be deployed on Tomcat). It's easy enough to let the game send a message to the stats server every time a user logs in, because handling requests is what Servlets/Tomcat are for.
I also need to periodically initiate requests on the stats server though, for example to retrieve the number of online users from the game server or the number of fans from our Facebook page.
It would be easy to just start a thread in the app's main servlet and let that do the data retrieval once in a while, but it feels a bit strange because all other threads are created by Tomcat.
Is doing it like that ok?
If not, what is the recommended way of doing this?
Is it even correct to use servlets for something like this? What's the alternative?
Note after first answers: I'm not looking for a solution to the problem of timing or concurrency, because I can easily handle both. I just need to know how to properly start a pro-active process in a servlet container.
Quartz is your best bet, and most highly configurable. It has CRON based interface or a more dynamic way to generate jobs that are relative from a specific event, if your use case calls for it Quartz can do it. It has the ability to persist jobs to the database so they can survive restarts.
http://www.quartz-scheduler.org/
Make configurations in web.xml like this to auto-start it:
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<display-name>Quartz Initializer Servlet</display-name>
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>shutdown-on-unload</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>start-scheduler-on-load</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
You should consider:
Quartz
The "regular" TimerTask
If you're using spring on your webapp, there is a dedicated part for it
Don't bother reinventing the wheel, Quartz and other products already handle Threads/timeouts/concurrency issues for you!

Categories