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

Reply via email to