diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml
new file mode 100644
index 000000000000..4c2b9ab262c0
--- /dev/null
+++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml
@@ -0,0 +1,99 @@
+
+
+
+
+ org.wso2.carbon.identity.framework
+ servlet-mgt
+ 7.7.124-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.identity.servlet.mgt
+ bundle
+ WSO2 Identity - Servlet Management Component
+ The Servlet Management backend component
+ http://wso2.org
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ provided
+
+
+ javax.servlet
+ javax.servlet-api
+ provided
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.jaxrs
+ jackson-jaxrs-json-provider
+ provided
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ${project.artifactId}
+
+ ${project.artifactId}
+
+ org.wso2.carbon.identity.servlet.mgt.*; version="${carbon.identity.package.export.version}"
+
+
+ javax.servlet.*; version="${imp.pkg.version.javax.servlet}"
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+ false
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+
+ ../../../spotbugs-exclude.xml
+ Max
+ High
+ true
+
+
+
+
+
+
diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java
new file mode 100644
index 000000000000..1b36883680d7
--- /dev/null
+++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java
@@ -0,0 +1,648 @@
+/*
+* Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+*
+* WSO2 LLC. 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.wso2.carbon.identity.servlet.mgt;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PrimitiveUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.ws.rs.core.Application;
+
+/**
+ * Custom CXFNonSpringJaxrsServlet to override the default behavior of CXFNonSpringJaxrsServlet.
+ */
+public class CustomCXFNonSpringJaxrsServlet extends CXFNonSpringServlet {
+
+ private static final long serialVersionUID = -8916352798780577499L;
+ private static final Logger LOG = LogUtils.getL7dLogger(CustomCXFNonSpringJaxrsServlet.class);
+ private static final String USER_MODEL_PARAM = "user.model";
+ private static final String SERVICE_ADDRESS_PARAM = "jaxrs.address";
+ private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore";
+ private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses";
+ private static final String PROVIDERS_PARAM = "jaxrs.providers";
+ private static final String FEATURES_PARAM = "jaxrs.features";
+ private static final String OUT_INTERCEPTORS_PARAM = "jaxrs.outInterceptors";
+ private static final String OUT_FAULT_INTERCEPTORS_PARAM = "jaxrs.outFaultInterceptors";
+ private static final String IN_INTERCEPTORS_PARAM = "jaxrs.inInterceptors";
+ private static final String INVOKER_PARAM = "jaxrs.invoker";
+ private static final String SERVICE_SCOPE_PARAM = "jaxrs.scope";
+ private static final String EXTENSIONS_PARAM = "jaxrs.extensions";
+ private static final String LANGUAGES_PARAM = "jaxrs.languages";
+ private static final String PROPERTIES_PARAM = "jaxrs.properties";
+ private static final String SCHEMAS_PARAM = "jaxrs.schemaLocations";
+ private static final String DOC_LOCATION_PARAM = "jaxrs.documentLocation";
+ private static final String STATIC_SUB_RESOLUTION_PARAM = "jaxrs.static.subresources";
+ private static final String SERVICE_SCOPE_SINGLETON = "singleton";
+ private static final String SERVICE_SCOPE_REQUEST = "prototype";
+ private static final String PARAMETER_SPLIT_CHAR = "class.parameter.split.char";
+ private static final String DEFAULT_PARAMETER_SPLIT_CHAR = ",";
+ private static final String SPACE_PARAMETER_SPLIT_CHAR = "space";
+ private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application";
+
+ private ClassLoader classLoader;
+ private final Application application;
+
+ public CustomCXFNonSpringJaxrsServlet(Application app) {
+
+ this.application = app;
+ }
+
+ public CustomCXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus) {
+
+ super(destinationRegistry, bus);
+ this.application = app;
+ }
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+
+ super.init(servletConfig);
+ if (this.getApplication() != null) {
+ this.createServerFromApplication(servletConfig);
+ } else {
+ String applicationClass = servletConfig.getInitParameter(JAXRS_APPLICATION_PARAM);
+ if (applicationClass != null) {
+ this.createServerFromApplication(applicationClass, servletConfig);
+ } else {
+ String splitChar = this.getParameterSplitChar(servletConfig);
+ JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
+ bean.setBus(this.getBus());
+ String address = servletConfig.getInitParameter(SERVICE_ADDRESS_PARAM);
+ if (address == null) {
+ address = "/";
+ }
+
+ bean.setAddress(address);
+ bean.setStaticSubresourceResolution(this.getStaticSubResolutionValue(servletConfig));
+ String modelRef = servletConfig.getInitParameter(USER_MODEL_PARAM);
+ if (modelRef != null) {
+ bean.setModelRef(modelRef.trim());
+ }
+
+ this.setDocLocation(bean, servletConfig);
+ this.setSchemasLocations(bean, servletConfig);
+ this.setAllInterceptors(bean, servletConfig, splitChar);
+ this.setInvoker(bean, servletConfig);
+ Map, Map>> resourceClasses = this.getServiceClasses(servletConfig,
+ modelRef != null, splitChar);
+ Map, ResourceProvider> resourceProviders = this.getResourceProviders(servletConfig,
+ resourceClasses);
+ List> providers = this.getProviders(servletConfig, splitChar);
+ bean.setResourceClasses(new ArrayList<>(resourceClasses.keySet()));
+ bean.setProviders(providers);
+
+ for (Map.Entry, ResourceProvider> entry : resourceProviders.entrySet()) {
+ bean.setResourceProvider(entry.getKey(), entry.getValue());
+ }
+
+ this.setExtensions(bean, servletConfig);
+ List extends Feature> features = this.getFeatures(servletConfig, splitChar);
+ bean.getFeatures().addAll(features);
+ bean.create();
+ }
+ }
+ }
+
+ protected String getParameterSplitChar(ServletConfig servletConfig) {
+
+ String param = servletConfig.getInitParameter(PARAMETER_SPLIT_CHAR);
+ return !StringUtils.isEmpty(param) && SPACE_PARAMETER_SPLIT_CHAR.equals(param.trim()) ? " "
+ : DEFAULT_PARAMETER_SPLIT_CHAR;
+ }
+
+ protected boolean getStaticSubResolutionValue(ServletConfig servletConfig) {
+
+ String param = servletConfig.getInitParameter(STATIC_SUB_RESOLUTION_PARAM);
+ return param != null && Boolean.parseBoolean(param.trim());
+ }
+
+ protected void setExtensions(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+
+ bean.setExtensionMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter(EXTENSIONS_PARAM))));
+ bean.setLanguageMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter(LANGUAGES_PARAM))));
+ Map properties = CastUtils.cast(parseMapSequence(
+ servletConfig.getInitParameter(PROPERTIES_PARAM)), String.class, Object.class);
+
+ //Custom impl to allow property values to be defined as system properties
+ for (Map.Entry entry : properties.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue().toString();
+
+ if (value.startsWith("{systemProperties")) {
+ int begin = value.indexOf("'");
+ int end = value.lastIndexOf("'");
+ String propertyKey = value.substring(begin + 1, end);
+ String systemPropValue = System.getProperty(propertyKey);
+ if (systemPropValue != null && !systemPropValue.isEmpty()) {
+ properties.put(key, systemPropValue);
+ }
+ }
+ }
+
+ if (!properties.isEmpty()) {
+ bean.getProperties(true).putAll(properties);
+ }
+ }
+
+ protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig,
+ String splitChar) throws ServletException {
+
+ this.setInterceptors(bean, servletConfig, OUT_INTERCEPTORS_PARAM, splitChar);
+ this.setInterceptors(bean, servletConfig, OUT_FAULT_INTERCEPTORS_PARAM, splitChar);
+ this.setInterceptors(bean, servletConfig, IN_INTERCEPTORS_PARAM, splitChar);
+ }
+
+ protected void setSchemasLocations(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+
+ String schemas = servletConfig.getInitParameter(SCHEMAS_PARAM);
+ if (schemas != null) {
+ String[] locations = schemas.split(" ");
+ List list = new ArrayList<>();
+
+ for (String loc : locations) {
+ String theLoc = loc.trim();
+ if (!theLoc.isEmpty()) {
+ list.add(theLoc);
+ }
+ }
+
+ if (!list.isEmpty()) {
+ bean.setSchemaLocations(list);
+ }
+ }
+ }
+
+ protected void setDocLocation(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+
+ String docLocation = servletConfig.getInitParameter(DOC_LOCATION_PARAM);
+ if (docLocation != null) {
+ bean.setDocLocation(docLocation);
+ }
+ }
+
+ protected void setInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String paramName,
+ String splitChar) throws ServletException {
+
+ String initParameter = servletConfig.getInitParameter(paramName);
+ if (initParameter != null) {
+ String[] values = initParameter.split(splitChar);
+ List> interceptors = new ArrayList<>();
+
+ for (String interceptorVal : values) {
+ Map> props = new HashMap<>();
+ String theValue = this.getClassNameAndProperties(interceptorVal, props);
+ if (!theValue.isEmpty()) {
+ try {
+ Class> intClass = this.loadClass(theValue, "Interceptor");
+ Object object = intClass.getDeclaredConstructor().newInstance();
+ this.injectProperties(object, props);
+ interceptors.add((Interceptor extends Message>) object);
+ } catch (ServletException exception) {
+ throw exception;
+ } catch (Exception exception) {
+ LOG.warning("Interceptor class " + theValue + " can not be created");
+ throw new ServletException(exception);
+ }
+ }
+ }
+
+ if (!interceptors.isEmpty()) {
+ if (OUT_INTERCEPTORS_PARAM.equals(paramName)) {
+ bean.setOutInterceptors(interceptors);
+ } else if (OUT_FAULT_INTERCEPTORS_PARAM.equals(paramName)) {
+ bean.setOutFaultInterceptors(interceptors);
+ } else {
+ bean.setInInterceptors(interceptors);
+ }
+ }
+ }
+ }
+
+ protected void setInvoker(JAXRSServerFactoryBean bean, ServletConfig servletConfig) throws ServletException {
+
+ String initParameter = servletConfig.getInitParameter(INVOKER_PARAM);
+ if (initParameter != null) {
+ Map> props = new HashMap<>();
+ String classNameAndProperties = this.getClassNameAndProperties(initParameter, props);
+ if (!classNameAndProperties.isEmpty()) {
+ try {
+ Class> intClass = this.loadClass(classNameAndProperties, "Invoker");
+ Object object = intClass.getDeclaredConstructor().newInstance();
+ this.injectProperties(object, props);
+ bean.setInvoker((Invoker) object);
+ } catch (ServletException exception) {
+ throw exception;
+ } catch (Exception exception) {
+ LOG.warning("Invoker class " + classNameAndProperties + " can not be created");
+ throw new ServletException(exception);
+ }
+ }
+ }
+ }
+
+ protected Map, Map>> getServiceClasses(ServletConfig servletConfig,
+ boolean modelAvailable, String splitChar)
+ throws ServletException {
+
+ String serviceBeans = servletConfig.getInitParameter(SERVICE_CLASSES_PARAM);
+ if (serviceBeans == null) {
+ if (modelAvailable) {
+ return Collections.emptyMap();
+ } else {
+ throw new ServletException("At least one resource class should be specified");
+ }
+ } else {
+ String[] classNames = serviceBeans.split(splitChar);
+ Map, Map>> classMapHashMap = new HashMap<>();
+
+ for (String cName : classNames) {
+ Map> props = new HashMap<>();
+ String theName = this.getClassNameAndProperties(cName, props);
+ if (!theName.isEmpty()) {
+ Class> cls = this.loadClass(theName);
+ classMapHashMap.put(cls, props);
+ }
+ }
+
+ if (classMapHashMap.isEmpty()) {
+ throw new ServletException("At least one resource class should be specified");
+ } else {
+ return classMapHashMap;
+ }
+ }
+ }
+
+ protected List getFeatures(ServletConfig servletConfig, String splitChar)
+ throws ServletException {
+
+ String featuresList = servletConfig.getInitParameter(FEATURES_PARAM);
+ if (featuresList == null) {
+ return Collections.emptyList();
+ } else {
+ String[] classNames = featuresList.split(splitChar);
+ List features = new ArrayList<>();
+
+ for (String cName : classNames) {
+ Map> props = new HashMap<>();
+ String classNameAndProperties = this.getClassNameAndProperties(cName, props);
+ if (!classNameAndProperties.isEmpty()) {
+ Class> cls = this.loadClass(classNameAndProperties);
+ if (Feature.class.isAssignableFrom(cls)) {
+ features.add((Feature) this.createSingletonInstance(cls, props, servletConfig));
+ }
+ }
+ }
+ return features;
+ }
+ }
+
+ protected List