jsr354-ri icon indicating copy to clipboard operation
jsr354-ri copied to clipboard

UnknownCurrencyException [currencyCode=EUR] with v1.3 and Java 11

Open ncwoehler opened this issue 5 years ago • 8 comments

After upgrading our application to Java 11 we are observing a UnknownCurrencyException exception similar to #158.

We are already using version 1.3 of moneta together with jackson-datatype-money.

implementation('org.javamoney:moneta:1.3')
implementation('org.zalando:jackson-datatype-money:1.1.1')

The stacktrace looks like this:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: 
Unknown currency code: EUR; nested exception is 
com.fasterxml.jackson.databind.JsonMappingException: Unknown currency code: EUR

I was able to reproduce the issue in this repository It appears when calling Monetary.getCurrency() in a parallel stream.

I verified that the issue does not appear with Java 8. Just switch to the jdk-8 branch and run the test again.

A static init block in the entry class of the application like this

    static {
        Monetary.getCurrency("EUR");
    }

fixes the issue. Tested within the static-init branch.

ncwoehler avatar May 06 '20 11:05 ncwoehler

Hi, thanks for mentioning that. It sounds a little strange but at least #158 was closed quite some time ago after @atsticks addressed it. He is currently a little busy because he's changing to another company right now, but we already published Moneta 1.4 based on Money-API 1.1 (MR1) so would it be possible that you fork https://github.com/zalando/jackson-datatype-money and try it with the new versions, or if you can test this independently from the Zalando lib, do that with the MR1? Please take the libraries only from Bintray/JCenter, because we still wait for @atsticks' help to syncronize MavenCentral, he has done that so far and the other Maintenance Leads (me, @otaviojava) currently don't have the necessary crypto keys to do that.

keilw avatar May 06 '20 11:05 keilw

The issue seems to be more related to the Spring Boot jar launcher than to the Jackson mapper library.

I've created a very minimal test with Java 11 but without Spring Boot that only depends on org.javamoney:moneta:1.4 and runs as a shadow jar. Here I cannot reproduce the problem. Neither with version 1.3 nor with version 1.4.

But after adding Spring Boot again and running the Jar that is created via ./gradlew bootJar the problem occurs again with all tested moneta versions, including version 1.4.

Stacktrace looks like this:

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: UnknownCurrencyException [currencyCode=EUR]
        at javax.money.spi.MonetaryCurrenciesSingletonSpi.getCurrency(MonetaryCurrenciesSingletonSpi.java:74)
        at javax.money.Monetary.getCurrency(Monetary.java:384)
        at de.nwoehler.unknown.currency.Main.lambda$main$0(Main.java:14)
        at java.base/java.util.stream.IntPipeline$1$1.accept(Unknown Source)
        at java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.Spliterator$OfInt.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(Unknown Source)
        at java.base/java.util.stream.AbstractTask.compute(Unknown Source)
        at java.base/java.util.concurrent.CountedCompleter.exec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)

ncwoehler avatar May 06 '20 13:05 ncwoehler

Would you be able to create an issue at Spring Boot instead? Pointing to this one, but based on your findings, I am inclined to close this one as "invalid" or not directly caused by JavaMoney.

keilw avatar May 06 '20 13:05 keilw

I investigated a bit more and it seems to be an issue with the call to ServiceLoader.load() in javax.money.spi.Bootstrap. When called in a parallel stream within a Spring Boot jar and OpenJDK 11 it does not return the correct results. Not sure whether this is a JDK or Spring Boot bug but I thing this cannot be addressed in the scope of this library. So please go ahead and close it

ncwoehler avatar May 08 '20 07:05 ncwoehler

https://github.com/JavaMoney/jsr354-ri/pull/333

utkanozyurek avatar Jun 04 '20 09:06 utkanozyurek

Looks like #333 fixed this, please reopen or create another one if you still face this or another problem in the MR1 (1.4)

keilw avatar Jul 18 '20 23:07 keilw

Just received the same problem with org.javamoney:moneta:1.4.2

fatroom avatar Oct 09 '20 05:10 fatroom

Not sure, if it's really fixed by #333 but there were changes between 1.4 and 1.4.2 that replaced this, I am putting the PR back into the current snapshot (1.4.3) so once that's released, please retest. If that doesn't solve it, we might have to investigate further, also with Spring Boot where necessary.

keilw avatar Oct 09 '20 11:10 keilw

Could be a classloading issue similar to #369

keilw avatar Nov 08 '22 20:11 keilw

@ncwoehler did you try this with more recent versions of the JDK? As it sounds like a variety of issues with reflection and Java 11, see e.g.: https://stackoverflow.com/questions/69135120/java-11-reflection

keilw avatar Jan 28 '23 18:01 keilw

I'm afraid not working in the payment industry anymore and cannot answer this. But if I remember correctly we did upgrade to a more recent version and were using java11 without problems before I left. Let me reach out to my former colleagues.

ncwoehler avatar Feb 12 '23 10:02 ncwoehler

Thanks, if you hear from them, feel free to close the ticket, if they're using a newer version with Java 11 or above without problems.

keilw avatar Feb 12 '23 14:02 keilw

Hey, I'm using java 17 and moneta 1.4 and I'm still seeing this issue. The static block in the entry point of my code (like mentioned in the OP) does fix the issue. Anyone else still seeing this ??

valtechtmn avatar Jan 18 '24 10:01 valtechtmn

Did you try the 1.4.3 Snapshot where especially #333 was merged?

keilw avatar Jan 18 '24 10:01 keilw

Ah nope, I'm using 1.4.2, in fact I'm not using moneta directly but through commercetools java sdk so I'll keep an eye on when 1.4.3 is released and they update the dependency on their side. Thanks for the quick reply though !

valtechtmn avatar Jan 18 '24 10:01 valtechtmn