You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/08/09 06:38:42 UTC

(maven) 01/01: Migrate internal plumbing DEBUG statements to TRACE level

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

gnodet pushed a commit to branch feature/trace-level-migration
in repository https://gitbox.apache.org/repos/asf/maven.git

commit c0b643fe405f841dfe4a4780c5cb95143a4783c9
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sun Aug 9 08:38:29 2026 +0200

    Migrate internal plumbing DEBUG statements to TRACE level
    
    Separate core-developer diagnostics from plugin-developer diagnostics
    by moving 70+ DEBUG log statements to TRACE in areas that produce
    excessive noise under -X:
    
    - Lifecycle engine: reactor plan dumps, step scheduling/skipping
    - Classrealm: realm creation, population, foreign/parent imports
    - Cache internals: config resolution, cache creation, access stats
    - Resolver: artifact descriptor filtering, relocation tracing
    - Model builder: cache clearing, profile activation, repo merging
    - Plugin resolution: version/prefix resolution tracing
    
    Also adds TRACE to Slf4jConfiguration.Level enum so the logging
    system can be configured to TRACE via system property
    (-Dmaven.logger.defaultLogLevel=trace).
    
    DEBUG (-X) remains the right level for plugin development.
    TRACE is for Maven core developers diagnosing framework internals.
    
    Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
 .../org/apache/maven/cling/invoker/CliUtils.java   |  4 +-
 .../maven/cling/logging/Slf4jConfiguration.java    |  1 +
 .../logging/impl/MavenSimpleConfiguration.java     |  1 +
 .../cling/invoker/LookupInvokerLoggingTest.java    |  1 +
 .../maven/classrealm/DefaultClassRealmManager.java | 20 +++++-----
 .../lifecycle/internal/LifecycleDebugLogger.java   | 44 +++++++++++-----------
 .../multithreaded/MultiThreadedBuilder.java        |  4 +-
 .../internal/concurrent/BuildPlanExecutor.java     | 14 +++----
 .../internal/DefaultPluginPrefixResolver.java      |  4 +-
 .../internal/DefaultPluginVersionResolver.java     |  8 ++--
 .../classrealm/DefaultClassRealmManagerTest.java   | 28 +++++++-------
 .../impl/cache/CacheConfigurationResolver.java     | 12 +++---
 .../maven/impl/cache/DefaultRequestCache.java      | 28 +++++++-------
 .../maven/impl/model/DefaultModelBuilder.java      | 20 +++++-----
 .../resolver/DefaultArtifactDescriptorReader.java  | 10 ++---
 ...ributionManagementArtifactRelocationSource.java |  2 +-
 .../UserPropertiesArtifactRelocationSource.java    |  4 +-
 .../maven/impl/resolver/type/TypeDeriver.java      |  8 ++--
 18 files changed, 108 insertions(+), 105 deletions(-)

diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CliUtils.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CliUtils.java
index 834f017b2e..b7387a510b 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CliUtils.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CliUtils.java
@@ -115,7 +115,7 @@ public static UnaryOperator<String> or(UnaryOperator<String>... callbacks) {
     public static int toMavenExecutionRequestLoggingLevel(Slf4jConfiguration.Level level) {
         requireNonNull(level, "level");
         return switch (level) {
-            case DEBUG -> MavenExecutionRequest.LOGGING_LEVEL_DEBUG;
+            case TRACE, DEBUG -> MavenExecutionRequest.LOGGING_LEVEL_DEBUG;
             case INFO -> MavenExecutionRequest.LOGGING_LEVEL_INFO;
             case ERROR -> MavenExecutionRequest.LOGGING_LEVEL_ERROR;
         };
@@ -124,7 +124,7 @@ public static int toMavenExecutionRequestLoggingLevel(Slf4jConfiguration.Level l
     public static int toPlexusLoggingLevel(Slf4jConfiguration.Level level) {
         requireNonNull(level, "level");
         return switch (level) {
-            case DEBUG -> Logger.LEVEL_DEBUG;
+            case TRACE, DEBUG -> Logger.LEVEL_DEBUG;
             case INFO -> Logger.LEVEL_INFO;
             case ERROR -> Logger.LEVEL_ERROR;
         };
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/Slf4jConfiguration.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/Slf4jConfiguration.java
index 28fa676f54..ee6bffe95c 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/Slf4jConfiguration.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/Slf4jConfiguration.java
@@ -29,6 +29,7 @@ public interface Slf4jConfiguration {
      * Level
      */
     enum Level {
+        TRACE,
         DEBUG,
         INFO,
         ERROR
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/impl/MavenSimpleConfiguration.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/impl/MavenSimpleConfiguration.java
index 7bef54100b..7c4acb61e1 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/impl/MavenSimpleConfiguration.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/logging/impl/MavenSimpleConfiguration.java
@@ -37,6 +37,7 @@ public class MavenSimpleConfiguration extends BaseSlf4jConfiguration {
     public void setRootLoggerLevel(Level level) {
         String value =
                 switch (level) {
+                    case TRACE -> "trace";
                     case DEBUG -> "debug";
                     case INFO -> "info";
                     case ERROR -> "error";
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
index c76cd26764..2ada9f443d 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
@@ -158,6 +158,7 @@ public void setRootLoggerLevel(Level level) {
             // Simulate what MavenSimpleConfiguration does
             String value =
                     switch (level) {
+                        case TRACE -> "trace";
                         case DEBUG -> "debug";
                         case INFO -> "info";
                         case ERROR -> "error";
diff --git a/impl/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java b/impl/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
index 2ef0706a63..68bb5a7391 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
@@ -131,7 +131,7 @@ private ClassRealm newRealm(String id) {
                 try {
                     ClassRealm classRealm = world.newRealm(realmId, null);
 
-                    logger.debug("Created new class realm {}", realmId);
+                    logger.trace("Created new class realm {}", realmId);
 
                     return classRealm;
                 } catch (DuplicateRealmException e) {
@@ -177,8 +177,8 @@ private ClassRealm createRealm(
             for (Artifact artifact : artifacts) {
                 if (!isProvidedArtifact(artifact, v4api) && artifact.getFile() != null) {
                     constituents.add(new ArtifactClassRealmConstituent(artifact));
-                } else if (logger.isDebugEnabled()) {
-                    logger.debug("  Excluded: {}", getId(artifact));
+                } else if (logger.isTraceEnabled()) {
+                    logger.trace("  Excluded: {}", getId(artifact));
                 }
             }
         }
@@ -314,14 +314,14 @@ private void callDelegates(
     }
 
     private void populateRealm(ClassRealm classRealm, List<ClassRealmConstituent> constituents) {
-        logger.debug("Populating class realm {}", classRealm.getId());
+        logger.trace("Populating class realm {}", classRealm.getId());
 
         for (ClassRealmConstituent constituent : constituents) {
             File file = constituent.getFile();
 
-            if (logger.isDebugEnabled()) {
+            if (logger.isTraceEnabled()) {
                 String id = getId(constituent);
-                logger.debug("  Included: {}", id);
+                logger.trace("  Included: {}", id);
             }
 
             try {
@@ -335,23 +335,23 @@ private void populateRealm(ClassRealm classRealm, List<ClassRealmConstituent> co
 
     private void wireRealm(ClassRealm classRealm, List<String> parentImports, Map<String, ClassLoader> foreignImports) {
         if (foreignImports != null && !foreignImports.isEmpty()) {
-            logger.debug("Importing foreign packages into class realm {}", classRealm.getId());
+            logger.trace("Importing foreign packages into class realm {}", classRealm.getId());
 
             for (Map.Entry<String, ClassLoader> entry : foreignImports.entrySet()) {
                 ClassLoader importedRealm = entry.getValue();
                 String imp = entry.getKey();
 
-                logger.debug("  Imported: {} < {}", imp, getId(importedRealm));
+                logger.trace("  Imported: {} < {}", imp, getId(importedRealm));
 
                 classRealm.importFrom(importedRealm, imp);
             }
         }
 
         if (parentImports != null && !parentImports.isEmpty()) {
-            logger.debug("Importing parent packages into class realm {}", classRealm.getId());
+            logger.trace("Importing parent packages into class realm {}", classRealm.getId());
 
             for (String imp : parentImports) {
-                logger.debug("  Imported: {} < {}", imp, getId(classRealm.getParentClassLoader()));
+                logger.trace("  Imported: {} < {}", imp, getId(classRealm.getParentClassLoader()));
 
                 classRealm.importFromParent(imp);
             }
diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
index 6695b69a12..5954da00bc 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
@@ -49,7 +49,7 @@ public class LifecycleDebugLogger {
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
     public void debug(String s) {
-        logger.debug(s);
+        logger.trace(s);
     }
 
     public void info(String s) {
@@ -57,45 +57,45 @@ public void info(String s) {
     }
 
     public void debugReactorPlan(ProjectBuildList projectBuilds) {
-        if (!logger.isDebugEnabled()) {
+        if (!logger.isTraceEnabled()) {
             return;
         }
 
-        logger.debug("=== REACTOR BUILD PLAN ================================================");
+        logger.trace("=== REACTOR BUILD PLAN ================================================");
 
         for (Iterator<ProjectSegment> it = projectBuilds.iterator(); it.hasNext(); ) {
             ProjectSegment projectBuild = it.next();
 
-            logger.debug("Project: " + projectBuild.getProject().getId());
-            logger.debug("Tasks:   " + projectBuild.getTaskSegment().getTasks());
-            logger.debug("Style:   " + (projectBuild.getTaskSegment().isAggregating() ? "Aggregating" : "Regular"));
+            logger.trace("Project: " + projectBuild.getProject().getId());
+            logger.trace("Tasks:   " + projectBuild.getTaskSegment().getTasks());
+            logger.trace("Style:   " + (projectBuild.getTaskSegment().isAggregating() ? "Aggregating" : "Regular"));
 
             if (it.hasNext()) {
-                logger.debug("-----------------------------------------------------------------------");
+                logger.trace("-----------------------------------------------------------------------");
             }
         }
 
-        logger.debug("=======================================================================");
+        logger.trace("=======================================================================");
     }
 
     public void debugProjectPlan(MavenProject currentProject, MavenExecutionPlan executionPlan) {
-        if (!logger.isDebugEnabled()) {
+        if (!logger.isTraceEnabled()) {
             return;
         }
 
-        logger.debug("=== PROJECT BUILD PLAN ================================================");
-        logger.debug("Project:       " + BuilderCommon.getKey(currentProject));
+        logger.trace("=== PROJECT BUILD PLAN ================================================");
+        logger.trace("Project:       " + BuilderCommon.getKey(currentProject));
 
         debugDependencyRequirements(executionPlan.getMojoExecutions());
 
-        logger.debug("Repositories (dependencies): " + currentProject.getRemoteProjectRepositories());
-        logger.debug("Repositories (plugins)     : " + currentProject.getRemotePluginRepositories());
+        logger.trace("Repositories (dependencies): " + currentProject.getRemoteProjectRepositories());
+        logger.trace("Repositories (plugins)     : " + currentProject.getRemotePluginRepositories());
 
         for (ExecutionPlanItem mojoExecution : executionPlan) {
             debugMojoExecution(mojoExecution.getMojoExecution());
         }
 
-        logger.debug("=======================================================================");
+        logger.trace("=======================================================================");
     }
 
     private void debugMojoExecution(MojoExecution mojoExecution) {
@@ -106,7 +106,7 @@ private void debugMojoExecution(MojoExecution mojoExecution) {
         Map<String, List<MojoExecution>> forkedExecutions = mojoExecution.getForkedExecutions();
         if (!forkedExecutions.isEmpty()) {
             for (Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet()) {
-                logger.debug("--- init fork of " + fork.getKey() + " for " + mojoExecId + " ---");
+                logger.trace("--- init fork of " + fork.getKey() + " for " + mojoExecId + " ---");
 
                 debugDependencyRequirements(fork.getValue());
 
@@ -114,15 +114,15 @@ private void debugMojoExecution(MojoExecution mojoExecution) {
                     debugMojoExecution(forkedExecution);
                 }
 
-                logger.debug("--- exit fork of " + fork.getKey() + " for " + mojoExecId + " ---");
+                logger.trace("--- exit fork of " + fork.getKey() + " for " + mojoExecId + " ---");
             }
         }
 
-        logger.debug("-----------------------------------------------------------------------");
-        logger.debug("Goal:          " + mojoExecId);
-        logger.debug(
+        logger.trace("-----------------------------------------------------------------------");
+        logger.trace("Goal:          " + mojoExecId);
+        logger.trace(
                 "Style:         " + (mojoExecution.getMojoDescriptor().isAggregator() ? "Aggregating" : "Regular"));
-        logger.debug("Configuration: " + mojoExecution.getConfiguration());
+        logger.trace("Configuration: " + mojoExecution.getConfiguration());
     }
 
     private void debugDependencyRequirements(List<MojoExecution> mojoExecutions) {
@@ -143,7 +143,7 @@ private void debugDependencyRequirements(List<MojoExecution> mojoExecutions) {
             }
         }
 
-        logger.debug("Dependencies (collect): " + scopesToCollect);
-        logger.debug("Dependencies (resolve): " + scopesToResolve);
+        logger.trace("Dependencies (collect): " + scopesToCollect);
+        logger.trace("Dependencies (resolve): " + scopesToResolve);
     }
 }
diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
index c61889cda5..ef6909ebb9 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
@@ -135,7 +135,7 @@ private void multiThreadedProjectTaskSegmentBuild(
         // schedule independent projects (ordered by critical path priority)
         for (MavenProject mavenProject : analyzer.getRootSchedulableBuilds()) {
             ProjectSegment projectSegment = projectBuildList.get(mavenProject);
-            logger.debug("Scheduling: {}", projectSegment.getProject());
+            logger.trace("Scheduling: {}", projectSegment.getProject());
             Callable<ProjectSegment> cb =
                     createBuildCallable(rootSession, projectSegment, reactorContext, taskSegment, duplicateArtifactIds);
             service.submit(cb);
@@ -155,7 +155,7 @@ private void multiThreadedProjectTaskSegmentBuild(
                             analyzer.markAsFinished(projectBuild.getProject());
                     for (MavenProject mavenProject : newItemsThatCanBeBuilt) {
                         ProjectSegment scheduledDependent = projectBuildList.get(mavenProject);
-                        logger.debug("Scheduling: {}", scheduledDependent);
+                        logger.trace("Scheduling: {}", scheduledDependent);
                         Callable<ProjectSegment> cb = createBuildCallable(
                                 rootSession, scheduledDependent, reactorContext, taskSegment, duplicateArtifactIds);
                         service.submit(cb);
diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java
index cbd5ae2ed9..ebde4a5329 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java
@@ -394,7 +394,7 @@ private void processStep(BuildStep step) {
                 if (shouldExecute && anyPredecessorFailed) {
                     // We'll run the step but mark it as SKIPPED instead of SCHEDULED
                     if (step.status.compareAndSet(CREATED, SKIPPED)) {
-                        logger.debug(
+                        logger.trace(
                                 "Running after:* step {} for cleanup but marking it as SKIPPED because a predecessor failed",
                                 step);
                         executor.execute(() -> {
@@ -405,7 +405,7 @@ private void processStep(BuildStep step) {
                                 step.status.compareAndSet(SKIPPED, FAILED);
                                 // Store the exception in the step for handling in the TEARDOWN phase
                                 step.exception = e;
-                                logger.debug("Stored exception for step {} to be handled in TEARDOWN phase", step, e);
+                                logger.trace("Stored exception for step {} to be handled in TEARDOWN phase", step, e);
                                 // Let the scheduler handle after:* phases and TEARDOWN in the next cycle
                                 executePlan();
                             }
@@ -443,7 +443,7 @@ private void processStep(BuildStep step) {
 
                         // Store the exception in the step for handling in the TEARDOWN phase
                         step.exception = e;
-                        logger.debug("Stored exception for step {} to be handled in TEARDOWN phase", step, e);
+                        logger.trace("Stored exception for step {} to be handled in TEARDOWN phase", step, e);
 
                         // Let the scheduler handle after:* phases and TEARDOWN in the next cycle
                         executePlan();
@@ -453,18 +453,18 @@ private void processStep(BuildStep step) {
                 // Skip the step and provide a specific reason
                 if (!shouldExecute) {
                     if (status.isHalted()) {
-                        logger.debug("Skipping step {} because the build is halted", step);
+                        logger.trace("Skipping step {} because the build is halted", step);
                     } else if (status.isBlackListed(step.project)) {
-                        logger.debug("Skipping step {} because the project is blacklisted", step);
+                        logger.trace("Skipping step {} because the project is blacklisted", step);
                     } else if (TEARDOWN.equals(step.name)) {
                         // This should never happen given we always process TEARDOWN steps
                         logger.warn("Unexpected skipping of TEARDOWN step {}", step);
                     } else {
-                        logger.debug("Skipping step {} because a dependency has failed", step);
+                        logger.trace("Skipping step {} because a dependency has failed", step);
                     }
                 } else {
                     // Skip because predecessors failed or were skipped
-                    logger.debug(
+                    logger.trace(
                             "Skipping step {} because one or more predecessors did not execute successfully", step);
                 }
                 // Recursively call executePlan to process steps that depend on this one
diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java
index 4bd4f51379..389a077a65 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java
@@ -88,7 +88,7 @@ public DefaultPluginPrefixResolver(
 
     @Override
     public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFoundForPrefixException {
-        logger.debug("Resolving plugin prefix {} from {}", request.getPrefix(), request.getPluginGroups());
+        logger.trace("Resolving plugin prefix {} from {}", request.getPrefix(), request.getPluginGroups());
 
         Model pom = request.getPom();
         Build build = pom != null ? pom.getBuild() : null;
@@ -132,7 +132,7 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo
                     request.getRepositorySession().getLocalRepository(),
                     request.getRepositories());
         } else {
-            logger.debug(
+            logger.trace(
                     "Resolved plugin prefix {} to {}:{} from repository {}",
                     request.getPrefix(),
                     result.getGroupId(),
diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
index b2afbb073e..7d1f6be264 100644
--- a/impl/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
@@ -106,7 +106,7 @@ public PluginVersionResult resolve(PluginVersionRequest request) throws PluginVe
             if (result == null) {
                 result = resolveFromRepository(request);
 
-                logger.debug(
+                logger.trace(
                         "Resolved plugin version for {}:{} to {} from repository {}",
                         request.getGroupId(),
                         request.getArtifactId(),
@@ -115,7 +115,7 @@ public PluginVersionResult resolve(PluginVersionRequest request) throws PluginVe
 
                 cache.putIfAbsent(key, result);
             } else {
-                logger.debug(
+                logger.trace(
                         "Reusing cached resolved plugin version for {}:{} to {} from POM {}",
                         request.getGroupId(),
                         request.getArtifactId(),
@@ -123,7 +123,7 @@ public PluginVersionResult resolve(PluginVersionRequest request) throws PluginVe
                         request.getPom());
             }
         } else {
-            logger.debug(
+            logger.trace(
                     "Reusing cached resolved plugin version for {}:{} to {} from POM {}",
                     request.getGroupId(),
                     request.getArtifactId(),
@@ -282,7 +282,7 @@ private boolean isCompatible(PluginVersionRequest request, String version) {
             pluginDescriptor = pluginManager.getPluginDescriptor(
                     plugin, request.getRepositories(), request.getRepositorySession());
         } catch (PluginResolutionException e) {
-            logger.debug("Ignoring unresolvable plugin version {}", version, e);
+            logger.trace("Ignoring unresolvable plugin version {}", version, e);
             return false;
         } catch (Exception e) {
             // ignore for now and delay failure to higher level processing
diff --git a/impl/maven-core/src/test/java/org/apache/maven/classrealm/DefaultClassRealmManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/classrealm/DefaultClassRealmManagerTest.java
index 411a483b22..36eefd5eeb 100644
--- a/impl/maven-core/src/test/java/org/apache/maven/classrealm/DefaultClassRealmManagerTest.java
+++ b/impl/maven-core/src/test/java/org/apache/maven/classrealm/DefaultClassRealmManagerTest.java
@@ -95,9 +95,9 @@ private Model newTestModel() {
     }
 
     @Test
-    void testDebugEnabled() throws PlexusContainerException {
+    void testTraceEnabled() throws PlexusContainerException {
         Logger logger = mock(Logger.class);
-        when(logger.isDebugEnabled()).thenReturn(true);
+        when(logger.isTraceEnabled()).thenReturn(true);
 
         DefaultClassRealmManager classRealmManager;
         ClassRealm classRealm;
@@ -122,18 +122,18 @@ void testDebugEnabled() throws PlexusContainerException {
                 classRealm.getURLs()[0].getPath().endsWith("local/repository/some/path"),
                 "ClassRealm URL should end with local repository path");
 
-        verifier.verify(logger, calls(1)).debug("Importing foreign packages into class realm {}", "maven.api");
-        verifier.verify(logger, calls(1)).debug("  Imported: {} < {}", "group1:artifact1", "test");
-        verifier.verify(logger, calls(1)).debug("  Excluded: {}", "group1:artifact2:ext:classifier1:null");
+        verifier.verify(logger, calls(1)).trace("Importing foreign packages into class realm {}", "maven.api");
+        verifier.verify(logger, calls(1)).trace("  Imported: {} < {}", "group1:artifact1", "test");
+        verifier.verify(logger, calls(1)).trace("  Excluded: {}", "group1:artifact2:ext:classifier1:null");
         verifier.verify(logger, calls(1))
-                .debug("Populating class realm {}", "project>modelGroup1:modelArtifact1:modelVersion1");
-        verifier.verify(logger, calls(1)).debug("  Included: {}", "group1:artifact1:ext:classifier1:null");
+                .trace("Populating class realm {}", "project>modelGroup1:modelArtifact1:modelVersion1");
+        verifier.verify(logger, calls(1)).trace("  Included: {}", "group1:artifact1:ext:classifier1:null");
     }
 
     @Test
-    void testDebugDisabled() throws PlexusContainerException {
+    void testTraceDisabled() throws PlexusContainerException {
         Logger logger = mock(Logger.class);
-        when(logger.isDebugEnabled()).thenReturn(false);
+        when(logger.isTraceEnabled()).thenReturn(false);
 
         DefaultClassRealmManager classRealmManager;
         ClassRealm classRealm;
@@ -158,11 +158,11 @@ void testDebugDisabled() throws PlexusContainerException {
                 classRealm.getURLs()[0].getPath().endsWith("local/repository/some/path"),
                 "ClassRealm URL should end with local repository path");
 
-        verifier.verify(logger, calls(1)).debug("Importing foreign packages into class realm {}", "maven.api");
-        verifier.verify(logger, calls(1)).debug("  Imported: {} < {}", "group1:artifact1", "test");
+        verifier.verify(logger, calls(1)).trace("Importing foreign packages into class realm {}", "maven.api");
+        verifier.verify(logger, calls(1)).trace("  Imported: {} < {}", "group1:artifact1", "test");
         verifier.verify(logger, calls(1))
-                .debug("Populating class realm {}", "project>modelGroup1:modelArtifact1:modelVersion1");
-        verifier.verify(logger, never()).debug("  Included: {}", "group1:artifact1:ext:classifier1:null");
-        verifier.verify(logger, never()).debug("  Excluded: {}", "group1:artifact2:ext:classifier1:null");
+                .trace("Populating class realm {}", "project>modelGroup1:modelArtifact1:modelVersion1");
+        verifier.verify(logger, never()).trace("  Included: {}", "group1:artifact1:ext:classifier1:null");
+        verifier.verify(logger, never()).trace("  Excluded: {}", "group1:artifact2:ext:classifier1:null");
     }
 }
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/CacheConfigurationResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/CacheConfigurationResolver.java
index d0b162ba0f..eaaf1f857c 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/CacheConfigurationResolver.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/CacheConfigurationResolver.java
@@ -103,7 +103,7 @@ public static CacheConfig resolveConfig(Request<?> req, Session session) {
             if (selector.matches(req)) {
                 if (mergedConfig == null) {
                     mergedConfig = selector.config();
-                    LOGGER.debug(
+                    LOGGER.trace(
                             "Cache config for {}: matched selector '{}' with config {}",
                             req.getClass().getSimpleName(),
                             selector,
@@ -111,7 +111,7 @@ public static CacheConfig resolveConfig(Request<?> req, Session session) {
                 } else {
                     PartialCacheConfig previousConfig = mergedConfig;
                     mergedConfig = mergedConfig.mergeWith(selector.config());
-                    LOGGER.debug(
+                    LOGGER.trace(
                             "Cache config for {}: merged selector '{}' with previous config {} -> {}",
                             req.getClass().getSimpleName(),
                             selector,
@@ -134,7 +134,7 @@ public static CacheConfig resolveConfig(Request<?> req, Session session) {
                 finalConfig =
                         new CacheConfig(finalConfig.scope(), finalConfig.referenceType(), keyRefType, valueRefType);
             }
-            LOGGER.debug("Final cache config for {}: {}", req.getClass().getSimpleName(), finalConfig);
+            LOGGER.trace("Final cache config for {}: {}", req.getClass().getSimpleName(), finalConfig);
             return finalConfig;
         }
 
@@ -142,7 +142,7 @@ public static CacheConfig resolveConfig(Request<?> req, Session session) {
         if (legacyRetention != null) {
             CacheConfig config = new CacheConfig(
                     legacyRetention, getDefaultReferenceType(legacyRetention), keyRefType, valueRefType);
-            LOGGER.debug(
+            LOGGER.trace(
                     "Cache config for {}: {} (legacy CacheMetadata)",
                     req.getClass().getSimpleName(),
                     config);
@@ -152,14 +152,14 @@ public static CacheConfig resolveConfig(Request<?> req, Session session) {
         if (keyRefType != null && valueRefType != null) {
             CacheConfig config = new CacheConfig(
                     CacheConfig.DEFAULT.scope(), CacheConfig.DEFAULT.referenceType(), keyRefType, valueRefType);
-            LOGGER.debug(
+            LOGGER.trace(
                     "Cache config for {}: {} (with key/value refs)",
                     req.getClass().getSimpleName(),
                     config);
             return config;
         }
 
-        LOGGER.debug("Cache config for {}: {} (default)", req.getClass().getSimpleName(), CacheConfig.DEFAULT);
+        LOGGER.trace("Cache config for {}: {} (default)", req.getClass().getSimpleName(), CacheConfig.DEFAULT);
         return CacheConfig.DEFAULT;
     }
 
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/DefaultRequestCache.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/DefaultRequestCache.java
index 79a7e73a21..d463703d8b 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/DefaultRequestCache.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/DefaultRequestCache.java
@@ -215,8 +215,8 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
         // Debug logging to verify reference types (disabled)
         // System.err.println("DEBUG: Cache config for " + req.getClass().getSimpleName() + ": retention=" + retention
         //         + ", keyRef=" + keyReferenceType + ", valueRef=" + valueReferenceType);
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug(
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace(
                     "Cache config for {}: retention={}, keyRef={}, valueRef={}",
                     req.getClass().getSimpleName(),
                     retention,
@@ -240,7 +240,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             Cache<Object, Cache<Object, CachingSupplier<?, ?>>> caches = session.getData()
                     .computeIfAbsent(KEY, () -> {
                         if (config.hasSeparateKeyValueReferenceTypes()) {
-                            LOGGER.debug(
+                            LOGGER.trace(
                                     "Creating SESSION_SCOPED parent cache with key={}, value={}",
                                     keyReferenceType,
                                     valueReferenceType);
@@ -253,7 +253,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             // Use separate key/value reference types if configured
             if (config.hasSeparateKeyValueReferenceTypes()) {
                 cache = caches.computeIfAbsent(ROOT, k -> {
-                    LOGGER.debug(
+                    LOGGER.trace(
                             "Creating SESSION_SCOPED cache with key={}, value={}",
                             keyReferenceType,
                             valueReferenceType);
@@ -283,8 +283,8 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             }
             cacheType = "SESSION_SCOPED";
             // Debug logging for cache sizes
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug(
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace(
                         "Cache access: type={}, request={}, cacheSize={}, totalCaches={}, key={}",
                         cacheType,
                         req.getClass().getSimpleName(),
@@ -297,7 +297,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             Cache<Object, Cache<Object, CachingSupplier<?, ?>>> caches = session.getData()
                     .computeIfAbsent(KEY, () -> {
                         if (config.hasSeparateKeyValueReferenceTypes()) {
-                            LOGGER.debug(
+                            LOGGER.trace(
                                     "Creating REQUEST_SCOPED parent cache with key={}, value={}",
                                     keyReferenceType,
                                     valueReferenceType);
@@ -310,7 +310,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             // Use separate key/value reference types if configured
             if (config.hasSeparateKeyValueReferenceTypes()) {
                 cache = caches.computeIfAbsent(key, k -> {
-                    LOGGER.debug(
+                    LOGGER.trace(
                             "Creating REQUEST_SCOPED cache with key={}, value={}",
                             keyReferenceType,
                             valueReferenceType);
@@ -333,8 +333,8 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             cacheType = "REQUEST_SCOPED";
 
             // Debug logging for cache sizes
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug(
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace(
                         "Cache access: type={}, request={}, cacheSize={}, totalCaches={}, key={}",
                         cacheType,
                         req.getClass().getSimpleName(),
@@ -347,7 +347,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             Cache<Object, Cache<Object, CachingSupplier<?, ?>>> caches = session.getData()
                     .computeIfAbsent(KEY, () -> {
                         if (config.hasSeparateKeyValueReferenceTypes()) {
-                            LOGGER.debug(
+                            LOGGER.trace(
                                     "Creating PERSISTENT parent cache with key={}, value={}",
                                     keyReferenceType,
                                     valueReferenceType);
@@ -361,7 +361,7 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             // Use separate key/value reference types if configured
             if (config.hasSeparateKeyValueReferenceTypes()) {
                 cache = caches.computeIfAbsent(KEY, k -> {
-                    LOGGER.debug(
+                    LOGGER.trace(
                             "Creating PERSISTENT cache with key={}, value={}", keyReferenceType, valueReferenceType);
                     Cache<Object, CachingSupplier<?, ?>> newCache =
                             Cache.newCache(keyReferenceType, valueReferenceType, "RequestCache-PERSISTENT");
@@ -381,8 +381,8 @@ protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ,
             }
             cacheType = "PERSISTENT";
 
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug(
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace(
                         "Cache access: type={}, request={}, cacheSize={}",
                         cacheType,
                         req.getClass().getSimpleName(),
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
index 496eb81ad1..39c07d4029 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
@@ -254,7 +254,7 @@ public ModelBuilderResult build(ModelBuilderRequest request) throws ModelBuilder
                         clearRequestScopedCache(request);
                     } catch (Exception e) {
                         // Log but don't fail the build due to cache cleanup issues
-                        logger.debug("Failed to clear REQUEST_SCOPED cache for request: {}", request, e);
+                        logger.trace("Failed to clear REQUEST_SCOPED cache for request: {}", request, e);
                     }
                 }
                 RequestTraceHelper.exit(trace);
@@ -791,7 +791,7 @@ private Map<String, String> getPropertiesWithProfiles(Model model, Map<String, S
                 // If profile activation fails, log a warning but continue with base properties
                 // This ensures that CI-friendly versions still work even if profile activation has issues
                 logger.warn("Failed to activate profiles for CI-friendly version processing: {}", e.getMessage());
-                logger.debug("Profile activation failure details", e);
+                logger.trace("Profile activation failure details", e);
             }
 
             // System and user properties override everything (use request properties
@@ -1315,8 +1315,8 @@ Model resolveAndReadParentExternally(
                 var previousRepositories = repositories;
                 mergeRepositories(childModel, false);
                 if (!Objects.equals(previousRepositories, repositories)) {
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("Merging repositories from " + childModel.getId() + "\n"
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("Merging repositories from " + childModel.getId() + "\n"
                                 + repositories.stream()
                                         .map(Object::toString)
                                         .collect(Collectors.joining("\n", "    ", "")));
@@ -1538,7 +1538,7 @@ private Model readEffectiveModel() throws ModelBuilderException {
                 List<String> newRepos =
                         repositories.stream().map(Object::toString).toList();
                 if (!Objects.equals(oldRepos, newRepos)) {
-                    logger.debug("Replacing repositories from " + resultModel.getId() + "\n"
+                    logger.trace("Replacing repositories from " + resultModel.getId() + "\n"
                             + newRepos.stream().map(s -> "    " + s).collect(Collectors.joining("\n")));
                 }
             }
@@ -1580,7 +1580,7 @@ Model doReadFileModel(Set<Path> activeModelReads) throws ModelBuilderException {
             Path rootDirectory;
             boolean rootDirectoryFromSession = false;
             setSource(modelSource.getLocation());
-            logger.debug("Reading file model from " + modelSource.getLocation());
+            logger.trace("Reading file model from " + modelSource.getLocation());
             Path sourcePath = modelSource.getPath();
             Path normalizedPath = sourcePath != null ? sourcePath.normalize() : null;
             boolean trackRead = normalizedPath != null && activeModelReads.add(normalizedPath);
@@ -1792,7 +1792,7 @@ Model doReadFileModel(Set<Path> activeModelReads) throws ModelBuilderException {
                                                     : null)
                                     .build();
                         } catch (ModelBuilderException e) {
-                            logger.debug(
+                            logger.trace(
                                     "Could not read root model properties for CI-friendly version interpolation", e);
                         }
                     }
@@ -2365,7 +2365,7 @@ public Model buildRawModel(ModelBuilderRequest request) throws ModelBuilderExcep
                 clearRequestScopedCache(request);
             } catch (Exception e) {
                 // Log but don't fail the build due to cache cleanup issues
-                logger.debug("Failed to clear REQUEST_SCOPED cache for raw model request: {}", request, e);
+                logger.trace("Failed to clear REQUEST_SCOPED cache for raw model request: {}", request, e);
             }
             RequestTraceHelper.exit(trace);
         }
@@ -2715,8 +2715,8 @@ private <REQ extends Request<?>> void clearRequestScopedCache(REQ req) {
                     int beforeSize = map.size();
                     map.removeIf((k, v) -> !(k instanceof RgavCacheKey) && !(k instanceof SourceCacheKey));
                     int afterSize = map.size();
-                    if (logger.isDebugEnabled()) {
-                        logger.debug(
+                    if (logger.isTraceEnabled()) {
+                        logger.trace(
                                 "Cleared REQUEST_SCOPED cache for request: {}, removed {} entries, remaining entries: {}",
                                 outerRequestKey.getClass().getSimpleName(),
                                 afterSize - beforeSize,
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultArtifactDescriptorReader.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultArtifactDescriptorReader.java
index 4283cfceae..24c993d638 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultArtifactDescriptorReader.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultArtifactDescriptorReader.java
@@ -352,7 +352,7 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re
 
         for (org.apache.maven.api.model.Dependency dependency : model.getDependencies()) {
             if (hasUninterpolatedExpression(dependency)) {
-                logger.debug("Filtered dependency with uninterpolated expression: {}", dependency);
+                logger.trace("Filtered dependency with uninterpolated expression: {}", dependency);
                 continue;
             }
             result.addDependency(convert(dependency, stereotypes));
@@ -362,7 +362,7 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re
         if (dependencyManagement != null) {
             for (org.apache.maven.api.model.Dependency dependency : dependencyManagement.getDependencies()) {
                 if (hasUninterpolatedExpression(dependency)) {
-                    logger.debug("Filtered managed dependency with uninterpolated expression: {}", dependency);
+                    logger.trace("Filtered managed dependency with uninterpolated expression: {}", dependency);
                     continue;
                 }
                 result.addManagedDependency(convert(dependency, stereotypes));
@@ -440,21 +440,21 @@ private static boolean hasUninterpolatedExpression(org.apache.maven.api.model.De
     private void filterUninterpolated(ArtifactDescriptorResult result) {
         result.getRepositories().removeIf(repo -> {
             if (containsPlaceholder(repo.getId()) || containsPlaceholder(repo.getUrl())) {
-                logger.debug("Filtered repository with uninterpolated expression: {}", repo);
+                logger.trace("Filtered repository with uninterpolated expression: {}", repo);
                 return true;
             }
             return false;
         });
         result.getDependencies().removeIf(dep -> {
             if (hasUninterpolatedExpression(dep.getArtifact())) {
-                logger.debug("Filtered dependency with uninterpolated expression: {}", dep);
+                logger.trace("Filtered dependency with uninterpolated expression: {}", dep);
                 return true;
             }
             return false;
         });
         result.getManagedDependencies().removeIf(dep -> {
             if (hasUninterpolatedExpression(dep.getArtifact())) {
-                logger.debug("Filtered managed dependency with uninterpolated expression: {}", dep);
+                logger.trace("Filtered managed dependency with uninterpolated expression: {}", dep);
                 return true;
             }
             return false;
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/DistributionManagementArtifactRelocationSource.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/DistributionManagementArtifactRelocationSource.java
index 2549b4f653..c8bab2c3f7 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/DistributionManagementArtifactRelocationSource.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/DistributionManagementArtifactRelocationSource.java
@@ -62,7 +62,7 @@ public Artifact relocatedTarget(
                         null,
                         relocation.getVersion(),
                         relocation.getMessage());
-                LOGGER.debug(
+                LOGGER.trace(
                         "The artifact {} has been relocated to {}: {}",
                         artifactDescriptorResult.getRequest().getArtifact(),
                         result,
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/UserPropertiesArtifactRelocationSource.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/UserPropertiesArtifactRelocationSource.java
index a667b2a286..e48130de5b 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/UserPropertiesArtifactRelocationSource.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/relocation/UserPropertiesArtifactRelocationSource.java
@@ -69,7 +69,7 @@ public Artifact relocatedTarget(
                 if (relocation.target == SENTINEL) {
                     String message = "The artifact " + original + " has been banned from resolution: "
                             + (relocation.global ? "User global ban" : "User project ban");
-                    LOGGER.debug(message);
+                    LOGGER.trace(message);
                     throw new ArtifactDescriptorException(artifactDescriptorResult, message);
                 }
                 Artifact result = new RelocatedArtifact(
@@ -80,7 +80,7 @@ public Artifact relocatedTarget(
                         isAny(relocation.target.getExtension()) ? null : relocation.target.getExtension(),
                         isAny(relocation.target.getVersion()) ? null : relocation.target.getVersion(),
                         relocation.global ? "User global relocation" : "User project relocation");
-                LOGGER.debug(
+                LOGGER.trace(
                         "The artifact {} has been relocated to {}: {}",
                         original,
                         result,
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/type/TypeDeriver.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/type/TypeDeriver.java
index 6343cd2cbf..e099fb7d6f 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/type/TypeDeriver.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/type/TypeDeriver.java
@@ -60,13 +60,13 @@ public class TypeDeriver implements DependencyGraphTransformer {
     @Override
     public DependencyNode transformGraph(DependencyNode root, DependencyGraphTransformationContext context) {
         ArtifactTypeRegistry registry = context.getSession().getArtifactTypeRegistry();
-        if (logger.isDebugEnabled()) {
+        if (logger.isTraceEnabled()) {
             StringBuilder sb = new StringBuilder();
             root.accept(new DependencyGraphDumper(
                     l -> sb.append(l).append("\n"),
                     DependencyGraphDumper.defaultsWith(
                             List.of(DependencyGraphDumper.artifactProperties(List.of(ArtifactProperties.TYPE))))));
-            logger.debug("TYPES: Before transform:\n {}", sb);
+            logger.trace("TYPES: Before transform:\n {}", sb);
         }
         root.accept(new TypeDeriverVisitor(registry));
         // Apply processor type info collected by TypeCollector before conflict resolution.
@@ -78,13 +78,13 @@ public DependencyNode transformGraph(DependencyNode root, DependencyGraphTransfo
         if (collectedProcessorTypes != null) {
             root.accept(new ProcessorTypeMerger(collectedProcessorTypes));
         }
-        if (logger.isDebugEnabled()) {
+        if (logger.isTraceEnabled()) {
             StringBuilder sb = new StringBuilder();
             root.accept(new DependencyGraphDumper(
                     l -> sb.append(l).append("\n"),
                     DependencyGraphDumper.defaultsWith(
                             List.of(DependencyGraphDumper.artifactProperties(List.of(ArtifactProperties.TYPE))))));
-            logger.debug("TYPES: After transform:\n {}", sb);
+            logger.trace("TYPES: After transform:\n {}", sb);
         }
         return root;
     }