Uploaded image for project: 'Jira Data Center'
  1. Jira Data Center
  2. JRASERVER-72139

Reindexing process breaks with IllegalStateException due to multiple NonNullCustomFieldProvider

XMLWordPrintable

      Issue Summary

      Reindexing process breaks with IllegalStateException due to registered multiple NonNullCustomFieldProvider for the same CustomField (this is a separate problem). This breaks the logic in the
      DefaultIssueDocumentFactory which expects only a single result, which causes the mentioned Exception.
      From the high level, the problem area looks like this:

      • Multiple providers got created during plugin restart due to a problem with deregistering logic (removeUnavailableProviders has a mechanism for removing stale providers.)
      • New CustomFieldProvider code doesn't handle duplicates (current bug)

      For example, reindex will fail after disabling and enabling of the Jira Agile Plugin. The same behaviour also reported after the upgrade of the UPM, since it will restart all dependant plugins (see JRASERVER-69963)

      Steps to Reproduce

      One of the ways to trigger the problem:

      1. Disable Jira Agile plugin.
      2. Enable Jira Agile plugin.
      3. Reindex a single issue.

      Expected Results

      Reindex should finish without any errors

      Actual Results

      The below exception is thrown in the atlassian-jira.log file:

      /secure/admin/IndexReIndex!reindex.jspa [c.a.jira.index.AccumulatingResultBuilder] java.lang.IllegalStateException: Duplicate keys mapped to com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@22069d65 / com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@6a887793 for custom field id customfield_10001
       java.lang.RuntimeException: java.lang.IllegalStateException: Duplicate keys mapped to com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@22069d65 / com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@6a887793 for custom field id customfield_10001
           at com.atlassian.jira.index.DefaultIndex$Failure.<init>(DefaultIndex.java:100)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer$EntityOperation.lambda$perform$6(DefaultIssueIndexer.java:858)
           at java.util.HashMap.forEach(HashMap.java:1289)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer$EntityOperation.perform(DefaultIssueIndexer.java:858)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer.lambda$processBatch$2(DefaultIssueIndexer.java:334)
           at com.atlassian.jira.index.SimpleIndexingStrategy.apply(SimpleIndexingStrategy.java:7)
           at com.atlassian.jira.index.SimpleIndexingStrategy.apply(SimpleIndexingStrategy.java:5)
           at com.atlassian.jira.index.MultiThreadedIndexingStrategy$1.call(MultiThreadedIndexingStrategy.java:47)
           at com.atlassian.jira.index.MultiThreadedIndexingStrategy$1.call(MultiThreadedIndexingStrategy.java:43)
           at com.atlassian.jira.util.concurrent.BoundedExecutor$2.call(BoundedExecutor.java:68)
           at java.util.concurrent.FutureTask.run(FutureTask.java:266)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
           at java.lang.Thread.run(Thread.java:748)
      
       Caused by: java.lang.IllegalStateException: Duplicate keys mapped to com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@22069d65 / com.atlassian.jira.issue.customfields.vdi.CustomFieldPrefetchedData@6a887793 for custom field id customfield_10001
           at com.atlassian.jira.issue.index.DefaultIssueDocumentFactory.lambda$processIssueEntry$9(DefaultIssueDocumentFactory.java:186)
           at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
           at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
           at java.util.Collections$2.tryAdvance(Collections.java:4717)
           at java.util.Collections$2.forEachRemaining(Collections.java:4725)
           at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
           at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
           at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
           at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
           at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
           at com.atlassian.jira.issue.index.DefaultIssueDocumentFactory.processIssueEntry(DefaultIssueDocumentFactory.java:177)
           at com.atlassian.jira.issue.index.DefaultIssueDocumentFactory.lambda$getPersistedFieldsWithData$7(DefaultIssueDocumentFactory.java:166)
           at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
           at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
           at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1699)
           at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
           at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
           at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
           at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
           at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1556)
           at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
           at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
           at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
           at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
           at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
           at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
           at com.atlassian.jira.issue.index.DefaultIssueDocumentFactory.getPersistedFieldsWithData(DefaultIssueDocumentFactory.java:166)
           at com.atlassian.jira.issue.index.DefaultIssueDocumentFactory.createDocuments(DefaultIssueDocumentFactory.java:97)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer$DefaultDocumentCreationStrategy.get(DefaultIssueIndexer.java:1332)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer$IssuesOperation.createDocuments(DefaultIssueIndexer.java:982)
           at com.atlassian.jira.issue.index.DefaultIssueIndexer$EntityOperation.perform(DefaultIssueIndexer.java:847)
           ... 10 more
      
      • Note: custom field id customfield_10001, in this case Epic CF (com.atlassian.greenhopper.customfield.epiclink.EpicLinkCFType.EpicLinkCustomFieldProvider) got duplicated.

      Note on fix

      The issue has been largely mitigated since the most common scenario was fixed (#1).
      The list of all possible scenario for future reference:

      1. When two instances of the same provider return the same data and this data can be compared correctly (e.g. Epic Link's type of data is IssueImpl and for this type we can determine if two ones are equal), we can make sure that both providers returned the same thing and we can turn a blind eye to having two providers.
      2. When two instances of the same provider return the same data, but it's not comparable (type coming from some other plugin with no equals implementation), we'll consider this data different.
      3. When two instances of the same provider return genuinely different data, e.g. the data has changed while indexing (a very unlikely concurrency bug), we'll fail indexing.

      Workaround

      A restart of the node having this problem

              kcichy Kamil Cichy (Inactive)
              ce77d5847fbf Deniz Secilir
              Votes:
              4 Vote for this issue
              Watchers:
              18 Start watching this issue

                Created:
                Updated:
                Resolved: