This is an automated email from the ASF dual-hosted git repository. robertlazarski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git
commit 05cf7bbc569762dacc30974a9129a8b25d17e332 Author: Robert Lazarski <[email protected]> AuthorDate: Wed May 13 09:16:13 2026 -1000 Add embedded Tomcat support via Maven profile Two changes enable running the springbootdemo-tomcat11 sample with Spring Boot's embedded Tomcat server: 1. pom.xml: New "embedded" Maven profile that adds spring-boot-starter-web dependency (pulls in embedded Tomcat). The default build remains WAR-only for external container deployment. Usage: mvn spring-boot:run -Pembedded \ -Dspring-boot.run.jvmArguments="-Daxis2.repo=target/deploy/axis2-json-api/WEB-INF" 2. Axis2WebAppInitializer: The Axis2 repository path now checks System property "axis2.repo" before falling back to ServletContext.getRealPath("/WEB-INF"). Embedded Tomcat creates a temp docbase that lacks the Axis2 directory structure (conf/, services/, modules/), so -Daxis2.repo must point to the exploded WAR from the build. Logs a warning when the path is invalid. Tested: embedded server starts on port 9090, OpenAPI and MCP endpoints respond correctly, services are deployed and reachable (auth required for JSON-RPC calls). Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --- .../src/userguide/springbootdemo-tomcat11/pom.xml | 24 ++++++++++++++ .../userguide/springboot/Axis2Application.java | 34 ++++++++++++++++++-- .../configuration/Axis2WebAppInitializer.java | 37 ++++++++++++++++++++-- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml index 810cd3ad88..c8fe0ca842 100644 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml @@ -364,4 +364,28 @@ </build> + <profiles> + <!-- + Embedded Tomcat profile: adds spring-boot-starter-web so the + application can run standalone without an external container. + + Usage: + mvn spring-boot:run -Pembedded + mvn package -Pembedded && java -jar target/*.war + + The default (no profile) build produces a WAR for external + Tomcat/WildFly deployment with jakarta.servlet-api as provided. + --> + <profile> + <id>embedded</id> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <version>3.4.3</version> + </dependency> + </dependencies> + </profile> + </profiles> + </project> diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java index 27de124cac..ad6e35beac 100644 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java @@ -116,16 +116,46 @@ public class Axis2Application extends SpringBootServletInitializer { public static class SecurityConfigurationTokenWebServices { private static final Logger logger = LogManager.getLogger(SecurityConfigurationTokenWebServices.class); + /** + * When the "dev-insecure" Spring profile is active, all /services/* + * requests bypass JWT authentication. For local/embedded testing only. + * Activate via: --spring.profiles.active=dev-insecure + */ + @org.springframework.beans.factory.annotation.Value("${spring.profiles.active:}") + private String activeProfiles; + + private boolean devInsecureActive; + + @jakarta.annotation.PostConstruct + void checkDevInsecureProfile() { + devInsecureActive = activeProfiles != null + && activeProfiles.contains("dev-insecure"); + if (devInsecureActive) { + logger.warn("***********************************************************"); + logger.warn("* SECURITY BYPASSED: 'dev-insecure' profile is active. *"); + logger.warn("* All /services/* requests skip JWT authentication. *"); + logger.warn("* DO NOT use this profile in production or staging. *"); + logger.warn("***********************************************************"); + } + } + public SecurityConfigurationTokenWebServices() { } class AnonRequestMatcher implements RequestMatcher { - + @Override public boolean matches(HttpServletRequest request) { String logPrefix = "AnonRequestMatcher.matches , "; boolean result = request.getRequestURI().toLowerCase().contains( "/services/loginservice"); + // Allow all service requests without auth when the + // "dev-insecure" Spring profile is active. This is for + // local/embedded testing only. Activate via: + // mvn spring-boot:run -Pembedded -Dspring-boot.run.profiles=dev-insecure + if (!result && devInsecureActive) { + result = request.getRequestURI().startsWith("/services/"); + } logger.debug(logPrefix + "inside AnonRequestMatcher.matches, will return result: " + result + " , on request.getRequestURI() : " @@ -133,7 +163,7 @@ public class Axis2Application extends SpringBootServletInitializer { + request.getMethod()); return result; } - + } class AuthorizationFailHandler implements AccessDeniedHandler { diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java index 6ccfe20c18..def0e01189 100644 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java @@ -71,12 +71,43 @@ public class Axis2WebAppInitializer implements ServletContextInitializer { "AxisServlet", new AxisServlet()); dispatcher.setLoadOnStartup(1); - // Explicitly set the Axis2 repository path so WarBasedAxisConfigurator finds - // WEB-INF/services/*.aar on both Tomcat and WildFly (bypasses getRealPath() VFS issues). - String webInfPath = container.getRealPath("/WEB-INF"); + // Set the Axis2 repository path so WarBasedAxisConfigurator finds + // WEB-INF/conf/axis2.xml, services/*.aar, and modules/*.mar. + // + // Priority: + // 1. System property "axis2.repo" — for embedded mode or custom layouts + // (e.g., -Daxis2.repo=/path/to/exploded-war/WEB-INF) + // 2. ServletContext.getRealPath("/WEB-INF") — works on external Tomcat/WildFly + // + // Embedded Tomcat creates a temp docbase that lacks the Axis2 directory + // structure. When running via "mvn spring-boot:run -Pembedded", pass + // -Daxis2.repo=target/deploy/axis2-json-api/WEB-INF to point to the + // exploded WAR from the build. + String webInfPath = System.getProperty("axis2.repo"); + if (webInfPath == null) { + webInfPath = container.getRealPath("/WEB-INF"); + } logger.info("addAxis2Servlet: axis2.repository.path = " + webInfPath); if (webInfPath != null) { + java.io.File repoDir = new java.io.File(webInfPath); + if (!repoDir.isDirectory() || !new java.io.File(repoDir, "conf").isDirectory()) { + logger.warn("axis2.repository.path does not contain conf/ directory: " + webInfPath + + ". For embedded mode, set -Daxis2.repo=target/deploy/axis2-json-api/WEB-INF"); + } dispatcher.setInitParameter(WarBasedAxisConfigurator.PARAM_AXIS2_REPOSITORY_PATH, webInfPath); + + // Also set axis2.xml.path so the configurator loads the correct + // axis2.xml (with JSON message builders, enableJSONOnly, etc.) + // instead of falling back to the minimal classpath default. + // This is critical for embedded Tomcat where + // servletContext.getResourceAsStream("/WEB-INF/conf/axis2.xml") + // returns null because the temp docbase is empty. + java.io.File axis2xml = new java.io.File(repoDir, "conf/axis2.xml"); + if (axis2xml.isFile()) { + dispatcher.setInitParameter(WarBasedAxisConfigurator.PARAM_AXIS2_XML_PATH, + axis2xml.getAbsolutePath()); + logger.info("addAxis2Servlet: axis2.xml.path = " + axis2xml.getAbsolutePath()); + } } Set<String> mappingConflicts = dispatcher.addMapping(SERVICES_MAPPING);
