diff --git a/.travis.yml b/.travis.yml index 38417456b7..f99f818794 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ install: - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ./gradlew :ui:jfxNative --stacktrace || ./gradlew --stacktrace ' script: - - ./gradlew checkstyleMain checkstyleTest pmdMain pmdTest jacocoTestReport jacocoRootReport test --stacktrace -Pheadless=true -PlogTests + - ./gradlew checkstyleMain checkstyleTest pmdMain pmdTest findbugsMain findbugsTest jacocoTestReport jacocoRootReport test --stacktrace -Pheadless=true -PlogTests after_success: - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then codecov ; fi diff --git a/appveyor.yml b/appveyor.yml index 39e840c521..c08dedf54a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ build_script: # to run your custom scripts instead of automatic tests test_script: - - gradlew.bat checkstyleMain checkstyleTest pmdMain pmdTest jacocoTestReport jacocoRootReport test --stacktrace -Pheadless=true -PlogTests + - gradlew.bat checkstyleMain checkstyleTest pmdMain pmdTest findbugsMain findbugsTest jacocoTestReport jacocoRootReport test --stacktrace -Pheadless=true -PlogTests platform: - x64 diff --git a/build.gradle b/build.gradle index a539d4037f..cdde67b931 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import groovy.xml.XmlUtil + buildscript { repositories { jcenter() @@ -85,13 +87,14 @@ def getVersionSimple = { -> } } -configure(allprojects - project(':ui:linuxLauncher')) { +configure(subprojects - project(':ui:linuxLauncher')) { apply plugin: 'java' apply plugin: 'application' apply plugin: 'jacoco' apply plugin: 'net.ltgt.errorprone' apply plugin: 'checkstyle' apply plugin: 'pmd' + apply plugin: 'findbugs' configurations.errorprone { resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.9' @@ -119,6 +122,30 @@ configure(allprojects - project(':ui:linuxLauncher')) { ruleSets = [] } + findbugs { + sourceSets = [sourceSets.main] + excludeFilter = new File(rootDir, "findBugsSuppressions.xml") + effort = "max" + } + + ext.printReportSafe = { xmlReport -> + if (xmlReport.exists()) { + def bugs = (new XmlParser().parse(xmlReport)).BugInstance + bugs.each { System.out.println(new XmlUtil().serialize(it)) } + } + } + + task findbugsMainReport << { + printReportSafe(findbugsMain.reports.getXml().destination) + } + + task findbugsTestReport << { + printReportSafe(findbugsTest.reports.getXml().destination) + } + + findbugsMain.finalizedBy findbugsMainReport + findbugsTest.finalizedBy findbugsTestReport + repositories { mavenCentral() jcenter() @@ -129,6 +156,7 @@ configure(allprojects - project(':ui:linuxLauncher')) { dependencies { + compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1' testCompile group: 'net.jodah', name: 'concurrentunit', version: '0.4.2' testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' testCompile group: 'junit', name: 'junit', version: '4.12' diff --git a/core/src/main/java/edu/wpi/grip/core/OperationDescription.java b/core/src/main/java/edu/wpi/grip/core/OperationDescription.java index d1872567a4..6647c3b996 100644 --- a/core/src/main/java/edu/wpi/grip/core/OperationDescription.java +++ b/core/src/main/java/edu/wpi/grip/core/OperationDescription.java @@ -9,6 +9,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; + import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java index 20db252038..433ccd06cb 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java @@ -191,7 +191,7 @@ public void perform() { continue; } - final double ratio = bb.width() / bb.height(); + final double ratio = (double) bb.width() / (double) bb.height(); if (ratio < minRatio || ratio > maxRatio) { continue; } diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java index 1709d2dc26..a30153bb9b 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java @@ -9,6 +9,8 @@ import com.google.common.collect.ImmutableList; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.bytedeco.javacpp.BytePointer; import org.bytedeco.javacpp.IntPointer; @@ -133,6 +135,8 @@ public class PublishVideoOperation implements Operation { }; @SuppressWarnings("JavadocMethod") + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", + justification = "Do not need to synchronize inside of a constructor") public PublishVideoOperation(InputSocket.Factory inputSocketFactory) { if (numSteps != 0) { throw new IllegalStateException("Only one instance of PublishVideoOperation may exist"); @@ -141,7 +145,7 @@ public PublishVideoOperation(InputSocket.Factory inputSocketFactory) { false)); this.qualitySocket = inputSocketFactory.create(SocketHints.Inputs .createNumberSliderSocketHint("Quality", 80, 0, 100)); - numSteps = numSteps + 1; + numSteps++; serverThread = new Thread(runServer, "Camera Server"); serverThread.setDaemon(true); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/ValveOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/ValveOperation.java index e2af95c3cc..aff111cc08 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/ValveOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/ValveOperation.java @@ -16,7 +16,7 @@ public class ValveOperation implements Operation { - public static OperationDescription DESCRIPTION = + public static final OperationDescription DESCRIPTION = OperationDescription.builder() .name("Valve") .summary("Toggle an output socket on or off using a boolean") diff --git a/core/src/main/java/edu/wpi/grip/core/operations/network/http/DataHandler.java b/core/src/main/java/edu/wpi/grip/core/operations/network/http/DataHandler.java index b5801e33ce..395e0b4e09 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/network/http/DataHandler.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/network/http/DataHandler.java @@ -12,6 +12,8 @@ import com.google.inject.Inject; import com.google.inject.Singleton; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.eclipse.jetty.server.Request; import java.io.IOException; @@ -69,6 +71,8 @@ public final class DataHandler extends PedanticHandler { } @Override + @SuppressFBWarnings(value = "UW_UNCOND_WAIT", + justification = "A bug in FindBugs. There is a condidtion (outside of the try)") protected void handleIfPassed(String target, Request baseRequest, HttpServletRequest request, diff --git a/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java b/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java index 1da37c7d1a..cb47c58755 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java +++ b/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java @@ -1,5 +1,7 @@ package edu.wpi.grip.core.util; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javax.annotation.Nullable; /** @@ -16,8 +18,11 @@ public final class SafeShutdown { * flagging a shutdown * that we can't control. */ + Runtime.getRuntime().addShutdownHook(new Thread() { @Override + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", + justification = "Static variable is volatile") public void run() { SafeShutdown.stopping = true; } diff --git a/core/src/test/java/edu/wpi/grip/core/ConnectionTest.java b/core/src/test/java/edu/wpi/grip/core/ConnectionTest.java index f05aa0d6e0..8b9922e562 100644 --- a/core/src/test/java/edu/wpi/grip/core/ConnectionTest.java +++ b/core/src/test/java/edu/wpi/grip/core/ConnectionTest.java @@ -69,7 +69,7 @@ public void testPipelineSaysConnectionIsInvalid() { ); } - private class MockPipeline extends Pipeline { + private static class MockPipeline extends Pipeline { } diff --git a/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java b/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java index 6b61d50751..7136833dfc 100644 --- a/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java +++ b/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java @@ -14,6 +14,9 @@ import com.google.common.eventbus.Subscribe; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.Service; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import net.jodah.concurrentunit.Waiter; import org.junit.After; import org.junit.Before; @@ -141,6 +144,8 @@ class ExceptionEventReceiver { private ExceptionEvent event; @Subscribe + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", + justification = "EventBus can call this method") public void onException(ExceptionEvent event) { this.event = event; callCount++; diff --git a/core/src/test/java/edu/wpi/grip/core/PipelineTest.java b/core/src/test/java/edu/wpi/grip/core/PipelineTest.java index a93a51a38a..e7f5445b55 100644 --- a/core/src/test/java/edu/wpi/grip/core/PipelineTest.java +++ b/core/src/test/java/edu/wpi/grip/core/PipelineTest.java @@ -381,7 +381,7 @@ public void testMoveStepToRight() { Arrays.asList(lowerStep, stepToMove, upperStep), pipeline.getSteps()); } - private class MockConnection extends Connection { + private static class MockConnection extends Connection { /** * @param pipeline The pipeline to create the connection inside of. diff --git a/core/src/test/java/edu/wpi/grip/core/http/GripServerTest.java b/core/src/test/java/edu/wpi/grip/core/http/GripServerTest.java index 149c6f8bd3..a3101c2af3 100644 --- a/core/src/test/java/edu/wpi/grip/core/http/GripServerTest.java +++ b/core/src/test/java/edu/wpi/grip/core/http/GripServerTest.java @@ -19,7 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; - +import java.nio.charset.StandardCharsets; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -71,12 +71,12 @@ public void testAddRemoveHandler() throws IOException { didRun[0] = true; }); instance.addHandler(h); - HttpResponse response = doPost(path, path.getBytes()); + HttpResponse response = doPost(path, path.getBytes(StandardCharsets.UTF_8)); EntityUtils.consume(response.getEntity()); assertTrue("Handler should have run", didRun[0]); didRun[0] = false; instance.removeHandler(h); - response = doPost(path, path.getBytes()); + response = doPost(path, path.getBytes(StandardCharsets.UTF_8)); EntityUtils.consume(response.getEntity()); assertFalse("Handler should not have run", didRun[0]); } @@ -89,7 +89,7 @@ public void testSuccessfulHandler() throws IOException { didRun[0] = true; }); instance.addHandler(h); - doPost(path, path.getBytes()); + doPost(path, path.getBytes(StandardCharsets.UTF_8)); assertTrue("Handler should have run on " + path, didRun[0]); } @@ -102,7 +102,7 @@ public void testUnsuccessfulPostHandler() throws Exception { throw new GripServerException("Expected"); }); instance.addHandler(h); - HttpResponse response = doPost(path, path.getBytes()); + HttpResponse response = doPost(path, path.getBytes(StandardCharsets.UTF_8)); assertEquals("Server should return an internal error (500)", 500, response.getStatusLine().getStatusCode()); diff --git a/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java b/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java index f04eb9cb82..fe6a00b893 100644 --- a/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java +++ b/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java @@ -17,6 +17,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -121,7 +122,7 @@ private HttpResponse doGet(String path) throws IOException { private HttpResponse doPost(String path, String text) throws IOException { HttpPost post = new HttpPost("http://localhost:" + server.getPort() + path); BasicHttpEntity httpEntity = new BasicHttpEntity(); - httpEntity.setContent(new ByteArrayInputStream(text.getBytes())); + httpEntity.setContent(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8))); post.setEntity(httpEntity); return client.execute(post); } diff --git a/core/src/test/java/edu/wpi/grip/core/http/NoContextHandlerTest.java b/core/src/test/java/edu/wpi/grip/core/http/NoContextHandlerTest.java index f17e890336..ed488ed74c 100644 --- a/core/src/test/java/edu/wpi/grip/core/http/NoContextHandlerTest.java +++ b/core/src/test/java/edu/wpi/grip/core/http/NoContextHandlerTest.java @@ -18,6 +18,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -71,7 +72,8 @@ public void tearDown() throws Exception { private CloseableHttpResponse sendHttpRequest(String path) throws IOException { HttpPost post = new HttpPost("http://localhost:" + getServerPort() + path); BasicHttpEntity httpEntity = new BasicHttpEntity(); - httpEntity.setContent(new ByteArrayInputStream("http_request_bytes".getBytes())); + httpEntity.setContent( + new ByteArrayInputStream("http_request_bytes".getBytes(StandardCharsets.UTF_8))); post.setEntity(httpEntity); return client.execute(post); } diff --git a/core/src/test/java/edu/wpi/grip/core/http/PedanticHandlerTest.java b/core/src/test/java/edu/wpi/grip/core/http/PedanticHandlerTest.java index 67d34c79e1..b95b88f663 100644 --- a/core/src/test/java/edu/wpi/grip/core/http/PedanticHandlerTest.java +++ b/core/src/test/java/edu/wpi/grip/core/http/PedanticHandlerTest.java @@ -16,6 +16,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -100,7 +101,8 @@ private static T[] arr(T... a) { private void sendHttpRequest(String path) throws IOException { HttpPost post = new HttpPost("http://localhost:" + getServerPort() + path); BasicHttpEntity httpEntity = new BasicHttpEntity(); - httpEntity.setContent(new ByteArrayInputStream("http_request_bytes".getBytes())); + httpEntity.setContent( + new ByteArrayInputStream("http_request_bytes".getBytes(StandardCharsets.UTF_8))); post.setEntity(httpEntity); HttpResponse resp = client.execute(post); EntityUtils.consume(resp.getEntity()); diff --git a/core/src/test/java/edu/wpi/grip/core/serialization/CompatibilityTest.java b/core/src/test/java/edu/wpi/grip/core/serialization/CompatibilityTest.java index e4e811d8b9..69f4f9b3df 100644 --- a/core/src/test/java/edu/wpi/grip/core/serialization/CompatibilityTest.java +++ b/core/src/test/java/edu/wpi/grip/core/serialization/CompatibilityTest.java @@ -16,10 +16,14 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.Writer; import java.net.URI; +import java.nio.charset.StandardCharsets; import static junit.framework.TestCase.assertEquals; @@ -60,7 +64,7 @@ public void setUp() throws Exception { //Open the project save file and read it into a string so that we can alter it File file = new File(fileName); - Reader temp = new FileReader(file); + Reader temp = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(temp); String line = ""; StringBuffer oldText = new StringBuffer(); @@ -72,10 +76,10 @@ public void setUp() throws Exception { // correct location of the test photo needed to the project file //Write the altered project file text - FileWriter writer2 = new FileWriter(file); - writer2.write(newText); + Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); + writer.write(newText); - writer2.close(); + writer.close(); //Open the test file as a project project.open(file); diff --git a/core/src/test/java/edu/wpi/grip/core/serialization/ProjectTest.java b/core/src/test/java/edu/wpi/grip/core/serialization/ProjectTest.java index e62021d756..013cd2f0eb 100644 --- a/core/src/test/java/edu/wpi/grip/core/serialization/ProjectTest.java +++ b/core/src/test/java/edu/wpi/grip/core/serialization/ProjectTest.java @@ -154,7 +154,6 @@ public void testSerializePipelineWithStepsAndConnections() throws Exception { final Step step2 = stepFactory.create(pythonAdditionOperationFromURL); final InputSocket a2 = (InputSocket) step2.getInputSockets().get(0); final InputSocket b2 = (InputSocket) step2.getInputSockets().get(1); - final OutputSocket sum2 = (OutputSocket) step2.getOutputSockets().get(0); a1.setValue(12); b1.setValue(34); diff --git a/core/src/test/java/edu/wpi/grip/core/sockets/SocketTest.java b/core/src/test/java/edu/wpi/grip/core/sockets/SocketTest.java index 449d269e12..f4740e0436 100644 --- a/core/src/test/java/edu/wpi/grip/core/sockets/SocketTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sockets/SocketTest.java @@ -6,6 +6,8 @@ import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.junit.Before; import org.junit.Test; @@ -52,6 +54,8 @@ public void testSocketChangedEvent() throws Exception { final boolean[] handled = new boolean[]{false}; final Double[] value = new Double[]{0.0}; Object eventHandler = new Object() { + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", + justification = "This method is called by Guava's EventBus") @Subscribe public void onSocketChanged(SocketChangedEvent e) { handled[0] = true; @@ -74,6 +78,8 @@ public void testSocketPreview() { final boolean[] handled = new boolean[]{false}; Object eventHandler = new Object() { + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", + justification = "This method is called by Guava's EventBus") @Subscribe public void onSocketPreviewed(SocketPreviewChangedEvent e) { handled[0] = true; diff --git a/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java b/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java index 1b4e554c56..1c1fc1f151 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java @@ -15,6 +15,8 @@ import com.google.inject.Guice; import com.google.inject.Injector; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import net.jodah.concurrentunit.Waiter; import org.bytedeco.javacpp.indexer.Indexer; @@ -65,6 +67,8 @@ public void setUp() throws Exception { final EventBus eventBus = new EventBus(); class UnhandledExceptionWitness { + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", + justification = "This method is called by Guava's EventBus") @Subscribe public void onUnexpectedThrowableEvent(UnexpectedThrowableEvent event) { event.handleSafely((throwable, message, isFatal) -> { @@ -254,7 +258,7 @@ public FrameGrabber create(String addressProperty) throws MalformedURLException } } - class MockFrameGrabber extends FrameGrabber { + static class MockFrameGrabber extends FrameGrabber { private final Frame frame; private final Indexer frameIdx; private boolean shouldThrowAtStart = false; @@ -310,7 +314,7 @@ public void setShouldThrowAtStop(boolean shouldThrowAtStop) { } } - class MockFrameGrabberFactory implements CameraSource.FrameGrabberFactory { + static class MockFrameGrabberFactory implements CameraSource.FrameGrabberFactory { private final MockFrameGrabber frameGrabber = new MockFrameGrabber(); @Override diff --git a/core/src/test/java/edu/wpi/grip/core/util/ExceptionWitnessTest.java b/core/src/test/java/edu/wpi/grip/core/util/ExceptionWitnessTest.java index 4cef964cff..50402b4668 100644 --- a/core/src/test/java/edu/wpi/grip/core/util/ExceptionWitnessTest.java +++ b/core/src/test/java/edu/wpi/grip/core/util/ExceptionWitnessTest.java @@ -77,7 +77,7 @@ private void fireAnError() { /** * Used to count the number of calls that ExceptionEvent and ExceptionClearedEvent fires. */ - private class TestWitnessListener { + private static class TestWitnessListener { private int errorRunCount = 0; private int clearRunCount = 0; private Optional errorWitnessObserver = Optional.empty(); diff --git a/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java b/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java index 13512efb3d..541f92ae01 100644 --- a/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java @@ -4,6 +4,8 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.Service; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -41,6 +43,8 @@ public class AutoRestartingServiceTest { private Throwable thrownByExecutionThread; private Executor exceptionCatchingExecutor; + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", + justification = "A JUnit rule -- used by JUnit") @Rule public Timeout timeout = new Timeout(10, TimeUnit.SECONDS); @@ -214,7 +218,7 @@ public void stopping(Service.State from) { /** * Records all instances of the object returned by {@link Supplier#get()} */ - private class RecordingSupplier implements Supplier { + private static class RecordingSupplier implements Supplier { private final LinkedList services = new LinkedList<>(); private final Supplier serviceSupplier; diff --git a/core/src/test/java/edu/wpi/grip/util/GripCoreTestModule.java b/core/src/test/java/edu/wpi/grip/util/GripCoreTestModule.java index 69bbd4ab42..ec4b4e7345 100644 --- a/core/src/test/java/edu/wpi/grip/util/GripCoreTestModule.java +++ b/core/src/test/java/edu/wpi/grip/util/GripCoreTestModule.java @@ -13,6 +13,8 @@ import com.google.common.eventbus.SubscriberExceptionContext; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; @@ -30,6 +32,8 @@ * that exceptions always get dumped for the test that has just run. */ public class GripCoreTestModule extends GripCoreModule { + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", + justification = "Member is volatile") private static volatile boolean instanceAlive = false; private final ConcurrentLinkedQueue threadExceptions = new diff --git a/findBugsSuppressions.xml b/findBugsSuppressions.xml new file mode 100644 index 0000000000..b5123c0a85 --- /dev/null +++ b/findBugsSuppressions.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/ui/src/main/java/edu/wpi/grip/ui/preview/BlobsSocketPreviewView.java b/ui/src/main/java/edu/wpi/grip/ui/preview/BlobsSocketPreviewView.java index 288081b3c6..b282252c85 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/preview/BlobsSocketPreviewView.java +++ b/ui/src/main/java/edu/wpi/grip/ui/preview/BlobsSocketPreviewView.java @@ -8,6 +8,8 @@ import com.google.common.eventbus.Subscribe; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javafx.application.Platform; import javafx.geometry.Orientation; import javafx.scene.control.CheckBox; @@ -38,7 +40,9 @@ public class BlobsSocketPreviewView extends SocketPreviewView { private final Mat tmp = new Mat(); private final GripPlatform platform; @SuppressWarnings("PMD.ImmutableField") - private boolean showInputImage; + @SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", + justification = "Do not need to synchronize inside of a constructor") + private boolean showInputImage = false; /** * @param socket An output socket to preview. diff --git a/ui/src/main/java/edu/wpi/grip/ui/preview/LinesSocketPreviewView.java b/ui/src/main/java/edu/wpi/grip/ui/preview/LinesSocketPreviewView.java index c79247d03c..85985464a6 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/preview/LinesSocketPreviewView.java +++ b/ui/src/main/java/edu/wpi/grip/ui/preview/LinesSocketPreviewView.java @@ -8,6 +8,8 @@ import com.google.common.eventbus.Subscribe; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import java.util.List; import javafx.application.Platform; import javafx.geometry.Orientation; @@ -40,7 +42,9 @@ public class LinesSocketPreviewView extends SocketPreviewView { private final Mat tmp = new Mat(); private final GripPlatform platform; @SuppressWarnings("PMD.ImmutableField") - private boolean showInputImage; + @SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", + justification = "Do not need to synchronize inside of a constructor") + private boolean showInputImage = false; /** * @param socket An output socket to preview. diff --git a/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java b/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java index 1ea7b749f1..4581a9bac5 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java @@ -16,6 +16,8 @@ import com.google.inject.Injector; import com.google.inject.util.Modules; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.junit.Test; import org.testfx.framework.junit.ApplicationTest; import org.testfx.util.WaitForAsyncUtils; @@ -23,7 +25,6 @@ import java.io.IOException; import java.util.Collections; import java.util.List; - import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; @@ -64,6 +65,8 @@ public void testPalette() { // Record when a a StepAddedEvent happens Step[] step = new Step[]{null}; eventBus.register(new Object() { + @SuppressFBWarnings(value = "UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", + justification = "This method is called by Guava's EventBus") @Subscribe public void onStepAdded(StepAddedEvent event) { step[0] = event.getStep(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java b/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java index 2dd5f5d5e5..6772999e73 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java @@ -61,7 +61,7 @@ public void testClickNext() { .isSelected()); } - class MockPreviousNext implements PreviousNext { + static class MockPreviousNext implements PreviousNext { private int index; diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java index 16eeb24937..9baac12eab 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java @@ -88,7 +88,7 @@ public void testCreatesSourceStarted() throws Exception { verifyThat("." + AddSourceButton.SOURCE_DIALOG_STYLE_CLASS, NodeMatchers.isNull()); } - class MockCameraSourceFactory implements CameraSource.Factory { + static class MockCameraSourceFactory implements CameraSource.Factory { private final EventBus eventBus; private Optional lastSourceCreated = Optional.empty(); @@ -176,7 +176,7 @@ public void testCreatesSourceStartedFails() throws Exception { .isRunning()); } - class MockCameraSourceFactory implements CameraSource.Factory { + static class MockCameraSourceFactory implements CameraSource.Factory { private final EventBus eventBus; private Optional lastSourceCreated = Optional.empty(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java index 7044d5d0fc..2c2246e5e9 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java @@ -68,7 +68,7 @@ public void testInitiallyPreviewedOutputSocket() { initiallyPreviewedOutputSocketController.previewButton().isSelected()); } - private class InitiallyPreviewedOutputSocket extends MockOutputSocket { + private static class InitiallyPreviewedOutputSocket extends MockOutputSocket { public InitiallyPreviewedOutputSocket(String socketName) { super(socketName); this.setPreviewed(true); diff --git a/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java b/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java index 5cbeb9f3fa..ff6ab75196 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java @@ -110,7 +110,7 @@ public void testTryToModifyManagedList() throws Exception { }); } - private class MockPane extends Pane { + private static class MockPane extends Pane { private final ControllerMap controllerMap; @@ -121,7 +121,7 @@ public MockPane() { } - private class MockController implements Controller { + private static class MockController implements Controller { private final Pane pane = new Pane(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java b/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java index dd06294f20..5b30a80874 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java @@ -2,6 +2,8 @@ import com.google.common.eventbus.EventBus; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import net.jodah.concurrentunit.Waiter; import org.junit.Before; @@ -20,6 +22,8 @@ public class GripPlatformTest extends ApplicationTest { + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", + justification = "A JUnit rule -- used by JUnit") @Rule public Timeout globalTimeout = Timeout.seconds(10); // 10 seconds max per method tested private GripPlatform platform;