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

kwin pushed a commit to branch feature/improve-exception-handling
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-packageinit.git

commit 5b5127cd7798581947ad3d7a590573ca2cb85202
Author: Konrad Windszus <[email protected]>
AuthorDate: Mon May 4 10:02:17 2026 +0200

    SLING-13185 Improve exception logging in ExecutionPlanRepoInitializer
    
    Include task index and package id in messages.
---
 .../impl/ExecutionPlanRepoInitializer.java         | 65 ++++++++++++----------
 .../ExecutionPlanRepoInitializerTest.java          |  4 +-
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/jcr/packageinit/impl/ExecutionPlanRepoInitializer.java
 
b/src/main/java/org/apache/sling/jcr/packageinit/impl/ExecutionPlanRepoInitializer.java
index 5278570..3ff61f9 100644
--- 
a/src/main/java/org/apache/sling/jcr/packageinit/impl/ExecutionPlanRepoInitializer.java
+++ 
b/src/main/java/org/apache/sling/jcr/packageinit/impl/ExecutionPlanRepoInitializer.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
+import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -33,6 +34,7 @@ import java.util.Set;
 import javax.jcr.Session;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.jackrabbit.vault.packaging.PackageException;
 import org.apache.jackrabbit.vault.packaging.registry.ExecutionPlan;
 import org.apache.jackrabbit.vault.packaging.registry.ExecutionPlanBuilder;
 import org.apache.jackrabbit.vault.packaging.registry.PackageRegistry;
@@ -126,39 +128,12 @@ public class ExecutionPlanRepoInitializer implements 
SlingRepositoryInitializer
                 PackageRegistry registry = (PackageRegistry) 
st.waitForService(0);
                 logger.info("PackageRegistry found - starting execution of 
execution plan");
                 
-                ExecutionPlanBuilder builder = registry.createExecutionPlan();
                 @SuppressWarnings("deprecation")
                 Session session = slingRepository.loginAdministrative(null);
                 try (BufferedWriter writer = new BufferedWriter(new 
FileWriter(statusFile))) {
+                    int planIndex = 0;
                     for (String plan : epCandidates) {
-                        builder.load(new 
ByteArrayInputStream(plan.getBytes(StandardCharsets.UTF_8)));
-                        builder.with(session);
-                        boolean planHasSnapshot = 
builder.preview().stream().anyMatch( p -> 
p.getVersionString().endsWith("-SNAPSHOT"));
-                        // by default check if either there are no SNAPSHOT 
versions ( e.g. all releases ) or if the config was set to not reinstall 
snapshots
-                        boolean checkIfCandidateWasProcessed = 
!planHasSnapshot || !config.reinstallSnapshots();
-                        if ( checkIfCandidateWasProcessed && 
isCandidateProcessed(plan, executedHashes)) {
-                            continue;
-                        }
-                        ExecutionPlan xplan = builder.execute();
-                        if (xplan.getTasks().size() > 0) {
-                            if (xplan.hasErrors()) {
-                                IllegalStateException ex = new 
IllegalStateException("Execution plan contained errors - cannot complete 
repository initialization.");
-                                for (PackageTask task : xplan.getTasks()) {
-                                    if 
(PackageTask.State.ERROR.equals(task.getState())){
-                                        ex.addSuppressed(task.getError());
-                                    }
-                                }
-                                throw ex;
-                            }
-                            logger.info("Execution plan executed with {} 
entries", xplan.getTasks().size());
-                        } else {
-                            logger.info("No tasks found in execution plan - no 
additional packages installed.");
-                        }
-                        
-                        // save hashes to file for crosscheck on subsequent 
startup to avoid double processing
-                        writer.write(String.valueOf(plan.hashCode()));
-                        writer.newLine();
-
+                        executePlan(executedHashes, registry, session, writer, 
plan, "Execution plan " + planIndex++);
                     }
                 } finally {
                     session.logout();
@@ -170,4 +145,36 @@ public class ExecutionPlanRepoInitializer implements 
SlingRepositoryInitializer
             logger.info("No execution plans configured - skipping init.");
         }
     }
+
+    private void executePlan(Set<Integer> executedHashes, PackageRegistry 
registry, Session session, BufferedWriter writer, String plan, String planLabel)
+            throws IOException, PackageException {
+        ExecutionPlanBuilder builder = registry.createExecutionPlan();
+        builder.load(new 
ByteArrayInputStream(plan.getBytes(StandardCharsets.UTF_8)));
+        builder.with(session);
+        boolean planHasSnapshot = builder.preview().stream().anyMatch( p -> 
p.getVersionString().endsWith("-SNAPSHOT"));
+        // by default check if either there are no SNAPSHOT versions ( e.g. 
all releases ) or if the config was set to not reinstall snapshots
+        boolean checkIfCandidateWasProcessed = !planHasSnapshot || 
!config.reinstallSnapshots();
+        if ( checkIfCandidateWasProcessed && isCandidateProcessed(plan, 
executedHashes)) {
+            return;
+        }
+        ExecutionPlan xplan = builder.execute();
+        if (xplan.getTasks().size() > 0) {
+            if (xplan.hasErrors()) {
+                IllegalStateException ex = new IllegalStateException(planLabel 
+ " contained errors - cannot complete repository initialization.");
+                for (PackageTask task : xplan.getTasks()) {
+                    if (PackageTask.State.ERROR.equals(task.getState())) {
+                        ex.addSuppressed(new PackageException("Error 
installing package " + task.getPackageId() + ": " + 
task.getError().getMessage(), task.getError()));
+                    }
+                }
+                throw ex;
+            }
+            logger.info(planLabel + " executed with {} entries", 
xplan.getTasks().size());
+        } else {
+            logger.info(planLabel + ": No tasks found - no additional packages 
installed.");
+        }
+        
+        // save hashes to file for crosscheck on subsequent startup to avoid 
double processing
+        writer.write(String.valueOf(plan.hashCode()));
+        writer.newLine();
+    }
 }
diff --git 
a/src/test/java/org/apache/sling/jcr/packageinit/ExecutionPlanRepoInitializerTest.java
 
b/src/test/java/org/apache/sling/jcr/packageinit/ExecutionPlanRepoInitializerTest.java
index c7a600c..6b76b48 100644
--- 
a/src/test/java/org/apache/sling/jcr/packageinit/ExecutionPlanRepoInitializerTest.java
+++ 
b/src/test/java/org/apache/sling/jcr/packageinit/ExecutionPlanRepoInitializerTest.java
@@ -220,6 +220,7 @@ public class ExecutionPlanRepoInitializerTest {
         
when(pt.getPackageId()).thenReturn(PackageId.fromString("test:test:1.0"));
         when(pt.getState()).thenReturn(State.ERROR);
         Throwable testEx = new Throwable("expectedException");
+        PackageException pkgEx = new PackageException("Error installing 
package test:test:1.0: " + testEx.getMessage(), testEx);
         when(pt.getError()).thenReturn(testEx);
         ptl.add(pt);
         when(xplan.getTasks()).thenReturn(ptl);
@@ -231,7 +232,8 @@ public class ExecutionPlanRepoInitializerTest {
         cdl.await(20500, TimeUnit.MILLISECONDS);
         verify(builder, times(1)).load(captor.capture());
         assertTrue("Expected IllegalStateException.",foundExceptions.get(0) 
instanceof IllegalStateException);
-        assertEquals(testEx.getMessage(), 
foundExceptions.get(0).getSuppressed()[0].getMessage());
+        assertEquals(pkgEx.getMessage(), 
foundExceptions.get(0).getSuppressed()[0].getMessage());
+        assertEquals(testEx.getMessage(), 
foundExceptions.get(0).getSuppressed()[0].getCause().getMessage());
 
         List<ILoggingEvent> logsList = listAppender.list;
         assertEquals("Waiting for PackageRegistry.", logsList.get(0)

Reply via email to