You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/12/01 13:00:16 UTC

[syncope] branch master updated: Empowering Spring Boot best-practices to Console and Enduser (#396)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new c00a6285cf Empowering Spring Boot best-practices to Console and Enduser (#396)
c00a6285cf is described below

commit c00a6285cf02f842b4d11065af67757cb8e123f2
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Thu Dec 1 14:00:11 2022 +0100

    Empowering Spring Boot best-practices to Console and Enduser (#396)
---
 .../ui/commons/ApplicationContextProvider.java     |  59 ----------
 ...ConsoleApplication.java => ConsoleContext.java} |  99 +++-------------
 .../client/console/SyncopeConsoleApplication.java  | 130 +++++----------------
 .../client/console/SyncopeWebApplication.java      |  83 +++++++++----
 .../wizards/any/UserFormFinalizerUtils.java        |  52 ---------
 .../console/wizards/any/UserWizardBuilder.java     |   5 +-
 .../src/main/resources/META-INF/spring.factories   |  19 +++
 .../syncope/client/console/AbstractTest.java       |  25 +++-
 .../syncope/client/enduser/EnduserContext.java     |  52 +++++++++
 .../client/enduser/SyncopeEnduserApplication.java  |  41 ++-----
 .../client/enduser/SyncopeWebApplication.java      |  31 ++---
 .../src/main/resources/META-INF/spring.factories   |  19 +++
 .../syncope/client/enduser/AbstractTest.java       |  10 ++
 .../syncope/fit/console/AbstractConsoleITCase.java |  12 --
 .../syncope/fit/enduser/AbstractEnduserITCase.java |   6 -
 pom.xml                                            |   1 +
 16 files changed, 252 insertions(+), 392 deletions(-)

diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/ApplicationContextProvider.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/ApplicationContextProvider.java
deleted file mode 100644
index a3334c521f..0000000000
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/ApplicationContextProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.ui.commons;
-
-import java.util.Optional;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class ApplicationContextProvider implements ApplicationContextAware {
-
-    private static ConfigurableApplicationContext CTX;
-
-    private static DefaultListableBeanFactory BEAN_FACTORY;
-
-    public static ConfigurableApplicationContext getApplicationContext() {
-        return CTX;
-    }
-
-    public static void setApplicationContext(final ConfigurableApplicationContext ctx) {
-        CTX = ctx;
-    }
-
-    public static DefaultListableBeanFactory getBeanFactory() {
-        return Optional.ofNullable(BEAN_FACTORY).orElseGet(()
-            -> Optional.ofNullable(CTX).map(ctx -> (DefaultListableBeanFactory) ctx.getBeanFactory()).orElse(null));
-    }
-
-    public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
-        BEAN_FACTORY = beanFactory;
-    }
-
-    /**
-     * Wiring the ApplicationContext into a static method.
-     *
-     * @param ctx Spring application context
-     */
-    @Override
-    public void setApplicationContext(final ApplicationContext ctx) {
-        CTX = (ConfigurableApplicationContext) ctx;
-    }
-}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/ConsoleContext.java
similarity index 53%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/ConsoleContext.java
index efb33df09d..6c6d741876 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/ConsoleContext.java
@@ -18,9 +18,6 @@
  */
 package org.apache.syncope.client.console;
 
-import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
-import java.util.Map;
-import org.apache.syncope.client.console.actuate.SyncopeConsoleInfoContributor;
 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionLinksProvider;
 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionsProvider;
 import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
@@ -42,77 +39,27 @@ import org.apache.syncope.client.console.commons.StatusProvider;
 import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationContributor;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.wizards.any.UserFormFinalizerUtils;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
 import org.apache.syncope.client.ui.commons.MIMETypesLoader;
-import org.apache.syncope.client.ui.commons.actuate.SyncopeCoreHealthIndicator;
-import org.apache.syncope.common.keymaster.client.api.ServiceOps;
-import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
-import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
-import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 
-@SpringBootApplication(exclude = {
-    ErrorMvcAutoConfiguration.class,
-    HttpMessageConvertersAutoConfiguration.class }, proxyBeanMethods = false)
-@EnableConfigurationProperties(ConsoleProperties.class)
-public class SyncopeConsoleApplication extends SpringBootServletInitializer {
-
-    public static void main(final String[] args) {
-        new SpringApplicationBuilder(SyncopeConsoleApplication.class).
-                properties("spring.config.name:console").
-                build().run(args);
-    }
-
-    @Override
-    protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
-        return builder.properties(Map.of(
-                WebSocketWicketWebInitializerAutoConfiguration.REGISTER_SERVER_ENDPOINT_ENABLED, false,
-                "spring.config.name", "console")).
-                sources(SyncopeConsoleApplication.class);
-    }
-
-    @Bean
-    public ApplicationContextProvider applicationContextProvider() {
-        return new ApplicationContextProvider();
-    }
-
-    @ConditionalOnMissingBean
-    @Bean
-    public SyncopeCoreHealthIndicator syncopeCoreHealthIndicator(final ServiceOps serviceOps,
-                                                                 final ConsoleProperties props) {
-        return new SyncopeCoreHealthIndicator(
-                serviceOps,
-                props.getAnonymousUser(),
-                props.getAnonymousKey(),
-                props.isUseGZIPCompression());
-    }
+@Configuration(proxyBeanMethods = false)
+public class ConsoleContext {
 
     @ConditionalOnMissingBean
     @Bean
-    public SyncopeConsoleInfoContributor syncopeConsoleInfoContributor() {
-        return new SyncopeConsoleInfoContributor();
-    }
+    public ClassPathScanImplementationLookup classPathScanImplementationLookup(
+            final ApplicationContext ctx, final ConsoleProperties props) {
 
-    @ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
-    @Bean
-    public ClassPathScanImplementationLookup classPathScanImplementationLookup(final ApplicationContext ctx,
-                                                                               final ConsoleProperties props) {
         ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(
                 ctx.getBeansOfType(ClassPathScanImplementationContributor.class).values(), props);
         lookup.load();
         return lookup;
     }
 
-    @ConditionalOnMissingBean(name = "mimeTypesLoader")
+    @ConditionalOnMissingBean
     @Bean
     public MIMETypesLoader mimeTypesLoader() {
         MIMETypesLoader mimeTypesLoader = new MIMETypesLoader();
@@ -120,61 +67,55 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
         return mimeTypesLoader;
     }
 
-    @ConditionalOnMissingBean(name = "previewUtils")
+    @ConditionalOnMissingBean
     @Bean
     public PreviewUtils previewUtils() {
         return new PreviewUtils();
     }
 
-    @ConditionalOnMissingBean(name = "userFormFinalizerUtils")
-    @Bean
-    public UserFormFinalizerUtils userFormFinalizerUtils() {
-        return new UserFormFinalizerUtils();
-    }
-
-    @ConditionalOnMissingBean(name = "resourceProvider")
+    @ConditionalOnMissingBean
     @Bean
     public ExternalResourceProvider resourceProvider() {
         return new IdRepoExternalResourceProvider();
     }
 
-    @ConditionalOnMissingBean(name = "anyDirectoryPanelAdditionalActionsProvider")
+    @ConditionalOnMissingBean
     @Bean
     public AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider() {
         return new IdRepoAnyDirectoryPanelAdditionalActionsProvider();
     }
 
-    @ConditionalOnMissingBean(name = "anyDirectoryPanelAdditionalActionLinksProvider")
+    @ConditionalOnMissingBean
     @Bean
     public AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider() {
         return new IdRepoAnyDirectoryPanelAdditionalActionLinksProvider();
     }
 
-    @ConditionalOnMissingBean(name = "anyWizardBuilderAdditionalSteps")
+    @ConditionalOnMissingBean
     @Bean
     public AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps() {
         return new IdRepoAnyWizardBuilderAdditionalSteps();
     }
 
-    @ConditionalOnMissingBean(name = "statusProvider")
+    @ConditionalOnMissingBean
     @Bean
     public StatusProvider statusProvider() {
         return new IdRepoStatusProvider();
     }
 
-    @ConditionalOnMissingBean(name = "virSchemaDetailsPanelProvider")
+    @ConditionalOnMissingBean
     @Bean
     public VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider() {
         return new IdRepoVirSchemaDetailsPanelProvider();
     }
 
-    @ConditionalOnMissingBean(name = "implementationInfoProvider")
+    @ConditionalOnMissingBean
     @Bean
     public ImplementationInfoProvider implementationInfoProvider() {
         return new IdRepoImplementationInfoProvider();
     }
 
-    @ConditionalOnMissingBean(name = "realmPolicyProvider")
+    @ConditionalOnMissingBean
     @Bean
     public RealmPolicyProvider realmPolicyProvider() {
         return new IdRepoRealmPolicyProvider();
@@ -184,14 +125,4 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
     public PolicyTabProvider idRepoPolicyTabProvider() {
         return new IdRepoPolicyTabProvider();
     }
-
-    @Bean
-    public KeymasterStart keymasterStart() {
-        return new KeymasterStart(NetworkService.Type.CONSOLE);
-    }
-
-    @Bean
-    public KeymasterStop keymasterStop() {
-        return new KeymasterStop(NetworkService.Type.CONSOLE);
-    }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index efb33df09d..d3ee8b5cf0 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -25,26 +25,10 @@ import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActi
 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionsProvider;
 import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
 import org.apache.syncope.client.console.commons.ExternalResourceProvider;
-import org.apache.syncope.client.console.commons.IdRepoAnyDirectoryPanelAdditionalActionLinksProvider;
-import org.apache.syncope.client.console.commons.IdRepoAnyDirectoryPanelAdditionalActionsProvider;
-import org.apache.syncope.client.console.commons.IdRepoAnyWizardBuilderAdditionalSteps;
-import org.apache.syncope.client.console.commons.IdRepoExternalResourceProvider;
-import org.apache.syncope.client.console.commons.IdRepoImplementationInfoProvider;
-import org.apache.syncope.client.console.commons.IdRepoPolicyTabProvider;
-import org.apache.syncope.client.console.commons.IdRepoRealmPolicyProvider;
-import org.apache.syncope.client.console.commons.IdRepoStatusProvider;
-import org.apache.syncope.client.console.commons.IdRepoVirSchemaDetailsPanelProvider;
 import org.apache.syncope.client.console.commons.ImplementationInfoProvider;
-import org.apache.syncope.client.console.commons.PolicyTabProvider;
-import org.apache.syncope.client.console.commons.PreviewUtils;
-import org.apache.syncope.client.console.commons.RealmPolicyProvider;
 import org.apache.syncope.client.console.commons.StatusProvider;
 import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
-import org.apache.syncope.client.console.init.ClassPathScanImplementationContributor;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.wizards.any.UserFormFinalizerUtils;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
-import org.apache.syncope.client.ui.commons.MIMETypesLoader;
 import org.apache.syncope.client.ui.commons.actuate.SyncopeCoreHealthIndicator;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
@@ -80,15 +64,38 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
                 sources(SyncopeConsoleApplication.class);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public ApplicationContextProvider applicationContextProvider() {
-        return new ApplicationContextProvider();
+    public SyncopeWebApplication syncopeWebApplication(
+            final ConsoleProperties props,
+            final ClassPathScanImplementationLookup lookup,
+            final ServiceOps serviceOps,
+            final ExternalResourceProvider resourceProvider,
+            final AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider,
+            final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider,
+            final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps,
+            final StatusProvider statusProvider,
+            final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider,
+            final ImplementationInfoProvider implementationInfoProvider,
+            final ApplicationContext ctx) {
+
+        return new SyncopeWebApplication(
+                props,
+                lookup,
+                serviceOps,
+                resourceProvider,
+                anyDirectoryPanelAdditionalActionsProvider,
+                anyDirectoryPanelAdditionalActionLinksProvider,
+                anyWizardBuilderAdditionalSteps, statusProvider,
+                virSchemaDetailsPanelProvider,
+                implementationInfoProvider, ctx);
     }
 
     @ConditionalOnMissingBean
     @Bean
-    public SyncopeCoreHealthIndicator syncopeCoreHealthIndicator(final ServiceOps serviceOps,
-                                                                 final ConsoleProperties props) {
+    public SyncopeCoreHealthIndicator syncopeCoreHealthIndicator(
+            final ServiceOps serviceOps, final ConsoleProperties props) {
+
         return new SyncopeCoreHealthIndicator(
                 serviceOps,
                 props.getAnonymousUser(),
@@ -102,89 +109,6 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
         return new SyncopeConsoleInfoContributor();
     }
 
-    @ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
-    @Bean
-    public ClassPathScanImplementationLookup classPathScanImplementationLookup(final ApplicationContext ctx,
-                                                                               final ConsoleProperties props) {
-        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(
-                ctx.getBeansOfType(ClassPathScanImplementationContributor.class).values(), props);
-        lookup.load();
-        return lookup;
-    }
-
-    @ConditionalOnMissingBean(name = "mimeTypesLoader")
-    @Bean
-    public MIMETypesLoader mimeTypesLoader() {
-        MIMETypesLoader mimeTypesLoader = new MIMETypesLoader();
-        mimeTypesLoader.load();
-        return mimeTypesLoader;
-    }
-
-    @ConditionalOnMissingBean(name = "previewUtils")
-    @Bean
-    public PreviewUtils previewUtils() {
-        return new PreviewUtils();
-    }
-
-    @ConditionalOnMissingBean(name = "userFormFinalizerUtils")
-    @Bean
-    public UserFormFinalizerUtils userFormFinalizerUtils() {
-        return new UserFormFinalizerUtils();
-    }
-
-    @ConditionalOnMissingBean(name = "resourceProvider")
-    @Bean
-    public ExternalResourceProvider resourceProvider() {
-        return new IdRepoExternalResourceProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "anyDirectoryPanelAdditionalActionsProvider")
-    @Bean
-    public AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider() {
-        return new IdRepoAnyDirectoryPanelAdditionalActionsProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "anyDirectoryPanelAdditionalActionLinksProvider")
-    @Bean
-    public AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider() {
-        return new IdRepoAnyDirectoryPanelAdditionalActionLinksProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "anyWizardBuilderAdditionalSteps")
-    @Bean
-    public AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps() {
-        return new IdRepoAnyWizardBuilderAdditionalSteps();
-    }
-
-    @ConditionalOnMissingBean(name = "statusProvider")
-    @Bean
-    public StatusProvider statusProvider() {
-        return new IdRepoStatusProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "virSchemaDetailsPanelProvider")
-    @Bean
-    public VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider() {
-        return new IdRepoVirSchemaDetailsPanelProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "implementationInfoProvider")
-    @Bean
-    public ImplementationInfoProvider implementationInfoProvider() {
-        return new IdRepoImplementationInfoProvider();
-    }
-
-    @ConditionalOnMissingBean(name = "realmPolicyProvider")
-    @Bean
-    public RealmPolicyProvider realmPolicyProvider() {
-        return new IdRepoRealmPolicyProvider();
-    }
-
-    @Bean
-    public PolicyTabProvider idRepoPolicyTabProvider() {
-        return new IdRepoPolicyTabProvider();
-    }
-
     @Bean
     public KeymasterStart keymasterStart() {
         return new KeymasterStart(NetworkService.Type.CONSOLE);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
index 2bb4daead5..23dfe3178a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
@@ -23,7 +23,9 @@ import de.agilecoders.wicket.core.Bootstrap;
 import de.agilecoders.wicket.core.settings.BootstrapSettings;
 import de.agilecoders.wicket.core.settings.IBootstrapSettings;
 import de.agilecoders.wicket.core.settings.SingleThemeProvider;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionLinksProvider;
 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionsProvider;
 import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
@@ -37,6 +39,7 @@ import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.pages.Dashboard;
 import org.apache.syncope.client.console.pages.Login;
 import org.apache.syncope.client.console.pages.MustChangePassword;
+import org.apache.syncope.client.console.wizards.any.UserFormFinalizer;
 import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
@@ -44,6 +47,7 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.SyncopeUIRequestCycleListener;
 import org.apache.syncope.client.ui.commons.annotations.Resource;
 import org.apache.syncope.client.ui.commons.themes.AdminLTE;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
 import org.apache.wicket.Page;
@@ -65,12 +69,10 @@ import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
 
-@Component
 public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
 
     protected static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class);
@@ -79,38 +81,53 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
         return (SyncopeWebApplication) WebApplication.get();
     }
 
-    @Autowired
-    protected ConsoleProperties props;
+    protected final ConsoleProperties props;
 
-    @Autowired
-    protected ClassPathScanImplementationLookup lookup;
+    protected final ClassPathScanImplementationLookup lookup;
 
-    @Autowired
-    protected ServiceOps serviceOps;
+    protected final ServiceOps serviceOps;
 
-    @Autowired
-    protected ExternalResourceProvider resourceProvider;
+    protected final ExternalResourceProvider resourceProvider;
 
-    @Autowired
-    protected AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider;
+    protected final AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider;
 
-    @Autowired
-    protected AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider;
+    protected final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider;
 
-    @Autowired
-    protected AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps;
+    protected final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps;
 
-    @Autowired
-    protected StatusProvider statusProvider;
+    protected final StatusProvider statusProvider;
 
-    @Autowired
-    protected VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider;
+    protected final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider;
 
-    @Autowired
-    protected ImplementationInfoProvider implementationInfoProvider;
+    protected final ImplementationInfoProvider implementationInfoProvider;
 
-    @Autowired
-    protected ApplicationContext ctx;
+    protected final ApplicationContext ctx;
+
+    public SyncopeWebApplication(
+            final ConsoleProperties props,
+            final ClassPathScanImplementationLookup lookup,
+            final ServiceOps serviceOps,
+            final ExternalResourceProvider resourceProvider,
+            final AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider,
+            final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider,
+            final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps,
+            final StatusProvider statusProvider,
+            final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider,
+            final ImplementationInfoProvider implementationInfoProvider,
+            final ApplicationContext ctx) {
+
+        this.props = props;
+        this.lookup = lookup;
+        this.serviceOps = serviceOps;
+        this.resourceProvider = resourceProvider;
+        this.anyDirectoryPanelAdditionalActionsProvider = anyDirectoryPanelAdditionalActionsProvider;
+        this.anyDirectoryPanelAdditionalActionLinksProvider = anyDirectoryPanelAdditionalActionLinksProvider;
+        this.anyWizardBuilderAdditionalSteps = anyWizardBuilderAdditionalSteps;
+        this.statusProvider = statusProvider;
+        this.virSchemaDetailsPanelProvider = virSchemaDetailsPanelProvider;
+        this.implementationInfoProvider = implementationInfoProvider;
+        this.ctx = ctx;
+    }
 
     @Override
     protected void init() {
@@ -316,4 +333,20 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
     public Collection<PolicyTabProvider> getPolicyTabProviders() {
         return ctx.getBeansOfType(PolicyTabProvider.class).values();
     }
+
+    public List<UserFormFinalizer> getFormFinalizers(final AjaxWizard.Mode mode) {
+        List<UserFormFinalizer> finalizers = new ArrayList<>();
+
+        lookup.getUserFormFinalizerClasses(mode).forEach(finalizer -> {
+            if (finalizer != null) {
+                try {
+                    finalizers.add(ClassUtils.getConstructorIfAvailable(finalizer).newInstance());
+                } catch (Exception e) {
+                    LOG.error("Could not instantiate {}", finalizer, e);
+                }
+            }
+        });
+
+        return finalizers;
+    }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserFormFinalizerUtils.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserFormFinalizerUtils.java
deleted file mode 100644
index fe11de401d..0000000000
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserFormFinalizerUtils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.wizards.any;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.ClassUtils;
-
-public final class UserFormFinalizerUtils {
-
-    private static final Logger LOG = LoggerFactory.getLogger(UserFormFinalizerUtils.class);
-
-    @Autowired
-    private ClassPathScanImplementationLookup lookup;
-
-    public List<UserFormFinalizer> getFormFinalizers(final AjaxWizard.Mode mode) {
-        List<UserFormFinalizer> finalizers = new ArrayList<>();
-
-        lookup.getUserFormFinalizerClasses(mode).forEach(applier -> {
-            if (applier != null) {
-                try {
-                    finalizers.add(ClassUtils.getConstructorIfAvailable(applier).newInstance());
-                } catch (Exception e) {
-                    LOG.error("Could not instantiate {}", applier, e);
-                }
-            }
-        });
-
-        return finalizers;
-    }
-}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 48125daecc..da44e19d72 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -22,9 +22,9 @@ import java.io.Serializable;
 import java.util.List;
 import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.console.rest.UserRestClient;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
 import org.apache.syncope.client.ui.commons.layout.UserForm;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
@@ -90,8 +90,7 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
                 result = new ProvisioningResult<>();
                 result.setEntity(inner);
             } else {
-                List<UserFormFinalizer> finalizers = ApplicationContextProvider.getApplicationContext().
-                        getBean(UserFormFinalizerUtils.class).getFormFinalizers(this.mode);
+                List<UserFormFinalizer> finalizers = SyncopeWebApplication.get().getFormFinalizers(mode);
 
                 finalizers.forEach(finalizer -> finalizer.beforeUpdate(userUR.getKey()));
 
diff --git a/client/idrepo/console/src/main/resources/META-INF/spring.factories b/client/idrepo/console/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..6357f8ae6c
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.client.console.ConsoleContext
diff --git a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
index 4b7d50caa0..861d54cabe 100644
--- a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
+++ b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java
@@ -53,7 +53,6 @@ import org.apache.syncope.client.console.commons.PreviewUtils;
 import org.apache.syncope.client.console.commons.StatusProvider;
 import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.wizards.any.UserFormFinalizerUtils;
 import org.apache.syncope.client.lib.AuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
@@ -78,6 +77,7 @@ import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.apache.wicket.util.tester.WicketTester;
 import org.junit.jupiter.api.BeforeAll;
 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -155,11 +155,6 @@ public abstract class AbstractTest {
             return new PreviewUtils();
         }
 
-        @Bean
-        public UserFormFinalizerUtils userFormFinalizerUtils() {
-            return new UserFormFinalizerUtils();
-        }
-
         @Bean
         public ExternalResourceProvider resourceProvider() {
             return new IdRepoExternalResourceProvider();
@@ -203,6 +198,24 @@ public abstract class AbstractTest {
 
     public static class TestSyncopeWebApplication extends SyncopeWebApplication {
 
+        public TestSyncopeWebApplication(
+                final ConsoleProperties props,
+                final ClassPathScanImplementationLookup lookup,
+                final ServiceOps serviceOps,
+                final ExternalResourceProvider resourceProvider,
+                final AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider,
+                final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider,
+                final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps,
+                final StatusProvider statusProvider,
+                final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider,
+                final ImplementationInfoProvider implementationInfoProvider,
+                final ApplicationContext ctx) {
+
+            super(props, lookup, serviceOps, resourceProvider, anyDirectoryPanelAdditionalActionsProvider,
+                    anyDirectoryPanelAdditionalActionLinksProvider, anyWizardBuilderAdditionalSteps, statusProvider,
+                    virSchemaDetailsPanelProvider, implementationInfoProvider, ctx);
+        }
+
         public interface SyncopeServiceClient extends SyncopeService, Client {
         }
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserContext.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserContext.java
new file mode 100644
index 0000000000..6bd8a74e3e
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserContext.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser;
+
+import org.apache.syncope.client.enduser.commons.PreviewUtils;
+import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
+import org.apache.syncope.client.ui.commons.MIMETypesLoader;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+public class EnduserContext {
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
+        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
+        lookup.load();
+        return lookup;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public MIMETypesLoader mimeTypesLoader() {
+        MIMETypesLoader mimeTypesLoader = new MIMETypesLoader();
+        mimeTypesLoader.load();
+        return mimeTypesLoader;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public PreviewUtils previewUtils() {
+        return new PreviewUtils();
+    }
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
index d51fa88687..7036996eb2 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -21,10 +21,7 @@ package org.apache.syncope.client.enduser;
 import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
 import java.util.Map;
 import org.apache.syncope.client.enduser.actuate.SyncopeEnduserInfoContributor;
-import org.apache.syncope.client.enduser.commons.PreviewUtils;
 import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
-import org.apache.syncope.client.ui.commons.MIMETypesLoader;
 import org.apache.syncope.client.ui.commons.actuate.SyncopeCoreHealthIndicator;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
@@ -38,6 +35,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.ResourceLoader;
 
 @SpringBootApplication(exclude = {
     ErrorMvcAutoConfiguration.class,
@@ -59,15 +57,22 @@ public class SyncopeEnduserApplication extends SpringBootServletInitializer {
                 sources(SyncopeEnduserApplication.class);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public ApplicationContextProvider applicationContextProvider() {
-        return new ApplicationContextProvider();
+    public SyncopeWebApplication syncopeWebApplication(
+            final ResourceLoader resourceLoader,
+            final EnduserProperties props,
+            final ClassPathScanImplementationLookup lookup,
+            final ServiceOps serviceOps) {
+
+        return new SyncopeWebApplication(resourceLoader, props, lookup, serviceOps);
     }
 
     @ConditionalOnMissingBean
     @Bean
-    public SyncopeCoreHealthIndicator syncopeCoreHealthIndicator(final ServiceOps serviceOps,
-                                                                 final EnduserProperties props) {
+    public SyncopeCoreHealthIndicator syncopeCoreHealthIndicator(
+            final ServiceOps serviceOps, final EnduserProperties props) {
+
         return new SyncopeCoreHealthIndicator(
                 serviceOps,
                 props.getAnonymousUser(),
@@ -81,28 +86,6 @@ public class SyncopeEnduserApplication extends SpringBootServletInitializer {
         return new SyncopeEnduserInfoContributor(enduserProperties);
     }
 
-    @ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
-    @Bean
-    public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
-        ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
-        lookup.load();
-        return lookup;
-    }
-
-    @ConditionalOnMissingBean(name = "mimeTypesLoader")
-    @Bean
-    public MIMETypesLoader mimeTypesLoader() {
-        MIMETypesLoader mimeTypesLoader = new MIMETypesLoader();
-        mimeTypesLoader.load();
-        return mimeTypesLoader;
-    }
-
-    @ConditionalOnMissingBean(name = "previewUtils")
-    @Bean
-    public PreviewUtils previewUtils() {
-        return new PreviewUtils();
-    }
-
     @Bean
     public KeymasterStart keymasterStart() {
         return new KeymasterStart(NetworkService.Type.ENDUSER);
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index 205b440b65..c7dda3204c 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -63,11 +63,8 @@ import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ResourceLoader;
-import org.springframework.stereotype.Component;
 
-@Component
 public class SyncopeWebApplication extends WicketBootStandardWebApplication {
 
     protected static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class);
@@ -81,20 +78,28 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
         return (SyncopeWebApplication) WebApplication.get();
     }
 
-    @Autowired
-    protected ResourceLoader resourceLoader;
+    protected final ResourceLoader resourceLoader;
 
-    @Autowired
-    protected EnduserProperties props;
+    protected final EnduserProperties props;
 
-    @Autowired
-    protected ClassPathScanImplementationLookup lookup;
+    protected final ClassPathScanImplementationLookup lookup;
 
-    @Autowired
-    protected ServiceOps serviceOps;
+    protected final ServiceOps serviceOps;
 
     protected UserFormLayoutInfo customFormLayout;
 
+    public SyncopeWebApplication(
+            final ResourceLoader resourceLoader,
+            final EnduserProperties props,
+            final ClassPathScanImplementationLookup lookup,
+            final ServiceOps serviceOps) {
+
+        this.resourceLoader = resourceLoader;
+        this.props = props;
+        this.lookup = lookup;
+        this.serviceOps = serviceOps;
+    }
+
     @Override
     protected void init() {
         super.init();
@@ -261,11 +266,11 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
     public boolean isCaptchaEnabled() {
         return props.isCaptcha();
     }
-    
+
     public boolean isReportPropagationErrors() {
         return props.isReportPropagationErrors();
     }
-    
+
     public boolean isReportPropagationErrorDetails() {
         return props.isReportPropagationErrorDetails();
     }
diff --git a/client/idrepo/enduser/src/main/resources/META-INF/spring.factories b/client/idrepo/enduser/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..8165f26596
--- /dev/null
+++ b/client/idrepo/enduser/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.syncope.client.enduser.EnduserContext
diff --git a/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java b/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java
index 4c09395e26..a209ca5949 100644
--- a/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java
+++ b/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java
@@ -60,6 +60,7 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ResourceLoader;
 
 public abstract class AbstractTest {
 
@@ -133,6 +134,15 @@ public abstract class AbstractTest {
 
     public static class TestSyncopeWebApplication extends SyncopeWebApplication {
 
+        public TestSyncopeWebApplication(
+                final ResourceLoader resourceLoader,
+                final EnduserProperties props,
+                final ClassPathScanImplementationLookup lookup,
+                final ServiceOps serviceOps) {
+
+            super(resourceLoader, props, lookup, serviceOps);
+        }
+
         public interface SyncopeServiceClient extends SyncopeService, Client {
         }
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
index 708b81c1b7..11b2b64758 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -40,9 +40,7 @@ import org.apache.syncope.client.console.commons.PreviewUtils;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
 import org.apache.syncope.client.console.pages.Login;
 import org.apache.syncope.client.console.topology.Topology;
-import org.apache.syncope.client.console.wizards.any.UserFormFinalizerUtils;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
 import org.apache.syncope.client.ui.commons.MIMETypesLoader;
 import org.apache.syncope.common.keymaster.client.self.SelfKeymasterClientContext;
 import org.apache.syncope.common.keymaster.client.zookeeper.ZookeeperKeymasterClientContext;
@@ -97,11 +95,6 @@ public abstract class AbstractConsoleITCase extends AbstractUIITCase {
             return new WicketEndpointRepositoryDefault();
         }
 
-        @Bean
-        public ApplicationContextProvider applicationContextProvider() {
-            return new ApplicationContextProvider();
-        }
-
         @Bean
         public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
             ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(Set.of(),
@@ -122,11 +115,6 @@ public abstract class AbstractConsoleITCase extends AbstractUIITCase {
             return new PreviewUtils();
         }
 
-        @Bean
-        public UserFormFinalizerUtils userFormFinalizerUtils() {
-            return new UserFormFinalizerUtils();
-        }
-
         @Bean
         public PolicyTabProvider idRepoPolicyTabProvider() {
             return new IdRepoPolicyTabProvider();
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/enduser/AbstractEnduserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/enduser/AbstractEnduserITCase.java
index 5f0f7e50b8..46d49d1ea7 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/enduser/AbstractEnduserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/enduser/AbstractEnduserITCase.java
@@ -38,7 +38,6 @@ import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
 import org.apache.syncope.client.enduser.pages.Login;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.client.ui.commons.ApplicationContextProvider;
 import org.apache.syncope.client.ui.commons.MIMETypesLoader;
 import org.apache.syncope.common.keymaster.client.self.SelfKeymasterClientContext;
 import org.apache.syncope.common.keymaster.client.zookeeper.ZookeeperKeymasterClientContext;
@@ -101,11 +100,6 @@ public abstract class AbstractEnduserITCase extends AbstractUIITCase {
             return new WicketEndpointRepositoryDefault();
         }
 
-        @Bean
-        public ApplicationContextProvider applicationContextProvider() {
-            return new ApplicationContextProvider();
-        }
-
         @Bean
         public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
             ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
diff --git a/pom.xml b/pom.xml
index 3027aad8ce..53493772e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1683,6 +1683,7 @@ under the License.
           <artifactId>maven-resources-plugin</artifactId>
           <version>3.3.0</version>
           <configuration>
+            <propertiesEncoding>${project.build.sourceEncoding}</propertiesEncoding>
             <useDefaultDelimiters>false</useDefaultDelimiters>
             <delimiters>
               <delimiter>${*}</delimiter>