Ich habe tomcat von Version 7.0.34 auf Version 8.0.33 aktualisiert, und seitdem habe ich ein Problem, den Webanwendungskontext und Junit-Kontext zu teilen.shared Classloader mit integriertem Tomcat 8
Ich habe eine Webanwendung mit Singleton-Klasse, die statistische Daten über die Webanwendung sammelt. Ich habe auch Junit, der die Webanwendung in Embedded Tomcat ausführt. Der Junit fragt die Webanwendung ab und überprüft dann die Statistikdaten.
Ich versuche, ein einfaches Beispiel zu machen:
die Singletons:
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();
}
}
das 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();
}
}
Prüfgerät:
public void mainTest() throws ServletException, LifecycleException{
Tomcat tomcat = new Tomcat();
tomcat.setPort(50000);
StandardContext ctx = (StandardContext) tomcat.addWebapp("/fe", System.getProperty("FEBaseDir")); //The FEBaseDir property is supposed to be taken from Maven build using 'test' profile
tomcat.start();
Counter.getInstance().getValue();
}
Wenn ich Tomcat 7 verwendet habe, hat alles gut funktioniert. Aber seit ich Tomcat 8.0.33 zu Tomcat upgraded, hat es nicht funktioniert. Die Singleton-Klasse mit den statischen Daten wird zweimal geladen. zuerst beim Kater und dann beim Junit.
Ich habe versucht, Tomcat ein Classloader zu übergeben, aber es funktioniert nicht.
public void mainTest() throws ServletException, LifecycleException{
Tomcat tomcat = new Tomcat();
tomcat.setPort(50000);
StandardContext ctx = (StandardContext) tomcat.addWebapp("/fe", System.getProperty("FEBaseDir")); //The FEBaseDir property is supposed to be taken from Maven build using 'test' profile
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();
}
Was mache ich falsch?