From eae62fe0f6b088d95f4d9f7a67f8c4cc447106ce Mon Sep 17 00:00:00 2001 From: Mark Waite Date: Thu, 5 Sep 2024 04:39:29 -0600 Subject: [PATCH] Replace JSR-305 annotations with spotbugs annotations (#71) * update parent and minimum jenkins version * use jenkins 2.414.3 * Replace JSR-305 annotations with spotbugs annotations Annotations for Nonnull, CheckForNull, and several others were proposed for Java as part of dormant Java specification request JSR-305. The proposal never became a part of standard Java. Jenkins plugins should switch from using JSR-305 annotations to use Spotbugs annotations that provide the same semantics. The [mailing list discussion](https://groups.google.com/g/jenkinsci-dev/c/uE1wwtVi1W0/m/gLxdEJmlBQAJ) from James Nord describes the affected annotations and why they should be replaced with annotations that are actively maintained. The ["Improve a plugin" tutorial](https://www.jenkins.io/doc/developer/tutorial-improve/replace-jsr-305-annotations/) provides instructions to perform this change. An [OpenRewrite recipe](https://docs.openrewrite.org/recipes/jenkins/javaxannotationstospotbugs) is also available and is even better than the tutorial. Confirmed that automated tests pass on Linux with Java 21. * Suppress spotbugs warning to not catch NPE * Rely on spotbugs configuration from parent pom * Use asm-api version provided by plugin BOM * Use latest plugin bom version * Remove uused code formatting version * Resolve hpi plugin warning for developer URL * Remove unused dependencies, reduce HPI file size * Use parent pom 4.82 https://github.com/jenkinsci/plugin-pom/releases/tag/plugin-4.82 * Use plugin parent pom 4.82 * Revert incorrect change to README URL * Remove extra blank line in test * Use consistent source format in test * Simplify the issue URL to modern URL and shorter string * Remove blue ocean from CI URL Blue Ocean enhancements have stopped. In the future, Blue Ocean will be removed from ci.jenkins.io. Better to prepare for that removal now. https://www.jenkins.io/doc/book/blueocean/ says: Blue Ocean status Blue Ocean will not receive further functionality updates. Blue Ocean will continue to provide easy-to-use Pipeline visualization, but it will not be enhanced further. It will only receive selective updates for significant security issues or functional defects. Alternative options for Pipeline visualization, such as the Pipeline: Stage View and Pipeline Graph View plugins, are available and offer some of the same functionality. While not complete replacements for Blue Ocean, contributions are encouraged from the community for continued development of these plugins. The Pipeline syntax snippet generator assists users as they define Pipeline steps with their arguments. It is the preferred tool for Jenkins Pipeline creation, as it provides online help for the Pipeline steps available in your Jenkins controller. It uses the plugins installed on your Jenkins controller to generate the Pipeline syntax. Refer to the Pipeline steps reference page for information on all available Pipeline steps. --------- Co-authored-by: Stefan Spieker --- pom.xml | 116 ++---------------- .../plugins/robot/RobotBuildAction.java | 2 +- .../hudson/plugins/robot/RobotPublisher.java | 8 +- .../java/hudson/plugins/robot/RobotStep.java | 7 +- .../plugins/robot/graph/RobotGraph.java | 1 - .../plugins/robot/graph/RobotGraphHelper.java | 3 +- .../plugins/robot/model/RobotCaseResult.java | 2 +- .../plugins/robot/model/RobotResult.java | 3 +- .../plugins/robot/model/RobotSuiteResult.java | 2 +- .../tokens/RobotReportLinkTokenMacro.java | 1 - .../plugins/robot/RobotProjectActionTest.java | 2 + .../robot/RobotPublisherSystemTest.java | 8 +- .../robot/SilentIncorrectnessListener.java | 2 +- .../robot/graph/RobotGraphHelperTest.java | 2 + .../robot/model/RobotSuiteResultTest.java | 4 +- 15 files changed, 35 insertions(+), 128 deletions(-) diff --git a/pom.xml b/pom.xml index 2087da7b..3a889fcf 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.jenkins-ci.plugins plugin - 4.32 + 4.82 robot @@ -37,18 +37,12 @@ - 2.346.3 - 1166.va_436e268e972 - 2.6 - 1.25 - 1229.v4880b_b_e905a_6 - 1.25.0 - 8 + 2.414.3 scm:git:ssh://github.com/jenkinsci/robot-plugin.git - scm:git:ssh://git@github.com/jenkinsci/robot-plugin.git + scm:git:git@github.com:jenkinsci/robot-plugin.git https://www.github.com/jenkinsci/robot-plugin HEAD @@ -56,8 +50,8 @@ io.jenkins.tools.bom - bom-2.346.x - 1742.vb_70478c1b_25f + bom-2.414.x + 2982.vdce2153031a_0 import pom @@ -76,7 +70,6 @@ org.jenkins-ci.plugins junit - ${junit.version} org.jenkins-ci.plugins.workflow @@ -119,19 +112,16 @@ org.jenkins-ci.plugins token-macro - ${token-macro.version} true io.jenkins.blueocean blueocean-rest-impl - ${blueocean-rest-impl.version} true org.jenkins-ci.plugins script-security - ${script-security.version} true @@ -145,90 +135,9 @@ 3.2.9 test - - org.apache.commons - commons-lang3 - 3.12.0 - - - - - org.jenkins-ci.plugins - jackson2-api - - - org.jenkins-ci.plugins - display-url-api - - - org.jenkins-ci.plugins - scm-api - - - org.jenkins-ci.plugins - variant - - - org.jenkins-ci.plugins - credentials - - - org.jenkins-ci - symbol-annotation - - - org.jenkins-ci.plugins - cloudbees-folder - io.jenkins.plugins - snakeyaml-api - - - org.slf4j - slf4j-api - - - org.slf4j - log4j-over-slf4j - - - org.slf4j - slf4j-jdk14 - test - - - org.slf4j - jcl-over-slf4j - - - org.ow2.asm - asm - - - org.ow2.asm - asm-tree - - - org.ow2.asm - asm-analysis - - - org.ow2.asm - asm-util - - - org.kohsuke - access-modifier-annotation - provided - - - org.jenkins-ci - annotation-indexer - - - com.github.spotbugs - spotbugs-annotations + commons-lang3-api @@ -253,15 +162,6 @@ - - com.github.spotbugs - spotbugs-maven-plugin - 3.1.12 - - Low - Max - - @@ -292,10 +192,10 @@ Jira - https://issues.jenkins-ci.org/issues/?jql=component%20%3D%20robot-plugin + https://issues.jenkins.io/issues/?jql=component%3Drobot-plugin Jenkins - https://ci.jenkins.io/blue/organizations/jenkins/Plugins%2Frobot-plugin + https://ci.jenkins.io/job/Plugins/job/robot-plugin/ diff --git a/src/main/java/hudson/plugins/robot/RobotBuildAction.java b/src/main/java/hudson/plugins/robot/RobotBuildAction.java index 72b9d1b5..056440d4 100755 --- a/src/main/java/hudson/plugins/robot/RobotBuildAction.java +++ b/src/main/java/hudson/plugins/robot/RobotBuildAction.java @@ -161,7 +161,7 @@ private XmlFile getDataFile() { private void cacheRobotResult(RobotResult result) { if (enableCache) { - resultReference = new WeakReference(result); + resultReference = new WeakReference<>(result); } } diff --git a/src/main/java/hudson/plugins/robot/RobotPublisher.java b/src/main/java/hudson/plugins/robot/RobotPublisher.java index a819989d..7ea6b63c 100755 --- a/src/main/java/hudson/plugins/robot/RobotPublisher.java +++ b/src/main/java/hudson/plugins/robot/RobotPublisher.java @@ -36,7 +36,6 @@ import java.util.ArrayList; import java.util.Collection; -import javax.annotation.Nonnull; import javax.servlet.ServletException; import jenkins.tasks.SimpleBuildStep; @@ -44,6 +43,9 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + public class RobotPublisher extends Recorder implements Serializable, MatrixAggregatable, SimpleBuildStep { @@ -250,7 +252,9 @@ protected RobotResult parse(String expandedTestResults, String expandedLogFileNa * {@inheritDoc} */ @Override - public void perform(Run build, @Nonnull FilePath workspace, @Nonnull EnvVars buildEnv, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException { + @SuppressFBWarnings(value = "DCN_NULLPOINTER_EXCEPTION", + justification = "Lower risk to suppress the warning than to stop catching the null pointer exception") + public void perform(Run build, @NonNull FilePath workspace, @NonNull EnvVars buildEnv, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException { if (build.getResult() != Result.ABORTED) { PrintStream logger = listener.getLogger(); logger.println(Messages.robot_publisher_started()); diff --git a/src/main/java/hudson/plugins/robot/RobotStep.java b/src/main/java/hudson/plugins/robot/RobotStep.java index 064eadd4..a3a9d914 100644 --- a/src/main/java/hudson/plugins/robot/RobotStep.java +++ b/src/main/java/hudson/plugins/robot/RobotStep.java @@ -3,8 +3,8 @@ import java.util.Set; import java.util.logging.Logger; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.workflow.steps.Step; @@ -20,7 +20,6 @@ import hudson.FilePath; import hudson.Launcher; import hudson.Util; -import hudson.matrix.MatrixBuild; import hudson.model.Run; import hudson.model.TaskListener; @@ -29,7 +28,7 @@ public class RobotStep extends Step { private static final Logger logger = Logger.getLogger(RobotStep.class.getName()); private @CheckForNull String archiveDirName; - private final @Nonnull String outputPath; + private final @NonNull String outputPath; private @CheckForNull String reportFileName; private @CheckForNull String logFileName; private @CheckForNull String outputFileName; diff --git a/src/main/java/hudson/plugins/robot/graph/RobotGraph.java b/src/main/java/hudson/plugins/robot/graph/RobotGraph.java index ec17be06..c5370e48 100755 --- a/src/main/java/hudson/plugins/robot/graph/RobotGraph.java +++ b/src/main/java/hudson/plugins/robot/graph/RobotGraph.java @@ -15,7 +15,6 @@ */ package hudson.plugins.robot.graph; -import hudson.model.AbstractBuild; import hudson.model.Run; import hudson.util.Graph; import hudson.util.ShiftedCategoryAxis; diff --git a/src/main/java/hudson/plugins/robot/graph/RobotGraphHelper.java b/src/main/java/hudson/plugins/robot/graph/RobotGraphHelper.java index f502bfac..498b9edc 100644 --- a/src/main/java/hudson/plugins/robot/graph/RobotGraphHelper.java +++ b/src/main/java/hudson/plugins/robot/graph/RobotGraphHelper.java @@ -85,6 +85,7 @@ public static RobotGraph createTestResultsGraphForTestObject(RobotTestObject roo upperbound = failed.intValue() + passed.intValue(); } + RobotBuildLabel label = new RobotBuildLabel(testObject,labelFormat); values.add(passed); @@ -119,7 +120,7 @@ public static RobotGraph createTestResultsGraphForTestObject(RobotTestObject roo * @return Created graph */ public static RobotGraph createDurationGraphForTestObject(RobotTestObject rootObject, boolean hd, int maxBuildsToShow, String labelFormat, boolean preview) { - DataSetBuilder builder = new DataSetBuilder(); + DataSetBuilder builder = new DataSetBuilder<>(); int scale = 1; int buildsLeftToShow = maxBuildsToShow > 0? maxBuildsToShow: -1; diff --git a/src/main/java/hudson/plugins/robot/model/RobotCaseResult.java b/src/main/java/hudson/plugins/robot/model/RobotCaseResult.java index 6b59328d..c136c5dc 100644 --- a/src/main/java/hudson/plugins/robot/model/RobotCaseResult.java +++ b/src/main/java/hudson/plugins/robot/model/RobotCaseResult.java @@ -204,7 +204,7 @@ public List getTags(){ public String getCommaSeparatedTags(){ List tags = getTags(); - if (tags.size()==0) + if (tags.isEmpty()) return ""; else { StringBuilder buf = new StringBuilder(); diff --git a/src/main/java/hudson/plugins/robot/model/RobotResult.java b/src/main/java/hudson/plugins/robot/model/RobotResult.java index 69e0ab99..0aed5d25 100755 --- a/src/main/java/hudson/plugins/robot/model/RobotResult.java +++ b/src/main/java/hudson/plugins/robot/model/RobotResult.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -222,7 +223,7 @@ public double getSkipPercentage() { private static double roundToDecimals(double value, int decimals){ BigDecimal bd = new BigDecimal(Double.toString(value)); - bd = bd.setScale(decimals, BigDecimal.ROUND_DOWN); + bd = bd.setScale(decimals, RoundingMode.DOWN); return bd.doubleValue(); } diff --git a/src/main/java/hudson/plugins/robot/model/RobotSuiteResult.java b/src/main/java/hudson/plugins/robot/model/RobotSuiteResult.java index 880f12ce..5c9f236b 100644 --- a/src/main/java/hudson/plugins/robot/model/RobotSuiteResult.java +++ b/src/main/java/hudson/plugins/robot/model/RobotSuiteResult.java @@ -438,7 +438,7 @@ public void tally(RobotBuildAction parentAction) { * @return Found Object */ public RobotTestObject findObjectById(String id) { - if(id.indexOf("/") >= 0){ + if(id.contains("/")){ String suiteName = id.substring(0, id.indexOf("/")); String childId = id.substring(id.indexOf("/")+1, id.length()); RobotSuiteResult suite = children.get(suiteName); diff --git a/src/main/java/hudson/plugins/robot/tokens/RobotReportLinkTokenMacro.java b/src/main/java/hudson/plugins/robot/tokens/RobotReportLinkTokenMacro.java index baad7890..f04faf51 100644 --- a/src/main/java/hudson/plugins/robot/tokens/RobotReportLinkTokenMacro.java +++ b/src/main/java/hudson/plugins/robot/tokens/RobotReportLinkTokenMacro.java @@ -5,7 +5,6 @@ import hudson.model.Run; import hudson.model.TaskListener; import hudson.model.AbstractBuild; -import hudson.model.Hudson; import hudson.plugins.robot.RobotBuildAction; import jenkins.model.Jenkins; diff --git a/src/test/java/hudson/plugins/robot/RobotProjectActionTest.java b/src/test/java/hudson/plugins/robot/RobotProjectActionTest.java index 313d0f5e..ab98c7f1 100644 --- a/src/test/java/hudson/plugins/robot/RobotProjectActionTest.java +++ b/src/test/java/hudson/plugins/robot/RobotProjectActionTest.java @@ -46,6 +46,8 @@ public void testShouldNotDisplayGraph() throws IOException { FreeStyleBuild build2 = spy(build); when(p.getLastBuild()).thenReturn(build2); doReturn(null).when(build2).getPreviousBuild(); + doReturn(null).when(build2).getAction(RobotBuildAction.class); + doReturn(null).when(build2).getAction(AggregatedRobotAction.class); RobotProjectAction action = new RobotProjectAction(p); assertFalse(action.isDisplayGraph()); diff --git a/src/test/java/hudson/plugins/robot/RobotPublisherSystemTest.java b/src/test/java/hudson/plugins/robot/RobotPublisherSystemTest.java index 3e8fd168..d7d671eb 100644 --- a/src/test/java/hudson/plugins/robot/RobotPublisherSystemTest.java +++ b/src/test/java/hudson/plugins/robot/RobotPublisherSystemTest.java @@ -25,9 +25,9 @@ import hudson.plugins.robot.model.RobotResult; import jenkins.model.Jenkins; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -44,9 +44,9 @@ import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.recipes.LocalData; -import com.gargoylesoftware.htmlunit.WebAssert; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.html.HtmlTable; +import org.htmlunit.WebAssert; +import org.htmlunit.html.HtmlPage; +import org.htmlunit.html.HtmlTable; public class RobotPublisherSystemTest { diff --git a/src/test/java/hudson/plugins/robot/SilentIncorrectnessListener.java b/src/test/java/hudson/plugins/robot/SilentIncorrectnessListener.java index 445393da..cb67d2a4 100644 --- a/src/test/java/hudson/plugins/robot/SilentIncorrectnessListener.java +++ b/src/test/java/hudson/plugins/robot/SilentIncorrectnessListener.java @@ -1,6 +1,6 @@ package hudson.plugins.robot; -import com.gargoylesoftware.htmlunit.IncorrectnessListener; +import org.htmlunit.IncorrectnessListener; /* * get rid of verbose warnings in system tests diff --git a/src/test/java/hudson/plugins/robot/graph/RobotGraphHelperTest.java b/src/test/java/hudson/plugins/robot/graph/RobotGraphHelperTest.java index d02950e9..2423a25e 100644 --- a/src/test/java/hudson/plugins/robot/graph/RobotGraphHelperTest.java +++ b/src/test/java/hudson/plugins/robot/graph/RobotGraphHelperTest.java @@ -50,6 +50,8 @@ protected void setUp() throws Exception { c.setTimeInMillis(0L); when(mockBuild1.getTimestamp()).thenReturn(c); when(mockBuild2.getTimestamp()).thenReturn(c); + when(mockBuild1.getTime()).thenReturn(c.getTime()); + when(mockBuild2.getTime()).thenReturn(c.getTime()); when(mockBuild1.getDisplayName()).thenReturn("1.2.3"); when(mockBuild2.getDisplayName()).thenReturn("3.2.1"); diff --git a/src/test/java/hudson/plugins/robot/model/RobotSuiteResultTest.java b/src/test/java/hudson/plugins/robot/model/RobotSuiteResultTest.java index ec0ff506..2440b808 100644 --- a/src/test/java/hudson/plugins/robot/model/RobotSuiteResultTest.java +++ b/src/test/java/hudson/plugins/robot/model/RobotSuiteResultTest.java @@ -47,7 +47,7 @@ public void shouldAcceptMultipleSuitesAsChildren(){ public void shouldReturnEmptyCollectionIfNoChildren(){ RobotSuiteResult result = new RobotSuiteResult(); assertNotNull("Return value was null", result.getChildSuites()); - assertTrue("Collection was not empty", result.getChildSuites().size() == 0); + assertEquals("Collection was not empty", 0, result.getChildSuites().size()); } @Test @@ -94,6 +94,6 @@ public void shouldAcceptMultipleCaseResults() { public void shouldReturnEmptyCollectionIfNoTestCases() throws DocumentException { RobotSuiteResult result = new RobotSuiteResult(); assertNotNull("Return value was null", result.getCaseResults()); - assertTrue("Collection was not empty", result.getCaseResults().size() == 0); + assertEquals("Collection was not empty", 0, result.getCaseResults().size()); } }