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();
    }
  }