1

I currently got the following piece of code:

captureFile = theCaptureFile;
    // If there is only 1 currency it gets the total right away
    if (captureFile.getTotalMoney().size() == 1) {
        Money totalMoney = captureFile.getTotalMoney().values().iterator().next();
        totalAmount  = totalMoney.getAmount();
        currencyCode = totalMoney.getCurrencyCode();
    }
    // If there is more than one currency, goes through every one, converts it to GBP and adds it to the total amount
    else if (captureFile.getTotalMoney().size() > 1) {
        Map<String, Money> totals = captureFile.getTotalMoney();

        for (Entry<String, Money> money : totals.entrySet()) {
            try {
                totalAmount = totalAmount + money.getValue().getEquivalent(BASE_CURRENCY).getAmount();
            } 
            catch (CurrencyNotFoundException e) {
                LOG.error("Getting ExchangeRate:", e);
                totalAmount = null;
                break;
            } 
            catch (ExchangeRateNotFoundException e) {
                LOG.error("Getting ExchangeRate:", e);
                totalAmount = null;
                break;
            }
        }
    }

When the code gets called, the first IF works just fine but, in case there are more than 2 currencies, I get a NullPointerException on the TRY bit. None of those methods have a return null so I'm guessing it is something wrong that I am doing on the mapping part to pull the values out.

Here are the other 2 methods that are pulled off:

public Money getEquivalent(String targetCurrencyCode) throws CurrencyNotFoundException,ExchangeRateNotFoundException {
    if (this.currencyCode.equals(targetCurrencyCode))   {
        return this;
    }
    return getEquivalent(CurrencyCache.get().getCurrency(targetCurrencyCode));
}

and:

public long getAmount() {
    return amount;
}

Any help would be greatly appreciated, any more info you might need just let me know.

Many thanks in advance.

eSp
  • 45
  • 5
  • 2
    Can you post the stack trace you get? – Andreas Fester Mar 04 '15 at 10:13
  • You can change totalAmount = null; to totalAmount = "" in the catch blocks and give a try.why you want to make totalAmount to be null if for a particular iteration of loop is throwing the exception – Kalaiarasan Manimaran Mar 04 '15 at 10:14
  • You never check for nullability your variable. Something like `money.getValue().getEquivalent(BASE_CURRENCY).getAmount()` could generate a NPE very easily. – riccardo.cardin Mar 04 '15 at 10:21
  • @Andreas: java.lang.NullPointerException at CaptureFileInsertOracle.init(CaptureFileInsertOracle.java:46) – eSp Mar 04 '15 at 10:49
  • @KalaiarasanManimaran: Because I will later pass those to the DB and if it can't calculate I want it to be passed as null. – eSp Mar 04 '15 at 10:50
  • @eSP - that isn't a stacktrace. That is just the first line of a stacktrace ... and it doesn't offer any real clues. – Stephen C Mar 05 '15 at 05:41

2 Answers2

2

Since totalAmount is nullable, and because it is used in the very first iteration, you need to set it to a non-null value before the loop:

totalAmount = 0L;
Map<String, Money> totals = captureFile.getTotalMoney();
for (Entry<String, Money> money : totals.entrySet()) {
    try {
        totalAmount = totalAmount + money.getValue().getEquivalent(BASE_CURRENCY).getAmount();
    }
    ... 
}

If totalAmount is not set to null before entering the loop, the first += call would result in an NPE.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • that assumes that totalAmount is a Long or an Integer (we would need to see its declaration to know for sure) - an alternative explanation would be money.getValue() returning null – tucuxi Mar 04 '15 at 10:20
  • @tucuxi There is no assumption here: `totalAmount` is assigned `getAmount()` in the first branch, and OP shows `getAmount()`'s signature, which returns `long`. In the exception handler OP assigns `null` to `totalAmount`, its type must be `Long`. – Sergey Kalinichenko Mar 04 '15 at 10:22
  • please correct me if I am wrong, but why would ```long totalAmount``` (note lowercase L) fail to compile? And why would money.getValue() returning null fail to account for the symptoms? – tucuxi Mar 04 '15 at 10:32
  • @tucuxi if `totalAmount` were `long`, not `Long`, this assignment from the exception handler would not compile: `totalAmount = null;` Returning `null` from `money.getValue()` would definitely account for the symptoms, but I think that it is a lot less likely, because OP uses exceptions rather than returning `null`s in situations where results are unknown (say, because the currency conversion fails). – Sergey Kalinichenko Mar 04 '15 at 10:34
  • ouch - should have seen it. I was looking for my clues further up. – tucuxi Mar 04 '15 at 10:36
  • Will try this approach first as I was under this same impression but disregarded it for some reason. Thanks, will come back with some feedback – eSp Mar 04 '15 at 11:38
  • @dasblinkenlight Many thanks, it worked like a charm. A lesson I won't forget (hopefully) =) – eSp Mar 05 '15 at 11:48
0

You seem to be saying that this line throws an NPE.

totalAmount = totalAmount +
         money.getValue().getEquivalent(BASE_CURRENCY).getAmount();

There are 4 ways that that can happen:

  • if totalAmount is declared as Integer (or another primitive wrapper type) and it is null,

  • if money is null,

  • if money.getValue() returns null,

  • if money.getValue().getEquivalent(BASE_CURRENCY) returns null.

Unfortunately your code is too fragmentary to tell which of these is possible.

It is also possible that the getEquivalent is throwing the NPE ... though that would be clear from the stacktrace.

The fact that this line:

totalAmount = totalMoney.getAmount();

is NOT throwing an NPE doesn't allow us to eliminate any of the possibilities listed above.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216