fb-contrib icon indicating copy to clipboard operation
fb-contrib copied to clipboard

Apparent false positive on PCAIL_POSSIBLE_CONSTANT_ALLOCATION_IN_LOOP

Open ThrawnCA opened this issue 7 years ago • 8 comments

We're hitting PCAIL_POSSIBLE_CONSTANT_ALLOCATION_IN_LOOP in code that, as far as I can tell, is not able to allocate the relevant variable outside the loop.

public List<Transaction> getTransactions(TransactionSearchCriteria criteria) throws Exception {
    TransactionSearchCriteria currentCriteria = criteria;
    final List<Transaction> all = new ArrayList<>();
    int lastSize = 0, loopCount = 0;
    do {
        loopCount++;
        List<Transaction> newTxns = transactionSearch.execute(currentCriteria);

        int curSize = newTxns.size();
        LOG.info("Searching for [{}] returned [{}] transactions", currentCriteria, curSize);
        all.addAll(newTxns);

        if (curSize <= 1 || curSize < lastSize) {
            return all;
        }

        lastSize = curSize;
        LocalDateTime latestPaymentTime = newTxns.get(curSize - 1).getPaymentDate();
        currentCriteria = new SearchCriteriaBuilder().withFromDate(latestPaymentTime).withToDate(currentCriteria.getToDate()).build();
    } while (loopCount < queryLoopLimit);

    throw new Exception(String.format("Orphan job query loop limit exceeded. Reached %d transactions. Last size: %d", all.size(), lastSize));
}

The detector complains about the lastSize variable, which is updated on each iteration to a) identify when we get less search results (meaning that we're on the last page of results) and b) report on the number of transactions returned if we crash. I don't see a better time to allocate it.

ThrawnCA avatar Jan 09 '18 04:01 ThrawnCA

something is odd here. it couldn't really be complaining about lastSize.... my guess is it's complaining about new SearchCriteriaBuilder and something confused it.. i'll have to take a look

mebigfatguy avatar Jan 09 '18 05:01 mebigfatguy

javap output:

public class au.gov.qld.ssq.service.bpoint.BPointOrphanTransactionResolver
  SourceFile: "BPointOrphanTransactionResolver.java"
  InnerClasses:
       public static #196= #90 of #237; //Entry=class java/util/Map$Entry of class java/util/Map
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Methodref          #52.#210      //  java/lang/Object."<init>":()V
    #2 = Fieldref           #105.#211     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.transactionSearch:Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;
    #3 = Fieldref           #105.#212     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.repository:Lau/gov/qld/ssq/repository/ReceiptableRepository;
    #4 = Fieldref           #105.#213     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.paymentService:Lau/gov/qld/ssq/service/PaymentService;
    #5 = Fieldref           #105.#214     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.sendToRadsService:Lau/gov/qld/ssq/service/rads/SendToRadsService;
    #6 = Fieldref           #105.#215     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.config:Lau/gov/qld/ssq/config/ConfigurationService;
    #7 = Methodref          #216.#217     //  au/gov/qld/ssq/config/ConfigurationService.getBpointResolveOrphansJobQueryLoopLimit:()I
    #8 = Fieldref           #105.#218     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.queryLoopLimit:I
    #9 = Class              #219          //  org/joda/time/LocalDateTime
   #10 = Methodref          #9.#210       //  org/joda/time/LocalDateTime."<init>":()V
   #11 = Methodref          #9.#220       //  org/joda/time/LocalDateTime.withTime:(IIII)Lorg/joda/time/LocalDateTime;
   #12 = Methodref          #9.#221       //  org/joda/time/LocalDateTime.minusDays:(I)Lorg/joda/time/LocalDateTime;
   #13 = Methodref          #9.#222       //  org/joda/time/LocalDateTime.plusDays:(I)Lorg/joda/time/LocalDateTime;
   #14 = Class              #223          //  au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder
   #15 = Methodref          #14.#210      //  au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder."<init>":()V
   #16 = Methodref          #14.#224      //  au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.withFromDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
   #17 = Methodref          #14.#225      //  au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.withToDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
   #18 = Methodref          #14.#226      //  au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.build:()Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
   #19 = Methodref          #105.#227     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.resolve:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)V
   #20 = Methodref          #105.#228     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.extractPaidCRNs:(Ljava/util/List;)Ljava/util/Set;
   #21 = InterfaceMethodref #229.#230     //  au/gov/qld/ssq/repository/ReceiptableRepository.findUnpaidReceiptablesByReference:(Ljava/util/Set;)Ljava/util/Collection;
   #22 = Methodref          #105.#231     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.combineReceiptablesAndTransactions:(Ljava/util/List;Ljava/util/Collection;)Ljava/util/Map;
   #23 = Methodref          #105.#232     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.getBpointTransactions:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
   #24 = Methodref          #105.#233     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.getOrphans:(Ljava/util/List;)Ljava/util/Map;
   #25 = Methodref          #105.#234     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.markOrphansAsPaid:(Ljava/util/Map;)V
   #26 = Fieldref           #105.#235     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.LOG:Lorg/slf4j/Logger;
   #27 = String             #236          //  Resolved [{}] orphaned transactions
   #28 = InterfaceMethodref #237.#238     //  java/util/Map.size:()I
   #29 = Methodref          #239.#240     //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   #30 = InterfaceMethodref #241.#242     //  org/slf4j/Logger.info:(Ljava/lang/String;Ljava/lang/Object;)V
   #31 = Methodref          #243.#244     //  org/apache/commons/collections4/MapUtils.isNotEmpty:(Ljava/util/Map;)Z
   #32 = String             #245          //  Sending orphan transactions to RADS as at [{}]
   #33 = Methodref          #246.#247     //  au/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria.getToDate:()Lorg/joda/time/LocalDateTime;
   #34 = String             #248          //  dd/yy/yyyy
   #35 = Methodref          #9.#249       //  org/joda/time/LocalDateTime.toString:(Ljava/lang/String;)Ljava/lang/String;
   #36 = Methodref          #105.#250     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.sendOrphanTransactionsToRads:()V
   #37 = Class              #251          //  java/util/ArrayList
   #38 = InterfaceMethodref #237.#252     //  java/util/Map.values:()Ljava/util/Collection;
   #39 = Methodref          #37.#253      //  java/util/ArrayList."<init>":(Ljava/util/Collection;)V
   #40 = Methodref          #254.#255     //  org/apache/commons/lang3/tuple/Pair.of:(Ljava/lang/Object;Ljava/lang/Object;)Lorg/apache/commons/lang3/tuple/Pair;
   #41 = Methodref          #37.#210      //  java/util/ArrayList."<init>":()V
   #42 = Methodref          #256.#257     //  au/gov/qld/ssq/service/bpoint/ws/TransactionSearch.execute:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
   #43 = InterfaceMethodref #258.#238     //  java/util/List.size:()I
   #44 = String             #259          //  Searching BPoint for [{}] returned [{}] transactions
   #45 = InterfaceMethodref #241.#260     //  org/slf4j/Logger.info:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
   #46 = InterfaceMethodref #258.#261     //  java/util/List.addAll:(Ljava/util/Collection;)Z
   #47 = InterfaceMethodref #258.#262     //  java/util/List.get:(I)Ljava/lang/Object;
   #48 = Class              #263          //  au/gov/qld/ssq/service/bpoint/ws/Transaction
   #49 = Methodref          #48.#264      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getPaymentDate:()Lorg/joda/time/LocalDateTime;
   #50 = Class              #265          //  au/gov/qld/ssq/exception/BPointException
   #51 = String             #266          //  BPoint Orphan job query loop limit exceeded. Reached %d transactions. Last size: %d
   #52 = Class              #267          //  java/lang/Object
   #53 = Methodref          #268.#269     //  java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
   #54 = Methodref          #50.#270      //  au/gov/qld/ssq/exception/BPointException."<init>":(Ljava/lang/String;)V
   #55 = Class              #271          //  java/util/HashSet
   #56 = Methodref          #55.#210      //  java/util/HashSet."<init>":()V
   #57 = InterfaceMethodref #258.#272     //  java/util/List.iterator:()Ljava/util/Iterator;
   #58 = InterfaceMethodref #273.#274     //  java/util/Iterator.hasNext:()Z
   #59 = InterfaceMethodref #273.#275     //  java/util/Iterator.next:()Ljava/lang/Object;
   #60 = Methodref          #48.#276      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.isApproved:()Z
   #61 = Methodref          #48.#277      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.isCardTest:()Z
   #62 = Methodref          #105.#278     //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver.shouldRejectMonth99:()Z
   #63 = Methodref          #48.#279      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getCustomerReferenceNumber:()Ljava/lang/String;
   #64 = Methodref          #280.#281     //  java/lang/Long.valueOf:(Ljava/lang/String;)Ljava/lang/Long;
   #65 = InterfaceMethodref #282.#283     //  java/util/Set.add:(Ljava/lang/Object;)Z
   #66 = Class              #284          //  java/lang/NumberFormatException
   #67 = String             #285          //  Transaction {} has non-numeric reference number; skipping
   #68 = InterfaceMethodref #241.#286     //  org/slf4j/Logger.warn:(Ljava/lang/String;Ljava/lang/Object;)V
   #69 = Class              #287          //  java/util/HashMap
   #70 = Methodref          #69.#210      //  java/util/HashMap."<init>":()V
   #71 = InterfaceMethodref #288.#272     //  java/util/Collection.iterator:()Ljava/util/Iterator;
   #72 = Class              #289          //  au/gov/qld/ssq/domain/Receiptable
   #73 = String             #290          //  Seeking transaction for receiptable {}
   #74 = InterfaceMethodref #241.#291     //  org/slf4j/Logger.trace:(Ljava/lang/String;Ljava/lang/Object;)V
   #75 = String             #292          //  Checking transaction {} against receiptable {}
   #76 = InterfaceMethodref #241.#293     //  org/slf4j/Logger.trace:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
   #77 = InterfaceMethodref #72.#294      //  au/gov/qld/ssq/domain/Receiptable.getReference:()Ljava/lang/Long;
   #78 = Methodref          #268.#295     //  java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   #79 = Methodref          #268.#296     //  java/lang/String.equals:(Ljava/lang/Object;)Z
   #80 = Methodref          #48.#297      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getAmount:()Lau/gov/qld/ssq/common/money/Money;
   #81 = InterfaceMethodref #72.#298      //  au/gov/qld/ssq/domain/Receiptable.getTotalAmount:()Lau/gov/qld/ssq/common/money/Money;
   #82 = Methodref          #299.#296     //  au/gov/qld/ssq/common/money/Money.equals:(Ljava/lang/Object;)Z
   #83 = String             #300          //  Transaction {} matches receiptable {}
   #84 = InterfaceMethodref #241.#301     //  org/slf4j/Logger.debug:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
   #85 = InterfaceMethodref #237.#302     //  java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
   #86 = String             #303          //  BPoint reports amount {} for CRN {} but receiptable total is {}
   #87 = InterfaceMethodref #241.#304     //  org/slf4j/Logger.error:(Ljava/lang/String;[Ljava/lang/Object;)V
   #88 = InterfaceMethodref #237.#305     //  java/util/Map.entrySet:()Ljava/util/Set;
   #89 = InterfaceMethodref #282.#272     //  java/util/Set.iterator:()Ljava/util/Iterator;
   #90 = Class              #306          //  java/util/Map$Entry
   #91 = InterfaceMethodref #90.#307      //  java/util/Map$Entry.getKey:()Ljava/lang/Object;
   #92 = InterfaceMethodref #90.#308      //  java/util/Map$Entry.getValue:()Ljava/lang/Object;
   #93 = Methodref          #48.#309      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getReceiptNumber:()Ljava/lang/String;
   #94 = Methodref          #48.#310      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getTransactionNumber:()Ljava/lang/String;
   #95 = Methodref          #48.#311      //  au/gov/qld/ssq/service/bpoint/ws/Transaction.getLocalPaymentDate:()Lorg/joda/time/LocalDateTime;
   #96 = Fieldref           #312.#313     //  au/gov/qld/ssq/domain/PaymentType.CC:Lau/gov/qld/ssq/domain/PaymentType;
   #97 = Methodref          #314.#315     //  au/gov/qld/ssq/service/PaymentService.pay:(Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/common/money/Money;Ljava/lang/String;Ljava/lang/String;Lorg/joda/time/LocalDateTime;Lau/gov/qld/ssq/domain/PaymentType;)Lau/gov/qld/ssq/domain/Payment;
   #98 = Class              #316          //  org/joda/time/LocalDate
   #99 = Methodref          #98.#210      //  org/joda/time/LocalDate."<init>":()V
  #100 = Methodref          #98.#317      //  org/joda/time/LocalDate.minusDays:(I)Lorg/joda/time/LocalDate;
  #101 = Methodref          #216.#318     //  au/gov/qld/ssq/config/ConfigurationService.getRadsCutoffTimeOn:(Lorg/joda/time/LocalDate;)Lorg/joda/time/LocalDateTime;
  #102 = Methodref          #319.#320     //  au/gov/qld/ssq/service/rads/SendToRadsService.sendUnsentTransactionsFrom:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/domain/Batch;
  #103 = Methodref          #216.#321     //  au/gov/qld/ssq/config/ConfigurationService.getEnvironment:()Lau/gov/qld/ssq/common/Environment;
  #104 = Fieldref           #322.#323     //  au/gov/qld/ssq/common/Environment.TRAINING:Lau/gov/qld/ssq/common/Environment;
  #105 = Class              #324          //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver
  #106 = Methodref          #325.#326     //  org/slf4j/LoggerFactory.getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger;
  #107 = Utf8               LOG
  #108 = Utf8               Lorg/slf4j/Logger;
  #109 = Utf8               transactionSearch
  #110 = Utf8               Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;
  #111 = Utf8               repository
  #112 = Utf8               Lau/gov/qld/ssq/repository/ReceiptableRepository;
  #113 = Utf8               paymentService
  #114 = Utf8               Lau/gov/qld/ssq/service/PaymentService;
  #115 = Utf8               sendToRadsService
  #116 = Utf8               Lau/gov/qld/ssq/service/rads/SendToRadsService;
  #117 = Utf8               config
  #118 = Utf8               Lau/gov/qld/ssq/config/ConfigurationService;
  #119 = Utf8               queryLoopLimit
  #120 = Utf8               I
  #121 = Utf8               <init>
  #122 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;Lau/gov/qld/ssq/repository/ReceiptableRepository;Lau/gov/qld/ssq/service/PaymentService;Lau/gov/qld/ssq/service/rads/SendToRadsService;Lau/gov/qld/ssq/config/ConfigurationService;)V
  #123 = Utf8               Code
  #124 = Utf8               LineNumberTable
  #125 = Utf8               LocalVariableTable
  #126 = Utf8               this
  #127 = Utf8               Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
  #128 = Utf8               RuntimeVisibleAnnotations
  #129 = Utf8               Lcom/google/inject/Inject;
  #130 = Utf8               resolve
  #131 = Utf8               ()V
  #132 = Utf8               startOfYesterday
  #133 = Utf8               Lorg/joda/time/LocalDateTime;
  #134 = Utf8               endOfYesterday
  #135 = Utf8               Exceptions
  #136 = Utf8               getOrphans
  #137 = Utf8               (Ljava/util/List;)Ljava/util/Map;
  #138 = Utf8               transactions
  #139 = Utf8               Ljava/util/List;
  #140 = Utf8               references
  #141 = Utf8               Ljava/util/Set;
  #142 = Utf8               receiptables
  #143 = Utf8               Ljava/util/Collection;
  #144 = Utf8               LocalVariableTypeTable
  #145 = Utf8               Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #146 = Utf8               Ljava/util/Set<Ljava/lang/Long;>;
  #147 = Utf8               Ljava/util/Collection<Lau/gov/qld/ssq/domain/Receiptable;>;
  #148 = Utf8               Signature
  #149 = Utf8               (Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;)Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #150 = Utf8               resolveOrphanTransactions
  #151 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Lorg/apache/commons/lang3/tuple/Pair;
  #152 = Utf8               criteria
  #153 = Utf8               Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
  #154 = Utf8               orphans
  #155 = Utf8               Ljava/util/Map;
  #156 = Utf8               Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #157 = Utf8               StackMapTable
  #158 = Class              #327          //  java/util/List
  #159 = Class              #328          //  java/util/Map
  #160 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Lorg/apache/commons/lang3/tuple/Pair<Ljava/util/ArrayList<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;Ljava/lang/Integer;>;
  #161 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)V
  #162 = Utf8               getBpointTransactions
  #163 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
  #164 = Utf8               newTxns
  #165 = Utf8               curSize
  #166 = Utf8               latestPaymentTime
  #167 = Utf8               currentCriteria
  #168 = Utf8               all
  #169 = Utf8               lastSize
  #170 = Utf8               loopCount
  #171 = Class              #324          //  au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver
  #172 = Class              #329          //  au/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria
  #173 = Utf8               (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #174 = Utf8               extractPaidCRNs
  #175 = Utf8               (Ljava/util/List;)Ljava/util/Set;
  #176 = Utf8               e
  #177 = Utf8               Ljava/lang/NumberFormatException;
  #178 = Utf8               transaction
  #179 = Utf8               Lau/gov/qld/ssq/service/bpoint/ws/Transaction;
  #180 = Utf8               i$
  #181 = Utf8               Ljava/util/Iterator;
  #182 = Class              #330          //  java/util/Set
  #183 = Class              #331          //  java/util/Iterator
  #184 = Class              #263          //  au/gov/qld/ssq/service/bpoint/ws/Transaction
  #185 = Class              #284          //  java/lang/NumberFormatException
  #186 = Utf8               (Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;)Ljava/util/Set<Ljava/lang/Long;>;
  #187 = Utf8               combineReceiptablesAndTransactions
  #188 = Utf8               (Ljava/util/List;Ljava/util/Collection;)Ljava/util/Map;
  #189 = Utf8               receiptable
  #190 = Utf8               Lau/gov/qld/ssq/domain/Receiptable;
  #191 = Class              #289          //  au/gov/qld/ssq/domain/Receiptable
  #192 = Utf8               (Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;Ljava/util/Collection<Lau/gov/qld/ssq/domain/Receiptable;>;)Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #193 = Utf8               markOrphansAsPaid
  #194 = Utf8               (Ljava/util/Map;)V
  #195 = Utf8               orphan
  #196 = Utf8               Entry
  #197 = Utf8               InnerClasses
  #198 = Utf8               Ljava/util/Map$Entry;
  #199 = Utf8               Ljava/util/Map$Entry<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
  #200 = Utf8               (Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;)V
  #201 = Utf8               sendOrphanTransactionsToRads
  #202 = Utf8               yesterday
  #203 = Utf8               Lorg/joda/time/LocalDate;
  #204 = Utf8               cutoff
  #205 = Utf8               shouldRejectMonth99
  #206 = Utf8               ()Z
  #207 = Utf8               <clinit>
  #208 = Utf8               SourceFile
  #209 = Utf8               BPointOrphanTransactionResolver.java
  #210 = NameAndType        #121:#131     //  "<init>":()V
  #211 = NameAndType        #109:#110     //  transactionSearch:Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;
  #212 = NameAndType        #111:#112     //  repository:Lau/gov/qld/ssq/repository/ReceiptableRepository;
  #213 = NameAndType        #113:#114     //  paymentService:Lau/gov/qld/ssq/service/PaymentService;
  #214 = NameAndType        #115:#116     //  sendToRadsService:Lau/gov/qld/ssq/service/rads/SendToRadsService;
  #215 = NameAndType        #117:#118     //  config:Lau/gov/qld/ssq/config/ConfigurationService;
  #216 = Class              #332          //  au/gov/qld/ssq/config/ConfigurationService
  #217 = NameAndType        #333:#334     //  getBpointResolveOrphansJobQueryLoopLimit:()I
  #218 = NameAndType        #119:#120     //  queryLoopLimit:I
  #219 = Utf8               org/joda/time/LocalDateTime
  #220 = NameAndType        #335:#336     //  withTime:(IIII)Lorg/joda/time/LocalDateTime;
  #221 = NameAndType        #337:#338     //  minusDays:(I)Lorg/joda/time/LocalDateTime;
  #222 = NameAndType        #339:#338     //  plusDays:(I)Lorg/joda/time/LocalDateTime;
  #223 = Utf8               au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder
  #224 = NameAndType        #340:#341     //  withFromDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
  #225 = NameAndType        #342:#341     //  withToDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
  #226 = NameAndType        #343:#344     //  build:()Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
  #227 = NameAndType        #130:#161     //  resolve:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)V
  #228 = NameAndType        #174:#175     //  extractPaidCRNs:(Ljava/util/List;)Ljava/util/Set;
  #229 = Class              #345          //  au/gov/qld/ssq/repository/ReceiptableRepository
  #230 = NameAndType        #346:#347     //  findUnpaidReceiptablesByReference:(Ljava/util/Set;)Ljava/util/Collection;
  #231 = NameAndType        #187:#188     //  combineReceiptablesAndTransactions:(Ljava/util/List;Ljava/util/Collection;)Ljava/util/Map;
  #232 = NameAndType        #162:#163     //  getBpointTransactions:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
  #233 = NameAndType        #136:#137     //  getOrphans:(Ljava/util/List;)Ljava/util/Map;
  #234 = NameAndType        #193:#194     //  markOrphansAsPaid:(Ljava/util/Map;)V
  #235 = NameAndType        #107:#108     //  LOG:Lorg/slf4j/Logger;
  #236 = Utf8               Resolved [{}] orphaned transactions
  #237 = Class              #328          //  java/util/Map
  #238 = NameAndType        #348:#334     //  size:()I
  #239 = Class              #349          //  java/lang/Integer
  #240 = NameAndType        #350:#351     //  valueOf:(I)Ljava/lang/Integer;
  #241 = Class              #352          //  org/slf4j/Logger
  #242 = NameAndType        #353:#354     //  info:(Ljava/lang/String;Ljava/lang/Object;)V
  #243 = Class              #355          //  org/apache/commons/collections4/MapUtils
  #244 = NameAndType        #356:#357     //  isNotEmpty:(Ljava/util/Map;)Z
  #245 = Utf8               Sending orphan transactions to RADS as at [{}]
  #246 = Class              #329          //  au/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria
  #247 = NameAndType        #358:#359     //  getToDate:()Lorg/joda/time/LocalDateTime;
  #248 = Utf8               dd/yy/yyyy
  #249 = NameAndType        #360:#361     //  toString:(Ljava/lang/String;)Ljava/lang/String;
  #250 = NameAndType        #201:#131     //  sendOrphanTransactionsToRads:()V
  #251 = Utf8               java/util/ArrayList
  #252 = NameAndType        #362:#363     //  values:()Ljava/util/Collection;
  #253 = NameAndType        #121:#364     //  "<init>":(Ljava/util/Collection;)V
  #254 = Class              #365          //  org/apache/commons/lang3/tuple/Pair
  #255 = NameAndType        #366:#367     //  of:(Ljava/lang/Object;Ljava/lang/Object;)Lorg/apache/commons/lang3/tuple/Pair;
  #256 = Class              #368          //  au/gov/qld/ssq/service/bpoint/ws/TransactionSearch
  #257 = NameAndType        #369:#163     //  execute:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
  #258 = Class              #327          //  java/util/List
  #259 = Utf8               Searching BPoint for [{}] returned [{}] transactions
  #260 = NameAndType        #353:#370     //  info:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
  #261 = NameAndType        #371:#372     //  addAll:(Ljava/util/Collection;)Z
  #262 = NameAndType        #373:#374     //  get:(I)Ljava/lang/Object;
  #263 = Utf8               au/gov/qld/ssq/service/bpoint/ws/Transaction
  #264 = NameAndType        #375:#359     //  getPaymentDate:()Lorg/joda/time/LocalDateTime;
  #265 = Utf8               au/gov/qld/ssq/exception/BPointException
  #266 = Utf8               BPoint Orphan job query loop limit exceeded. Reached %d transactions. Last size: %d
  #267 = Utf8               java/lang/Object
  #268 = Class              #376          //  java/lang/String
  #269 = NameAndType        #377:#378     //  format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
  #270 = NameAndType        #121:#379     //  "<init>":(Ljava/lang/String;)V
  #271 = Utf8               java/util/HashSet
  #272 = NameAndType        #380:#381     //  iterator:()Ljava/util/Iterator;
  #273 = Class              #331          //  java/util/Iterator
  #274 = NameAndType        #382:#206     //  hasNext:()Z
  #275 = NameAndType        #383:#384     //  next:()Ljava/lang/Object;
  #276 = NameAndType        #385:#206     //  isApproved:()Z
  #277 = NameAndType        #386:#206     //  isCardTest:()Z
  #278 = NameAndType        #205:#206     //  shouldRejectMonth99:()Z
  #279 = NameAndType        #387:#388     //  getCustomerReferenceNumber:()Ljava/lang/String;
  #280 = Class              #389          //  java/lang/Long
  #281 = NameAndType        #350:#390     //  valueOf:(Ljava/lang/String;)Ljava/lang/Long;
  #282 = Class              #330          //  java/util/Set
  #283 = NameAndType        #391:#392     //  add:(Ljava/lang/Object;)Z
  #284 = Utf8               java/lang/NumberFormatException
  #285 = Utf8               Transaction {} has non-numeric reference number; skipping
  #286 = NameAndType        #393:#354     //  warn:(Ljava/lang/String;Ljava/lang/Object;)V
  #287 = Utf8               java/util/HashMap
  #288 = Class              #394          //  java/util/Collection
  #289 = Utf8               au/gov/qld/ssq/domain/Receiptable
  #290 = Utf8               Seeking transaction for receiptable {}
  #291 = NameAndType        #395:#354     //  trace:(Ljava/lang/String;Ljava/lang/Object;)V
  #292 = Utf8               Checking transaction {} against receiptable {}
  #293 = NameAndType        #395:#370     //  trace:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
  #294 = NameAndType        #396:#397     //  getReference:()Ljava/lang/Long;
  #295 = NameAndType        #350:#398     //  valueOf:(Ljava/lang/Object;)Ljava/lang/String;
  #296 = NameAndType        #399:#392     //  equals:(Ljava/lang/Object;)Z
  #297 = NameAndType        #400:#401     //  getAmount:()Lau/gov/qld/ssq/common/money/Money;
  #298 = NameAndType        #402:#401     //  getTotalAmount:()Lau/gov/qld/ssq/common/money/Money;
  #299 = Class              #403          //  au/gov/qld/ssq/common/money/Money
  #300 = Utf8               Transaction {} matches receiptable {}
  #301 = NameAndType        #404:#370     //  debug:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
  #302 = NameAndType        #405:#406     //  put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
  #303 = Utf8               BPoint reports amount {} for CRN {} but receiptable total is {}
  #304 = NameAndType        #407:#408     //  error:(Ljava/lang/String;[Ljava/lang/Object;)V
  #305 = NameAndType        #409:#410     //  entrySet:()Ljava/util/Set;
  #306 = Utf8               java/util/Map$Entry
  #307 = NameAndType        #411:#384     //  getKey:()Ljava/lang/Object;
  #308 = NameAndType        #412:#384     //  getValue:()Ljava/lang/Object;
  #309 = NameAndType        #413:#388     //  getReceiptNumber:()Ljava/lang/String;
  #310 = NameAndType        #414:#388     //  getTransactionNumber:()Ljava/lang/String;
  #311 = NameAndType        #415:#359     //  getLocalPaymentDate:()Lorg/joda/time/LocalDateTime;
  #312 = Class              #416          //  au/gov/qld/ssq/domain/PaymentType
  #313 = NameAndType        #417:#418     //  CC:Lau/gov/qld/ssq/domain/PaymentType;
  #314 = Class              #419          //  au/gov/qld/ssq/service/PaymentService
  #315 = NameAndType        #420:#421     //  pay:(Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/common/money/Money;Ljava/lang/String;Ljava/lang/String;Lorg/joda/time/LocalDateTime;Lau/gov/qld/ssq/domain/PaymentType;)Lau/gov/qld/ssq/domain/Payment;
  #316 = Utf8               org/joda/time/LocalDate
  #317 = NameAndType        #337:#422     //  minusDays:(I)Lorg/joda/time/LocalDate;
  #318 = NameAndType        #423:#424     //  getRadsCutoffTimeOn:(Lorg/joda/time/LocalDate;)Lorg/joda/time/LocalDateTime;
  #319 = Class              #425          //  au/gov/qld/ssq/service/rads/SendToRadsService
  #320 = NameAndType        #426:#427     //  sendUnsentTransactionsFrom:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/domain/Batch;
  #321 = NameAndType        #428:#429     //  getEnvironment:()Lau/gov/qld/ssq/common/Environment;
  #322 = Class              #430          //  au/gov/qld/ssq/common/Environment
  #323 = NameAndType        #431:#432     //  TRAINING:Lau/gov/qld/ssq/common/Environment;
  #324 = Utf8               au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver
  #325 = Class              #433          //  org/slf4j/LoggerFactory
  #326 = NameAndType        #434:#435     //  getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger;
  #327 = Utf8               java/util/List
  #328 = Utf8               java/util/Map
  #329 = Utf8               au/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria
  #330 = Utf8               java/util/Set
  #331 = Utf8               java/util/Iterator
  #332 = Utf8               au/gov/qld/ssq/config/ConfigurationService
  #333 = Utf8               getBpointResolveOrphansJobQueryLoopLimit
  #334 = Utf8               ()I
  #335 = Utf8               withTime
  #336 = Utf8               (IIII)Lorg/joda/time/LocalDateTime;
  #337 = Utf8               minusDays
  #338 = Utf8               (I)Lorg/joda/time/LocalDateTime;
  #339 = Utf8               plusDays
  #340 = Utf8               withFromDate
  #341 = Utf8               (Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
  #342 = Utf8               withToDate
  #343 = Utf8               build
  #344 = Utf8               ()Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
  #345 = Utf8               au/gov/qld/ssq/repository/ReceiptableRepository
  #346 = Utf8               findUnpaidReceiptablesByReference
  #347 = Utf8               (Ljava/util/Set;)Ljava/util/Collection;
  #348 = Utf8               size
  #349 = Utf8               java/lang/Integer
  #350 = Utf8               valueOf
  #351 = Utf8               (I)Ljava/lang/Integer;
  #352 = Utf8               org/slf4j/Logger
  #353 = Utf8               info
  #354 = Utf8               (Ljava/lang/String;Ljava/lang/Object;)V
  #355 = Utf8               org/apache/commons/collections4/MapUtils
  #356 = Utf8               isNotEmpty
  #357 = Utf8               (Ljava/util/Map;)Z
  #358 = Utf8               getToDate
  #359 = Utf8               ()Lorg/joda/time/LocalDateTime;
  #360 = Utf8               toString
  #361 = Utf8               (Ljava/lang/String;)Ljava/lang/String;
  #362 = Utf8               values
  #363 = Utf8               ()Ljava/util/Collection;
  #364 = Utf8               (Ljava/util/Collection;)V
  #365 = Utf8               org/apache/commons/lang3/tuple/Pair
  #366 = Utf8               of
  #367 = Utf8               (Ljava/lang/Object;Ljava/lang/Object;)Lorg/apache/commons/lang3/tuple/Pair;
  #368 = Utf8               au/gov/qld/ssq/service/bpoint/ws/TransactionSearch
  #369 = Utf8               execute
  #370 = Utf8               (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
  #371 = Utf8               addAll
  #372 = Utf8               (Ljava/util/Collection;)Z
  #373 = Utf8               get
  #374 = Utf8               (I)Ljava/lang/Object;
  #375 = Utf8               getPaymentDate
  #376 = Utf8               java/lang/String
  #377 = Utf8               format
  #378 = Utf8               (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
  #379 = Utf8               (Ljava/lang/String;)V
  #380 = Utf8               iterator
  #381 = Utf8               ()Ljava/util/Iterator;
  #382 = Utf8               hasNext
  #383 = Utf8               next
  #384 = Utf8               ()Ljava/lang/Object;
  #385 = Utf8               isApproved
  #386 = Utf8               isCardTest
  #387 = Utf8               getCustomerReferenceNumber
  #388 = Utf8               ()Ljava/lang/String;
  #389 = Utf8               java/lang/Long
  #390 = Utf8               (Ljava/lang/String;)Ljava/lang/Long;
  #391 = Utf8               add
  #392 = Utf8               (Ljava/lang/Object;)Z
  #393 = Utf8               warn
  #394 = Utf8               java/util/Collection
  #395 = Utf8               trace
  #396 = Utf8               getReference
  #397 = Utf8               ()Ljava/lang/Long;
  #398 = Utf8               (Ljava/lang/Object;)Ljava/lang/String;
  #399 = Utf8               equals
  #400 = Utf8               getAmount
  #401 = Utf8               ()Lau/gov/qld/ssq/common/money/Money;
  #402 = Utf8               getTotalAmount
  #403 = Utf8               au/gov/qld/ssq/common/money/Money
  #404 = Utf8               debug
  #405 = Utf8               put
  #406 = Utf8               (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
  #407 = Utf8               error
  #408 = Utf8               (Ljava/lang/String;[Ljava/lang/Object;)V
  #409 = Utf8               entrySet
  #410 = Utf8               ()Ljava/util/Set;
  #411 = Utf8               getKey
  #412 = Utf8               getValue
  #413 = Utf8               getReceiptNumber
  #414 = Utf8               getTransactionNumber
  #415 = Utf8               getLocalPaymentDate
  #416 = Utf8               au/gov/qld/ssq/domain/PaymentType
  #417 = Utf8               CC
  #418 = Utf8               Lau/gov/qld/ssq/domain/PaymentType;
  #419 = Utf8               au/gov/qld/ssq/service/PaymentService
  #420 = Utf8               pay
  #421 = Utf8               (Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/common/money/Money;Ljava/lang/String;Ljava/lang/String;Lorg/joda/time/LocalDateTime;Lau/gov/qld/ssq/domain/PaymentType;)Lau/gov/qld/ssq/domain/Payment;
  #422 = Utf8               (I)Lorg/joda/time/LocalDate;
  #423 = Utf8               getRadsCutoffTimeOn
  #424 = Utf8               (Lorg/joda/time/LocalDate;)Lorg/joda/time/LocalDateTime;
  #425 = Utf8               au/gov/qld/ssq/service/rads/SendToRadsService
  #426 = Utf8               sendUnsentTransactionsFrom
  #427 = Utf8               (Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/domain/Batch;
  #428 = Utf8               getEnvironment
  #429 = Utf8               ()Lau/gov/qld/ssq/common/Environment;
  #430 = Utf8               au/gov/qld/ssq/common/Environment
  #431 = Utf8               TRAINING
  #432 = Utf8               Lau/gov/qld/ssq/common/Environment;
  #433 = Utf8               org/slf4j/LoggerFactory
  #434 = Utf8               getLogger
  #435 = Utf8               (Ljava/lang/Class;)Lorg/slf4j/Logger;
{
  public au.gov.qld.ssq.service.bpoint.BPointOrphanTransactionResolver(au.gov.qld.ssq.service.bpoint.ws.TransactionSearch, au.gov.qld.ssq.repository.ReceiptableRepository, au.gov.qld.ssq.service.PaymentService, au.gov.qld.ssq.service.rads.SendToRadsService, au.gov.qld.ssq.config.ConfigurationService);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=6, args_size=6
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: aload_1       
         6: putfield      #2                  // Field transactionSearch:Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;
         9: aload_0       
        10: aload_2       
        11: putfield      #3                  // Field repository:Lau/gov/qld/ssq/repository/ReceiptableRepository;
        14: aload_0       
        15: aload_3       
        16: putfield      #4                  // Field paymentService:Lau/gov/qld/ssq/service/PaymentService;
        19: aload_0       
        20: aload         4
        22: putfield      #5                  // Field sendToRadsService:Lau/gov/qld/ssq/service/rads/SendToRadsService;
        25: aload_0       
        26: aload         5
        28: putfield      #6                  // Field config:Lau/gov/qld/ssq/config/ConfigurationService;
        31: aload_0       
        32: aload         5
        34: invokevirtual #7                  // Method au/gov/qld/ssq/config/ConfigurationService.getBpointResolveOrphansJobQueryLoopLimit:()I
        37: putfield      #8                  // Field queryLoopLimit:I
        40: return        
      LineNumberTable:
        line 46: 0
        line 47: 4
        line 48: 9
        line 49: 14
        line 50: 19
        line 51: 25
        line 52: 31
        line 53: 40
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      41     0  this   Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
               0      41     1 transactionSearch   Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearch;
               0      41     2 repository   Lau/gov/qld/ssq/repository/ReceiptableRepository;
               0      41     3 paymentService   Lau/gov/qld/ssq/service/PaymentService;
               0      41     4 sendToRadsService   Lau/gov/qld/ssq/service/rads/SendToRadsService;
               0      41     5 config   Lau/gov/qld/ssq/config/ConfigurationService;
    RuntimeVisibleAnnotations:
      0: #129()

  public void resolve() throws au.gov.qld.ssq.exception.BPointException;
    flags: ACC_PUBLIC
    Code:
      stack=5, locals=3, args_size=1
         0: new           #9                  // class org/joda/time/LocalDateTime
         3: dup           
         4: invokespecial #10                 // Method org/joda/time/LocalDateTime."<init>":()V
         7: iconst_0      
         8: iconst_0      
         9: iconst_0      
        10: iconst_0      
        11: invokevirtual #11                 // Method org/joda/time/LocalDateTime.withTime:(IIII)Lorg/joda/time/LocalDateTime;
        14: iconst_1      
        15: invokevirtual #12                 // Method org/joda/time/LocalDateTime.minusDays:(I)Lorg/joda/time/LocalDateTime;
        18: astore_1      
        19: aload_1       
        20: iconst_1      
        21: invokevirtual #13                 // Method org/joda/time/LocalDateTime.plusDays:(I)Lorg/joda/time/LocalDateTime;
        24: astore_2      
        25: aload_0       
        26: new           #14                 // class au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder
        29: dup           
        30: invokespecial #15                 // Method au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder."<init>":()V
        33: aload_1       
        34: invokevirtual #16                 // Method au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.withFromDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
        37: aload_2       
        38: invokevirtual #17                 // Method au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.withToDate:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder;
        41: invokevirtual #18                 // Method au/gov/qld/ssq/service/bpoint/ws/SearchCriteriaBuilder.build:()Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
        44: invokevirtual #19                 // Method resolve:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)V
        47: return        
      LineNumberTable:
        line 56: 0
        line 57: 19
        line 59: 25
        line 60: 47
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      48     0  this   Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
              19      29     1 startOfYesterday   Lorg/joda/time/LocalDateTime;
              25      23     2 endOfYesterday   Lorg/joda/time/LocalDateTime;
    Exceptions:
      throws au.gov.qld.ssq.exception.BPointException

  public org.apache.commons.lang3.tuple.Pair<java.util.ArrayList<au.gov.qld.ssq.service.bpoint.ws.Transaction>, java.lang.Integer> resolveOrphanTransactions(au.gov.qld.ssq.service.bpoint.ws.TransactionSearchCriteria) throws au.gov.qld.ssq.exception.BPointException;
    flags: ACC_PUBLIC
    Code:
      stack=4, locals=4, args_size=2
         0: aload_0       
         1: aload_1       
         2: invokespecial #23                 // Method getBpointTransactions:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
         5: astore_2      
         6: aload_0       
         7: aload_2       
         8: invokespecial #24                 // Method getOrphans:(Ljava/util/List;)Ljava/util/Map;
        11: astore_3      
        12: aload_0       
        13: aload_3       
        14: invokespecial #25                 // Method markOrphansAsPaid:(Ljava/util/Map;)V
        17: getstatic     #26                 // Field LOG:Lorg/slf4j/Logger;
        20: ldc           #27                 // String Resolved [{}] orphaned transactions
        22: aload_3       
        23: invokeinterface #28,  1           // InterfaceMethod java/util/Map.size:()I
        28: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        31: invokeinterface #30,  3           // InterfaceMethod org/slf4j/Logger.info:(Ljava/lang/String;Ljava/lang/Object;)V
        36: aload_3       
        37: invokestatic  #31                 // Method org/apache/commons/collections4/MapUtils.isNotEmpty:(Ljava/util/Map;)Z
        40: ifeq          66
        43: getstatic     #26                 // Field LOG:Lorg/slf4j/Logger;
        46: ldc           #32                 // String Sending orphan transactions to RADS as at [{}]
        48: aload_1       
        49: invokevirtual #33                 // Method au/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria.getToDate:()Lorg/joda/time/LocalDateTime;
        52: ldc           #34                 // String dd/yy/yyyy
        54: invokevirtual #35                 // Method org/joda/time/LocalDateTime.toString:(Ljava/lang/String;)Ljava/lang/String;
        57: invokeinterface #30,  3           // InterfaceMethod org/slf4j/Logger.info:(Ljava/lang/String;Ljava/lang/Object;)V
        62: aload_0       
        63: invokevirtual #36                 // Method sendOrphanTransactionsToRads:()V
        66: new           #37                 // class java/util/ArrayList
        69: dup           
        70: aload_0       
        71: aload_2       
        72: invokespecial #24                 // Method getOrphans:(Ljava/util/List;)Ljava/util/Map;
        75: invokeinterface #38,  1           // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
        80: invokespecial #39                 // Method java/util/ArrayList."<init>":(Ljava/util/Collection;)V
        83: aload_3       
        84: invokeinterface #28,  1           // InterfaceMethod java/util/Map.size:()I
        89: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        92: invokestatic  #40                 // Method org/apache/commons/lang3/tuple/Pair.of:(Ljava/lang/Object;Ljava/lang/Object;)Lorg/apache/commons/lang3/tuple/Pair;
        95: areturn       
      LineNumberTable:
        line 69: 0
        line 71: 6
        line 72: 12
        line 73: 17
        line 75: 36
        line 76: 43
        line 77: 62
        line 80: 66
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      96     0  this   Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
               0      96     1 criteria   Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
               6      90     2 transactions   Ljava/util/List;
              12      84     3 orphans   Ljava/util/Map;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            6      90     2 transactions   Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
           12      84     3 orphans   Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
      StackMapTable: number_of_entries = 1
           frame_type = 253 /* append */
             offset_delta = 66
        locals = [ class java/util/List, class java/util/Map ]

    Exceptions:
      throws au.gov.qld.ssq.exception.BPointException
    Signature: #160                         // (Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Lorg/apache/commons/lang3/tuple/Pair<Ljava/util/ArrayList<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;Ljava/lang/Integer;>;

  public void resolve(au.gov.qld.ssq.service.bpoint.ws.TransactionSearchCriteria) throws au.gov.qld.ssq.exception.BPointException;
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=4, args_size=2
         0: aload_0       
         1: aload_1       
         2: invokespecial #23                 // Method getBpointTransactions:(Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;)Ljava/util/List;
         5: astore_2      
         6: aload_0       
         7: aload_2       
         8: invokespecial #24                 // Method getOrphans:(Ljava/util/List;)Ljava/util/Map;
        11: astore_3      
        12: aload_0       
        13: aload_3       
        14: invokespecial #25                 // Method markOrphansAsPaid:(Ljava/util/Map;)V
        17: getstatic     #26                 // Field LOG:Lorg/slf4j/Logger;
        20: ldc           #27                 // String Resolved [{}] orphaned transactions
        22: aload_3       
        23: invokeinterface #28,  1           // InterfaceMethod java/util/Map.size:()I
        28: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        31: invokeinterface #30,  3           // InterfaceMethod org/slf4j/Logger.info:(Ljava/lang/String;Ljava/lang/Object;)V
        36: return        
      LineNumberTable:
        line 84: 0
        line 85: 6
        line 86: 12
        line 87: 17
        line 88: 36
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      37     0  this   Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
               0      37     1 criteria   Lau/gov/qld/ssq/service/bpoint/ws/TransactionSearchCriteria;
               6      31     2 transactions   Ljava/util/List;
              12      25     3 orphans   Ljava/util/Map;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            6      31     2 transactions   Ljava/util/List<Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
           12      25     3 orphans   Ljava/util/Map<Lau/gov/qld/ssq/domain/Receiptable;Lau/gov/qld/ssq/service/bpoint/ws/Transaction;>;
    Exceptions:
      throws au.gov.qld.ssq.exception.BPointException

  public void sendOrphanTransactionsToRads();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: new           #98                 // class org/joda/time/LocalDate
         3: dup           
         4: invokespecial #99                 // Method org/joda/time/LocalDate."<init>":()V
         7: iconst_1      
         8: invokevirtual #100                // Method org/joda/time/LocalDate.minusDays:(I)Lorg/joda/time/LocalDate;
        11: astore_1      
        12: aload_0       
        13: getfield      #6                  // Field config:Lau/gov/qld/ssq/config/ConfigurationService;
        16: aload_1       
        17: invokevirtual #101                // Method au/gov/qld/ssq/config/ConfigurationService.getRadsCutoffTimeOn:(Lorg/joda/time/LocalDate;)Lorg/joda/time/LocalDateTime;
        20: astore_2      
        21: aload_0       
        22: getfield      #5                  // Field sendToRadsService:Lau/gov/qld/ssq/service/rads/SendToRadsService;
        25: aload_2       
        26: invokevirtual #102                // Method au/gov/qld/ssq/service/rads/SendToRadsService.sendUnsentTransactionsFrom:(Lorg/joda/time/LocalDateTime;)Lau/gov/qld/ssq/domain/Batch;
        29: pop           
        30: return        
      LineNumberTable:
        line 159: 0
        line 160: 12
        line 161: 21
        line 162: 30
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      31     0  this   Lau/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver;
              12      19     1 yesterday   Lorg/joda/time/LocalDate;
              21      10     2 cutoff   Lorg/joda/time/LocalDateTime;

  static {};
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc_w         #105                // class au/gov/qld/ssq/service/bpoint/BPointOrphanTransactionResolver
         3: invokestatic  #106                // Method org/slf4j/LoggerFactory.getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger;
         6: putstatic     #26                 // Field LOG:Lorg/slf4j/Logger;
         9: return        
      LineNumberTable:
        line 34: 0
}

ThrawnCA avatar Jan 16 '18 01:01 ThrawnCA

When i use the following mock code, it highlights the line

	    currentCriteria = new SearchCriteriaBuilder().withFromDate(latestPaymentTime).withToDate(currentCriteria.getToDate()).build();

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Thrawn {

	private int queryLoopLimit;
	private Transaction transactionSearch;
	private Logger LOG;

	public List<Transaction> getTransactions(TransactionSearchCriteria criteria) throws Exception {
		TransactionSearchCriteria currentCriteria = criteria;
		final List<Transaction> all = new ArrayList<>();
		int lastSize = 0, loopCount = 0;
		do {
			loopCount++;
			List<Transaction> newTxns = transactionSearch.execute(currentCriteria);

			int curSize = newTxns.size();
			LOG.info("Searching for [{}] returned [{}] transactions", currentCriteria, curSize);
			all.addAll(newTxns);

			if (curSize <= 1 || curSize < lastSize) {
			    return all;
			}

			lastSize = curSize;
			LocalDateTime latestPaymentTime = newTxns.get(curSize - 1).getPaymentDate();
			currentCriteria = new SearchCriteriaBuilder().withFromDate(latestPaymentTime).withToDate(currentCriteria.getToDate()).build();
		} while (loopCount < queryLoopLimit);

		throw new Exception(String.format("Orphan job query loop limit exceeded. Reached %d transactions. Last size: %d", all.size(), lastSize));
	}
}

class SearchCriteriaBuilder {
	public SearchCriteriaBuilder withFromDate(LocalDateTime dt) {
		return this;
	}

	public SearchCriteriaBuilder withToDate(LocalDateTime dt) {
		return this;
	}

	public TransactionSearchCriteria build() {
		return null;
	}
}

class Transaction {
	public List<Transaction> execute(TransactionSearchCriteria sc) {
		return new ArrayList<>();
	}

	public LocalDateTime getPaymentDate() {
		return LocalDateTime.now();
	}
}

class TransactionSearchCriteria {
	public LocalDateTime getToDate() {
		return LocalDateTime.now();
	}
}

class Logger {
	public void info(String message, Object... parms) {
	}
}

mebigfatguy avatar Jan 16 '18 03:01 mebigfatguy

Is there any kind of code generation/augmentation that perhaps is not updating the line number table properly?

mebigfatguy avatar Jan 16 '18 03:01 mebigfatguy

OK, either I was reading it wrong before or it's detecting the line numbers better now. Yes, it's reporting on the currentCriteria = new SearchCriteriaBuilder() line.

Still seems like a false positive, though, since the search criteria are derived from the latest payment time, which is obtained from the last transaction returned.

ThrawnCA avatar Apr 03 '18 00:04 ThrawnCA

while this is splitting hairs, you could pull SearchCriteriaBuilder builder = new SearchCriteriaBuilder();

out of the loop, and just do currentCriteria = builder.withFromDate(latestPaymentTime).withToDate(currentCriteria.getToDate()).build();

in the loop

mebigfatguy avatar Apr 09 '18 23:04 mebigfatguy

SearchCriteriaBuilder is stateful. That might be possible, but is too error-prone if we don't override all relevant aspects of its state. Not entirely comfortable doing that.

ThrawnCA avatar Apr 10 '18 01:04 ThrawnCA

yes no doubt it's a FP, and should be fixed. I'm just saying that in this specific example you could just allocate it once.

mebigfatguy avatar Apr 10 '18 03:04 mebigfatguy