public void execute()

in knights/openwebbeans-knight/src/main/java/org/apache/geronimo/arthur/knight/openwebbeans/OpenWebBeansExtension.java [117:300]


    public void execute(final Context context) {
        final Properties original = new Properties();
        original.putAll(System.getProperties());
        try (final SeContainer container = configureInitializer(context, SeContainerInitializer.newInstance()).initialize()) {
            final WebBeansContext webBeansContext = WebBeansContext.currentInstance();
            final BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl();
            final Set<Bean<?>> beans = beanManager.getBeans();
            final Collection<javax.enterprise.inject.spi.Interceptor<?>> interceptors = webBeansContext.getInterceptorsManager().getCdiInterceptors();
            final Predicate<String> classFilter = context.createIncludesExcludes(
                    "extension.openwebbeans.classes.filter.", PredicateType.STARTS_WITH);

            // 1. capture all proxies
            dumpProxies(context, webBeansContext, beans, classFilter);

            // 2. register all classes which will require reflection + proxies
            final String beanClassesList = registerBeansForReflection(context, beans, classFilter, interceptors);
            getProxies(webBeansContext).keySet().stream()
                    .filter(classFilter)
                    .flatMap(it -> {
                        try {
                            return hierarchy(context.loadClass(it))
                                    .map(Class::getName);
                        } catch (final RuntimeException re) {
                            return Stream.of(it);
                        }
                    })
                    .sorted()
                    .forEach(name -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(name);
                        model.setAllDeclaredConstructors(true);
                        model.setAllDeclaredFields(true);
                        model.setAllDeclaredMethods(true);
                        context.register(model);
                    });

            // 3. dump owb properties for runtime
            final Properties properties = initProperties(context, webBeansContext.getOpenWebBeansConfiguration(), beanClassesList);

            // 4. register CDI/OWB API which require some reflection
            // 4.1 SPI (interface)
            Stream.of(
                            ScannerService.class, LoaderService.class, BeanArchiveService.class, SecurityService.class,
                            ContainerLifecycle.class, JNDIService.class, ApplicationBoundaryService.class, ContextsService.class,
                            InjectionPointService.class, ResourceInjectionService.class, DefiningClassService.class,
                            Filter.class)
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz.getName());
                        model.setAllPublicMethods(true);
                        context.register(model);
                    });
            // 4.2 classes which must be instantiable
            Stream.concat(Stream.of(
                                    ClassLoaderProxyService.LoadOnly.class, StandaloneLifeCycle.class, StandaloneContextsService.class,
                                    DefaultLoaderService.class, InjectionPointImpl.class, ConversationImpl.class, SimpleApplicationBoundaryService.class,
                                    ApplicationScopedBeanInterceptorHandler.class, RequestScopedBeanInterceptorHandler.class,
                                    SessionScopedBeanInterceptorHandler.class, NormalScopedBeanInterceptorHandler.class,
                                    CDISeScannerService.class, PreScannedCDISeScannerService.class, DefaultScannerService.class),
                            findServices(properties))
                    .distinct()
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz.getName());
                        model.setAllDeclaredConstructors(true);
                        context.register(model);
                    });
            // 4.3 needed by prescanned scanner
            final ClassReflectionModel owbFinder = new ClassReflectionModel();
            owbFinder.setName(AnnotationFinder.class.getName());
            final ClassReflectionModel.FieldReflectionModel owbFinderLinking = new ClassReflectionModel.FieldReflectionModel();
            owbFinderLinking.setAllowWrite(true);
            owbFinderLinking.setName("linking");
            owbFinder.setFields(singletonList(owbFinderLinking));
            context.register(owbFinder);
            // 5 annotations
            final Collection<Class<?>> customAnnotations = Stream.concat(
                            context.findAnnotatedClasses(Qualifier.class).stream(),
                            context.findAnnotatedClasses(NormalScope.class).stream())
                    .collect(toList());
            Stream.concat(Stream.concat(Stream.of(
                                            Initialized.class, Destroyed.class, NormalScope.class, ApplicationScoped.class, Default.class,
                                            Dependent.class, ConversationScoped.class, RequestScoped.class, Observes.class, ObservesAsync.class,
                                            Qualifier.class, InterceptorBinding.class, Priority.class),
                                    beanManager.getAdditionalQualifiers().stream()),
                            customAnnotations.stream())
                    .distinct()
                    .map(Class::getName)
                    .sorted()
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz);
                        model.setAllDeclaredMethods(true);
                        context.register(model);
                    });
            customAnnotations.stream() // DefaultAnnotation.of
                    .filter(it -> !it.getName().startsWith("javax.") && !it.getName().startsWith("jakarta."))
                    .map(Class::getName)
                    .sorted()
                    .map(it -> {
                        final DynamicProxyModel proxyModel = new DynamicProxyModel();
                        proxyModel.setClasses(singleton(it));
                        return proxyModel;
                    })
                    .forEach(context::register);

            // 6 extensions - normally taken by graalvm service loader but we need a bit more reflection
            final ExtensionLoader extensionLoader = webBeansContext.getExtensionLoader();
            try {
                final Field extensionClasses = ExtensionLoader.class.getDeclaredField("extensionClasses");
                if (!extensionClasses.isAccessible()) {
                    extensionClasses.setAccessible(true);
                }
                final Predicate<String> extensionFilter = context.createPredicate("extension.openwebbeans.extension.excludes", PredicateType.STARTS_WITH)
                        .map(Predicate::negate)
                        .orElseGet(() -> n -> true);
                final Set<Class<?>> classes = (Set<Class<?>>) extensionClasses.get(extensionLoader);
                classes.stream()
                        .filter(it -> extensionFilter.test(it.getName()))
                        .flatMap(this::hierarchy)
                        .distinct()
                        .map(Class::getName)
                        .filter(classFilter)
                        .sorted()
                        .forEach(clazz -> {
                            final ClassReflectionModel model = new ClassReflectionModel();
                            model.setName(clazz);
                            model.setAllDeclaredConstructors(true);
                            model.setAllDeclaredMethods(true);
                            model.setAllDeclaredMethods(true);
                            context.register(model);
                        });
            } catch (final NoSuchFieldException | IllegalAccessException e) {
                throw new IllegalStateException("Incompatible OpenWebBeans version", e);
            }

            // 7. producer types must be reflection friendly
            findProducedClasses(beans)
                    .map(Class::getName)
                    .sorted()
                    .forEach(name -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(name);
                        model.setAllDeclaredConstructors(true);
                        model.setAllDeclaredFields(true);
                        model.setAllDeclaredMethods(true);
                        context.register(model);
                    });

            // 8. enforce some build time init for annotations and some specific classes
            context.initializeAtBuildTime(
                    Reception.class.getName(),
                    TransactionPhase.class.getName(),
                    DefaultSingletonService.class.getName(),
                    WebBeansLoggerFacade.class.getName());
            try { // openwebbeans-slf4j is an optional module
                final Class<?> logger = context.loadClass("org.apache.openwebbeans.slf4j.Slf4jLogger");
                context.initializeAtBuildTime(logger.getName());
            } catch (final RuntimeException e) {
                // ignore, not there
            }

            // 9. we add the resource bundle + the bundle as resource for some extensions (thank you JUL)
            context.includeResourceBundle("openwebbeans/Messages");
            final ResourceModel resourceModel = new ResourceModel();
            resourceModel.setPattern("openwebbeans/Messages\\.properties");
            context.register(resourceModel);

            // 10. OWB creates proxies on TypeVariable (generics checks) so enable it
            final DynamicProxyModel typeVariableProxyModel = new DynamicProxyModel();
            typeVariableProxyModel.setClasses(singleton(TypeVariable.class.getName()));
            context.register(typeVariableProxyModel);

            // 11. interceptor bindings
            context.findAnnotatedClasses(InterceptorBinding.class).forEach(clazz -> {
                final ClassReflectionModel model = new ClassReflectionModel();
                model.setName(clazz.getName());
                model.setAllPublicMethods(true);
                context.register(model);
            });
        } finally {
            System.setProperties(original);
        }
    }