public TomEEWebappClassLoader() { hashCode = construct(); setJavaseClassLoader(getSystemClassLoader()); containerClassLoader = ParentClassLoaderFinder.Helper.get(); isEar = getParent() != null && !getParent().equals(containerClassLoader) && defaultEarBehavior(); originalDelegate = getDelegate(); }
// mainly intended to avoid conflicts between internal and overrided spec extensions private boolean isFiltered(final Collection<Extension> extensions, final Extension next) { final ClassLoader containerLoader = ParentClassLoaderFinder.Helper.get(); final Class<? extends Extension> extClass = next.getClass(); if (extClass.getClassLoader() != containerLoader) { return false; } final String name = extClass.getName(); switch (name) { case "org.apache.bval.cdi.BValExtension": for (final Extension e : extensions) { final String en = e.getClass().getName(); // org.hibernate.validator.internal.cdi.ValidationExtension but allowing few evolutions of // packages if (en.startsWith("org.hibernate.validator.") && en.endsWith("ValidationExtension")) { log.info("Skipping BVal CDI integration cause hibernate was found in the application"); return true; } } break; case "org.apache.batchee.container.cdi.BatchCDIInjectionExtension": // see // org.apache.openejb.batchee.BatchEEServiceManager return "true" .equals(SystemInstance.get().getProperty("tomee.batchee.cdi.use-extension", "false")); case "org.apache.commons.jcs.jcache.cdi.MakeJCacheCDIInterceptorFriendly": final String spi = "META-INF/services/javax.cache.spi.CachingProvider"; try { final Enumeration<URL> appResources = Thread.currentThread().getContextClassLoader().getResources(spi); if (appResources != null && appResources.hasMoreElements()) { final Collection<URL> containerResources = Collections.list(containerLoader.getResources(spi)); do { if (!containerResources.contains(appResources.nextElement())) { log.info( "Skipping JCS CDI integration cause another provide was found in the application"); return true; } } while (appResources.hasMoreElements()); } } catch (final Exception e) { // no-op } break; default: } return false; }
@Before public void initContext() throws LifecycleException { final OpenEjbConfiguration configuration = new OpenEjbConfiguration(); configuration.facilities = new FacilitiesInfo(); final CoreContainerSystem containerSystem = new CoreContainerSystem(new IvmJndiFactory()); SystemInstance.get().setComponent(OpenEjbConfiguration.class, configuration); SystemInstance.get().setComponent(ContainerSystem.class, containerSystem); SystemInstance.get() .setComponent( WebAppEnricher.class, new WebAppEnricher() { @Override public URL[] enrichment(final ClassLoader webappClassLaoder) { return new URL[0]; } }); loader = new TomEEWebappClassLoader(ParentClassLoaderFinder.Helper.get()) { @Override protected void clearReferences() { // no-op: this test should be reworked to support it but in real life a loader is not // stopped/started } }; loader.init(); final StandardRoot resources = new StandardRoot(); loader.setResources(resources); resources.setContext( new StandardContext() { @Override public String getDocBase() { final File file = new File("target/foo"); file.mkdirs(); return file.getAbsolutePath(); } @Override public String getMBeanKeyProperties() { return "foo"; } { } }); resources.start(); loader.start(); info = new AppInfo(); info.appId = "test"; context = new AppContext( info.appId, SystemInstance.get(), loader, new IvmContext(), new IvmContext(), true); containerSystem.addAppContext(context); final WebContext webDeployment = new WebContext(context); webDeployment.setId(context.getId()); webDeployment.setClassLoader(loader); containerSystem.addWebContext(webDeployment); }
@Test public void tomcatClassLoaderParentShouldntBeNulAfterAStopStartOtherwiseReloadIsBroken() throws Exception { final CxfRSService server = new CxfRSService(); try { server.init(new Properties()); server.start(); server.afterApplicationCreated( new AssemblerAfterApplicationCreated( info, context, Collections.<BeanContext>emptyList())); { final ClassLoader beforeLoader = SystemInstance.get() .getComponent(ContainerSystem.class) .getWebContext("test") .getClassLoader(); assertSame(loader, beforeLoader); assertNotNull(beforeLoader); assertNotNull(Reflections.get(beforeLoader, "parent")); } loader.internalStop(); server.undeploy(new AssemblerBeforeApplicationDestroyed(info, context)); { final URLClassLoader afterLoader = URLClassLoader.class.cast( SystemInstance.get() .getComponent(ContainerSystem.class) .getWebContext("test") .getClassLoader()); assertSame(loader, afterLoader); assertNotNull(afterLoader); assertEquals(0, afterLoader.getURLs().length); assertEquals(LifecycleState.STOPPED, loader.getState()); } final StandardRoot resources = new StandardRoot(); loader.setResources(resources); resources.setContext( new StandardContext() { @Override public String getDocBase() { final File file = new File("target/foo"); file.mkdirs(); return file.getAbsolutePath(); } @Override public String getMBeanKeyProperties() { return "foo"; } { } }); resources.start(); loader.start(); // TomcatWebAppBuilder ill catch start event from StandardContext and force a classloader Reflections.set(loader, "parent", ParentClassLoaderFinder.Helper.get()); server.afterApplicationCreated( new AssemblerAfterApplicationCreated( info, context, Collections.<BeanContext>emptyList())); { final ClassLoader afterLoader = SystemInstance.get() .getComponent(ContainerSystem.class) .getWebContext("test") .getClassLoader(); assertSame(loader, afterLoader); assertNotNull(afterLoader); assertNotNull(Reflections.get(afterLoader, "parent")); } server.undeploy(new AssemblerBeforeApplicationDestroyed(info, context)); } finally { server.stop(); } }