You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by oren peer <or...@gmail.com> on 2016/08/03 14:30:11 UTC

Re: Tomcat 8.0.33, Ubuntu 14.04.3 : shared classloader with embedded Tomcat 8

Hi again. I've search for solution to my problem and found that When an app
is deployed to Tomcat, all of the application's startup is performed with a
WebAppClassLoader being the thread context class loader.
When an app is using *embedded Tomcat*, the WebAppClassLoader is created as
part of the application starting but
is never set as the thread context class loader.
how can I fix it?

Thanks
Oren


2016-07-23 0:00 GMT+03:00 oren peer <or...@gmail.com>:

> I have upgraded tomcat from version 7.0.34 to version 8.0.33, and since
> then I have been facing a problem to share the web application context and
> Junit context.
>
> I have a web application with singleton class that gathers statistic data
> about the web application. I also have Junit that runs the web application
> in embedded tomcat. the Junit queries the web application and then checks
> the statistic data.
>
> I try to make a simple example:
>
> the singleton:
>
>   public class Counter {
>
>   private static Counter instance;
>   private AtomicLong counter;
>
>   private Counter(){}
>
>   public static Counter getInstance(){
>     if(instance == null){
>       synchronized (Counter.class) {
>         if(instance == null){
>           instance = new Counter();
>         }
>       }
>     }
>
>     return instance;
>   }
>
>   public long incrementAndGet(){
>     return counter.incrementAndGet();
>   }
>
>   public long getValue(){
>     return counter.get();
>   }
> }
>
> the servlet:
>
> @WebServlet(name="servlet",loadOnStartup=1, urlPatterns="/servletTest")public class Servlet extends HttpServlet{
>
>   @Override
>   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
>       resp.getWriter().write("Hi, you are the #" + Counter.getInstance().incrementAndGet() + " visitor");
>   }}
>
> contextListener:
>
> public class MyContextListener implements ServletContextListener{
>   @Override
>   public void contextDestroyed(ServletContextEvent arg0) {}
>
>   @Override
>   public void contextInitialized(ServletContextEvent arg0) {
>     Counter.getInstance().incrementAndGet();
>   }}
>
> Test unit:
>
>   public void mainTest() throws ServletException, LifecycleException{
>     Tomcat tomcat = new Tomcat();
>
>    tomcat.setPort(50000);
>    StandardContext ctx = (StandardContext) tomcat.addWebapp("/fe", System.getProperty("FEBaseDir"));
>
>    tomcat.start();
>
>    Counter.getInstance().getValue();
>
>   }
>
> when I used Tomcat 7, everything worked fine. but since I upgraded tomcat to tomcat 8.0.33, It hasn't been working. the singleton class with the static data loads twice. first by the tomcat and then by the Junit itself.
>
> I have tried to pass tomcat a classloader but it doesn't work.
>
>  public void mainTest() throws ServletException, LifecycleException{
>     Tomcat tomcat = new Tomcat();
>
>    tomcat.setPort(50000);
>    StandardContext ctx = (StandardContext) tomcat.addWebapp("/fe", System.getProperty("FEBaseDir")); /
>
>    ctx.setCrossContext(true);
>    ctx.setLoader((Loader) new WebappLoader(Thread.currentThread().getContextClassLoader()));
>
>    ctx.setParentClassLoader(Thread.currentThread().getContextClassLoader());
>
>    tomcat.getEngine().setParentClassLoader(Thread.currentThread().getContextClassLoader());
>    tomcat.getHost().setParentClassLoader(Thread.currentThread().getContextClassLoader());
>    tomcat.getService().setParentClassLoader(Thread.currentThread().getContextClassLoader());
>    tomcat.getServer().setParentClassLoader(Thread.currentThread().getContextClassLoader());
>    tomcat.start();
>
>    Counter.getInstance().getValue();
>
>   }
>
>
> What am I doing wrong?
>
> Thanks!
>
> Oren
>
>