SonarQube gradle 插件因 ArrayIndexOutOfBounds 异常而失败

SonarQube gradle plugin failing with ArrayIndexOutOfBounds exception

我正在尝试 运行 声纳 gradle 插件,在 运行 测试后我得到以下信息:

任务“:sonarqube”执行失败。

String index out of range: -1

为了它的价值,我在 OS X 10.10 with sonar qube gradle 插件版本 2.2.1

编辑:这是我在日志中看到的内容:

    :sonarqube
    Class not found: javax.annotation.Nullable
    Class not found: javax.annotation.CheckReturnValue
    Class not found: org.apache.http.annotation.NotThreadSafe
    Class not found: org.apache.http.annotation.Immutable
    Class not found: org.apache.http.annotation.ThreadSafe
    Class not found: org.apache.http.annotation.Immutable
    Class not found: org.apache.http.annotation.NotThreadSafe
    Class not found: org.apache.http.annotation.ThreadSafe
    (list goes on, there are some, but not all of my classes in here as well)
:sonarqube FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':sonarqube'.
> String index out of range: -1

当我 运行 sonarqube 启用堆栈跟踪时,我得到以下堆栈跟踪:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':sonarqube'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:236)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
        at org.gradle.internal.Transformers.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access[=12=]0(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:256)
        at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:253)
        at org.gradle.internal.Transformers.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:175)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
        at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:49)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:31)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator.run(DaemonStateCoordinator.java:297)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.StoppableExecutorImpl.run(StoppableExecutorImpl.java:46)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
        at org.sonar.plugins.surefire.data.SurefireStaxHandler.getClassname(SurefireStaxHandler.java:69)
        at org.sonar.plugins.surefire.data.SurefireStaxHandler.stream(SurefireStaxHandler.java:57)
        at org.sonar.api.utils.StaxParser.parse(StaxParser.java:115)
        at org.sonar.api.utils.StaxParser.parse(StaxParser.java:95)
        at org.sonar.api.utils.StaxParser.parse(StaxParser.java:85)
        at org.sonar.plugins.surefire.SurefireJavaParser.parseFiles(SurefireJavaParser.java:109)
        at org.sonar.plugins.surefire.SurefireJavaParser.parseFiles(SurefireJavaParser.java:99)
        at org.sonar.plugins.surefire.SurefireJavaParser.collect(SurefireJavaParser.java:64)
        at org.sonar.plugins.surefire.SurefireSensor.collect(SurefireSensor.java:65)
        at org.sonar.plugins.surefire.SurefireSensor.analyse(SurefireSensor.java:60)
        at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:58)
        at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:50)
        at org.sonar.batch.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:83)
        at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:192)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
        at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:241)
        at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:236)
        at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:226)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
        at org.sonar.batch.task.ScanTask.execute(ScanTask.java:47)
        at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
        at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:106)
        at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy179.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
        at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
        at org.sonarqube.gradle.SonarQubeTask.run(SonarQubeTask.java:93)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:141)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:123)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:632)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:615)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:95)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:76)
        ... 70 more

编辑:原来原因是 Sonar Surefire 库,更具体地说,它不是为处理测试 class 名称中的不平衡括号而设计的,我不小心在我的黄瓜场景之一中留下了不平衡的括号姓名

根据评论总结解决方法,这个问题是场景名括号不平衡导致的。最好避免在功能和场景名称中使用括号。

在我的具体案例中,我有一个名为 Feedback (bounce and confirmation) 的功能,这导致 Cucumber 生成名称为 ).Email successfully sent( 而不是通常的 Feedback (bounce and confirmation).Email successfully sent 的每个场景报告。显然,sonarqube 插件不喜欢那样。

将功能名称更改为 Bounce and confirmation feedback 解决了问题。