JavaMoney / jsr354-ri

JSR 354 - Moneta: Reference Implementation
Other
333 stars 100 forks source link

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

Closed ncwoehler closed 1 year ago

ncwoehler commented 4 years ago

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.

keilw commented 4 years ago

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.

ncwoehler commented 4 years ago

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)
keilw commented 4 years ago

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.

ncwoehler commented 4 years ago

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

utkanozyurek commented 4 years ago

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

keilw commented 4 years ago

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

fatroom commented 3 years ago

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

keilw commented 3 years ago

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 commented 1 year ago

Could be a classloading issue similar to #369

keilw commented 1 year ago

@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

ncwoehler commented 1 year ago

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.

keilw commented 1 year ago

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.

valtechtmn commented 7 months ago

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 ??

keilw commented 7 months ago

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

valtechtmn commented 7 months ago

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 !