SonarQube 后台任务因 Java 的 IllegalArgumentException 而失败

SonarQube background tasks failing with IllegalArgumentException for Java

我们将 Sonarqube 更新到 5.2 版。之后,一些 Java 项目开始失败并出现以下异常:

    2015.12.22 02:42:13 INFO  [o.s.s.c.s.ComputationStepExecutor] Execute component visitors | time=9942ms        
    2015.12.21 13:01:45 ERROR [o.s.s.c.t.CeWorkerRunnableImpl] Failed to execute task AVHFtA0KaMG72s7lWjEx
            java.lang.IllegalArgumentException: Multiple entries with same key: MeasureKey{metricKey='lines', ruleId=-6253, characteristicId=-6253}=org.sonar.db.measure.PastMeasureDto@7493f7f3 and MeasureKey{metricKey='lines', ruleId=-6253, characteristicId=-6253}=org.sonar.db.measure.PastMeasureDto@1e7bae50
                at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:150) ~[guava-17.0.jar:na]
                at com.google.common.collect.RegularImmutableMap.checkNoConflictInBucket(RegularImmutableMap.java:104) ~[guava-17.0.jar:na]
                at com.google.common.collect.RegularImmutableMap.<init>(RegularImmutableMap.java:70) ~[guava-17.0.jar:na]
                at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:254) ~[guava-17.0.jar:na]
                at com.google.common.collect.Maps.uniqueIndex(Maps.java:1166) ~[guava-17.0.jar:na]
                at com.google.common.collect.Maps.uniqueIndex(Maps.java:1140) ~[guava-17.0.jar:na]
                at com.google.common.collect.FluentIterable.uniqueIndex(FluentIterable.java:424) ~[guava-17.0.jar:na]
                at org.sonar.server.computation.step.ComputeMeasureVariationsStep$VariationMeasuresVisitor.setVariationMeasures(ComputeMeasureVariationsStep.java:145) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.step.ComputeMeasureVariationsStep$VariationMeasuresVisitor.computeMeasuresWithVariations(ComputeMeasureVariationsStep.java:124) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.step.ComputeMeasureVariationsStep$VariationMeasuresVisitor.visitAny(ComputeMeasureVariationsStep.java:115) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visitNode(DepthTraversalTypeAwareCrawler.java:60) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visit(DepthTraversalTypeAwareCrawler.java:44) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visitChildren(DepthTraversalTypeAwareCrawler.java:91) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visit(DepthTraversalTypeAwareCrawler.java:47) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.step.ComputeMeasureVariationsStep.execute(ComputeMeasureVariationsStep.java:92) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:39) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.taskprocessor.report.ReportTaskProcessor.process(ReportTaskProcessor.java:53) ~[sonar-server-5.2.jar:na]
                at org.sonar.server.computation.taskprocessor.CeWorkerRunnableImpl.executeTask(CeWorkerRunnableImpl.java:78) [sonar-server-5.2.jar:na]
                at org.sonar.server.computation.taskprocessor.CeWorkerRunnableImpl.run(CeWorkerRunnableImpl.java:55) [sonar-server-5.2.jar:na]
                at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [na:1.7.0_45]
                at java.util.concurrent.FutureTask.runAndReset(Unknown Source) [na:1.7.0_45]
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(Unknown Source) [na:1.7.0_45]
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) [na:1.7.0_45]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.7.0_45]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.7.0_45]
                at java.lang.Thread.run(Unknown Source) [na:1.7.0_45]

我在 Sonar 中安装了以下插件

您似乎有一些损坏的过去的措施,可能是由于迁移过程中缺少分析或其他意外问题。

您必须清理数据库才能继续分析。 使用 SonarQube 5.3,您将能够知道哪个组件损坏了过去的测量值。

要为给定组件查找要删除的重复度量,您必须执行以下 SQL 查询(替换为组件的键):

SELECT s.id, pm.metric_id, pm.rule_id, pm.characteristic_id FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id
INNER JOIN projects p ON p.id=s.project_id AND p.kee='<COMPONENT_KEY>'
INNER JOIN metrics m ON m.id=pm.metric_id
WHERE m.name='lines' 
AND pm.person_id IS NULL
GROUP BY s.id, pm.metric_id, pm.rule_id, pm.characteristic_id
HAVING count(*) > 1

然后,对于返回的每一行,执行以下查询(替换为 s.id 列的值等):

SELECT pm.* FROM project_measures pm 
INNER JOIN snapshots s ON s.id=pm.snapshot_id
WHERE s.id=<S_ID> AND pm.metric_id=<PM_METRIC_ID> AND pm.rule_id=<PM_RULE_ID> AND pm.characteristic_id=<PM_CHARCTERISTIC_ID>

此查询至少应返回 2 行:重复数据导致项目计算失败。您只需要通过删除其他行来保留一行:

DELETE FROM project_measures WHERE id=<PM_ID>

请注意在删除某些数据之前备份您的数据库!

我们也遇到了 type=DIRECTORY 的这个问题,但是使用 Julien 的 SQL 查询没有发现重复的度量。解决方案是排除抛出的异常中指示的每个目录。这是通过将如下模式添加到排除列表中来完成的。

**/Implementations/Sales/**

一旦分析成功完成(可能需要多次 运行),您就可以从列表中删除排除项并再次 运行。分析将成功完成,导致问题的任何内容都将被清除。