diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenPipelineException.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenPipelineException.java new file mode 100644 index 00000000..55e87e54 --- /dev/null +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenPipelineException.java @@ -0,0 +1,28 @@ +package org.jenkinsci.plugins.pipeline.maven; + +import static java.util.stream.Collectors.joining; + +import java.util.List; + +import org.jenkinsci.plugins.pipeline.maven.publishers.MavenPipelinePublisherException; + +public class MavenPipelineException extends RuntimeException { + + private static final long serialVersionUID = 4164091766147994893L; + + public MavenPipelineException(Throwable cause) { + super("Exception occured in withMaven pipeline step: " + cause.getMessage(), cause); + } + + public MavenPipelineException(List publishersExceptions) { + super(publishersExceptions.size() + " exceptions occured within the publishers of the withMaven pipeline step:\n" + + publishersExceptions.stream().map(e -> { + StringBuilder builder = new StringBuilder("- "); + builder.append(e.getMessage()); + if (e.getCause() != null) { + builder.append(": ").append(e.getCause().getMessage()); + } + return builder.toString(); + }).collect(joining())); + } +} diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenSpyLogProcessor.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenSpyLogProcessor.java index 57eed616..c8fa4c6c 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenSpyLogProcessor.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenSpyLogProcessor.java @@ -30,6 +30,7 @@ import jenkins.model.InterruptedBuildAction; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.pipeline.maven.publishers.JenkinsMavenEventSpyLogsPublisher; +import org.jenkinsci.plugins.pipeline.maven.publishers.MavenPipelinePublisherException; import org.jenkinsci.plugins.pipeline.maven.util.XmlUtils; import org.jenkinsci.plugins.workflow.steps.StepContext; import org.w3c.dom.Element; @@ -134,6 +135,7 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath listener.getLogger().println("[withMaven] Maven Publisher Strategy: " + publisherStrategy.getDescription()); } List mavenPublishers = publisherStrategy.buildPublishersList(options, listener); + List exceptions = new ArrayList<>(); for (MavenPublisher mavenPublisher : mavenPublishers) { String skipFileName = mavenPublisher.getDescriptor().getSkipFileName(); if (Boolean.TRUE.equals(mavenPublisher.isDisabled())) { @@ -156,26 +158,37 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBefore, TimeUnit.NANOSECONDS) + "ms."); Thread.currentThread().interrupt(); // set interrupt flag throw e; - } catch (IOException | RuntimeException e) { + } catch (MavenPipelinePublisherException e) { + exceptions.add(e); + } catch (Exception e) { PrintWriter error = listener.error("[withMaven] WARNING Exception executing Maven reporter '" + mavenPublisher.getDescriptor().getDisplayName() + "' / " + mavenPublisher.getDescriptor().getId() + "." + " Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org "); e.printStackTrace(error); + exceptions.add(new MavenPipelinePublisherException(mavenPublisher.getDescriptor().getDisplayName(), "", e)); } finally { durationInMillisPerPublisher.add(new AbstractMap.SimpleImmutableEntry(mavenPublisher.getDescriptor().getDisplayName(), TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBeforePublisher, TimeUnit.NANOSECONDS))); } } } + if (!exceptions.isEmpty()) { + throw new MavenPipelineException(exceptions); + } + } catch (MavenPipelineException e) { + throw e; } catch (SAXException e) { Run run = context.get(Run.class); + String msg = ""; if (run.getActions(InterruptedBuildAction.class).isEmpty()) { - listener.error("[withMaven] WARNING Exception parsing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " + - " Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org "); + msg = "[withMaven] WARNING Exception parsing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " + + " Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org "; } else { // job has been aborted (see InterruptedBuildAction) - listener.error("[withMaven] WARNING logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + " are invalid, probably due to the interruption of the job, ignore file."); + msg = "[withMaven] WARNING logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + " are invalid, probably due to the interruption of the job, ignore file."; } - listener.error(e.toString()); + PrintWriter errorWriter = listener.error(msg); + e.printStackTrace(errorWriter); + throw new MavenPipelineException(e); } catch (InterruptedException e) { PrintWriter errorWriter = listener.error("[withMaven] Processing of Maven build outputs interrupted after " + TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBefore, TimeUnit.NANOSECONDS) + "ms."); @@ -188,13 +201,13 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath PrintWriter errorWriter = listener.error("[withMaven] WARNING Exception processing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " + " Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org "); e.printStackTrace(errorWriter); + throw new MavenPipelineException(e); } finally { if (LOGGER.isLoggable(Level.INFO)) { listener.getLogger().println("[withMaven] Publishers: " + durationInMillisPerPublisher.stream().filter(entry -> entry.getValue() > 0). map(entry -> entry.getKey() + ": " + entry.getValue() + " ms"). collect(Collectors.joining(", "))); - } } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/dao/AbstractPipelineMavenPluginDao.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/dao/AbstractPipelineMavenPluginDao.java index 52d65c9a..390cdff6 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/dao/AbstractPipelineMavenPluginDao.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/dao/AbstractPipelineMavenPluginDao.java @@ -353,7 +353,7 @@ public void cleanup() { } } - protected long getOrCreateBuildPrimaryKey(String jobFullName, int buildNumber) { + protected synchronized long getOrCreateBuildPrimaryKey(String jobFullName, int buildNumber) { try (Connection cnn = ds.getConnection()) { cnn.setAutoCommit(false); diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/ConcordionTestsPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/ConcordionTestsPublisher.java index 49b5262b..1e9388c5 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/ConcordionTestsPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/ConcordionTestsPublisher.java @@ -142,9 +142,9 @@ public void process(@NonNull final StepContext context, @NonNull final Element m "\" with the following files: " + target.getReportFiles()); HtmlPublisher.publishReports(run, workspace, listener, Collections.singletonList(target), HtmlPublisher.class); } catch (final Exception e) { - listener.error("[withMaven] concordionPublisher - exception archiving Concordion reports: " + e + ". Failing the build."); + listener.error("[withMaven] concordionPublisher - exception archiving Concordion reports: " + e); LOGGER.log(Level.WARNING, "Exception processing Concordion reports archiving", e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("concordionPublisher", "archiving Concordion reports", e); } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/FindbugsAnalysisPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/FindbugsAnalysisPublisher.java index e5037367..9205323e 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/FindbugsAnalysisPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/FindbugsAnalysisPublisher.java @@ -235,13 +235,12 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE findBugsPublisher.perform(run, workspace, launcher, listener); } catch (Exception e) { listener.error("[withMaven] findbugsPublisher - exception archiving FindBugs results for Maven artifact " + mavenArtifact.toString() + " generated by " + - pluginInvocation + ": " + e + ". Failing the build."); + pluginInvocation + ": " + e); LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(findBugsTestEvent), e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("findbugsPublisher", + "archiving FindBugs results for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e); } - } - } /** diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/GeneratedArtifactsPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/GeneratedArtifactsPublisher.java index c4da8fb8..84231b60 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/GeneratedArtifactsPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/GeneratedArtifactsPublisher.java @@ -136,11 +136,13 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE // FINGERPRINT GENERATED MAVEN ARTIFACT if (!fingerprintFilesDisabled) { - FingerprintMap fingerprintMap = Jenkins.get().getFingerprintMap(); - for (Map.Entry artifactToFingerprint : artifactsToFingerPrint.entrySet()) { - String artifactPathInArchiveZone = artifactToFingerprint.getKey(); - String artifactMd5 = artifactToFingerprint.getValue(); - fingerprintMap.getOrCreate(run, artifactPathInArchiveZone, artifactMd5).addFor(run); + synchronized (this) { // to avoid exceptions when creating folders under Jenkins home + FingerprintMap fingerprintMap = Jenkins.get().getFingerprintMap(); + for (Map.Entry artifactToFingerprint : artifactsToFingerPrint.entrySet()) { + String artifactPathInArchiveZone = artifactToFingerprint.getKey(); + String artifactMd5 = artifactToFingerprint.getValue(); + fingerprintMap.getOrCreate(run, artifactPathInArchiveZone, artifactMd5).addFor(run); + } } // add action diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/InvokerRunsPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/InvokerRunsPublisher.java index 7afd9ce9..ee288231 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/InvokerRunsPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/InvokerRunsPublisher.java @@ -222,11 +222,11 @@ private void executeReporterForOldEvents(StepContext context, TaskListener liste try { archiver.perform(run, workspace, launcher, listener, node); } catch (Exception e) { - listener.error("[withMaven] invokerPublisher - exception archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId() + ": " + e + ". Failing the build."); + listener.error("[withMaven] invokerPublisher - exception archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId() + ": " + e); LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(testEvent), e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("invokerPublisher", + "archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e); } - } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JGivenTestsPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JGivenTestsPublisher.java index 23bfea1d..6175d0af 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JGivenTestsPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JGivenTestsPublisher.java @@ -117,9 +117,9 @@ public void process(@NonNull final StepContext context, @NonNull final Element m generator.perform(run, workspace, launcher, listener); } catch (final Exception e) { listener.error( - "[withMaven] jgivenPublisher - exception archiving JGiven reports: " + e + ". Failing the build."); + "[withMaven] jgivenPublisher - exception archiving JGiven reports: " + e); LOGGER.log(Level.WARNING, "Exception processing JGiven reports archiving", e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("jgivenPublisher", "archiving JGiven reports", e); } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JUnitUtils.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JUnitUtils.java index 9d54f941..4e383210 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JUnitUtils.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JUnitUtils.java @@ -100,9 +100,9 @@ static void archiveResults(final StepContext context, final JUnitResultArchiver run.setResult(Result.UNSTABLE); } } catch (RuntimeException e) { - listener.error("[withMaven] " + publisherName + " - exception archiving JUnit results " + testResults + ": " + e + ". Failing the build."); + listener.error("[withMaven] " + publisherName + " - exception archiving JUnit results " + testResults + ": " + e); LOGGER.log(Level.WARNING, "Exception processing " + testResults, e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException(publisherName, "archiving JUnit results " + testResults, e); } } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JacocoReportPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JacocoReportPublisher.java index 90db843a..228c2a52 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JacocoReportPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/JacocoReportPublisher.java @@ -220,9 +220,9 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE try { jacocoPublisher.perform(run, workspace, launcher, listener); } catch (Exception e) { - listener.error("[withMaven] jacocoPublisher - exception archiving JaCoCo results for " + jacocoReportDetails + ": " + e + ". Failing the build."); + listener.error("[withMaven] jacocoPublisher - exception archiving JaCoCo results for " + jacocoReportDetails + ": " + e); LOGGER.log(Level.WARNING, "Exception processing JaCoCo results", e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("jacocoPublisher", "archiving JaCoCo results for " + jacocoReportDetails, e); } } diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/MavenPipelinePublisherException.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/MavenPipelinePublisherException.java new file mode 100644 index 00000000..069c06a8 --- /dev/null +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/MavenPipelinePublisherException.java @@ -0,0 +1,24 @@ +package org.jenkinsci.plugins.pipeline.maven.publishers; + +public class MavenPipelinePublisherException extends RuntimeException { + + private static final long serialVersionUID = -5374242713614539146L; + + private String name; + + private String step; + + public MavenPipelinePublisherException(String name, String step, Throwable cause) { + super(name + " faced exception while " + step, cause); + this.name = name; + this.step = step; + } + + public String getName() { + return name; + } + + public String getStep() { + return step; + } +} diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/SpotBugsAnalysisPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/SpotBugsAnalysisPublisher.java index 6f09cbf5..01a20980 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/SpotBugsAnalysisPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/SpotBugsAnalysisPublisher.java @@ -236,15 +236,14 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE findBugsPublisher.perform(run, workspace, launcher, listener); } catch (Exception e) { listener.error("[withMaven] SpotBugsPublisher - exception archiving FindBugs results for Maven artifact " + mavenArtifact.toString() + " generated by " + - pluginInvocation + ": " + e + ". Failing the build."); + pluginInvocation + ": " + e); LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(findBugsTestEvent), e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("SpotBugsPublisher", + "archiving FindBugs results for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e); } - } - } - + @Symbol("spotbugsPublisher") @Extension public static class DescriptorImpl extends AbstractHealthAwarePublisher.DescriptorImpl { diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/TasksScannerPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/TasksScannerPublisher.java index 4628913a..587a69e2 100644 --- a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/TasksScannerPublisher.java +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/TasksScannerPublisher.java @@ -170,9 +170,9 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE try { tasksPublisher.perform(run, workspace, launcher, listener); } catch (Exception e) { - listener.error("[withMaven] openTasksPublisher - exception scanning tasks in " + pattern + ": " + e + ". Failing the build."); + listener.error("[withMaven] openTasksPublisher - exception scanning tasks in " + pattern + ": " + e); LOGGER.log(Level.WARNING, "Exception scanning tasks in " + pattern, e); - run.setResult(Result.FAILURE); + throw new MavenPipelinePublisherException("openTasksPublisher", "scanning tasks in " + pattern, e); } }