JSR 354, which is also termed as JavaMoney, provides a set of money and currency APIs for Java. These APIs provide support for standard ISO-4217 and custom currencies. They also help to bridge the gap in the representation of a monetary amount. JSR 354 provides an API for representing, transporting and performing comprehensive calculations with money and currency.
Money is a very common concept, used for most application implementations across different domains. But when it comes to Java based development, there is no dedicated support for currencies or monetary arithmetic libraries and APIs. The existing java.util.Currency class is strictly a structure used for representing ISO-4217 standard currencies, and doesn’t provide flexible or standardised calculation and conversion facilities.
It was in Java 1.4 that java.util.Currency got introduced with a standard three-letter currency notation like USD or INR. Later, in the Java 7 upgrade, a support for three-letter numeric code representation like USD=840 was introduced. Also, there is no standard value type to represent a monetary amount or currency arithmetic functions in the current version of Java. Either the user has to rely on some popular third party library (like Joda) or write customised code that may not be generic to global conventions.
JavaMoney supports currency arithmetic across different currencies, as well as foreign currency exchange. Monetary values are a key feature of many applications, mainly in banking, financial services, insurance and other such similar domains.
What is money?
Money is a simple representation of an amount (value) and the currency (unit). For example, with US$ 100, ‘100’ is the amount and US$ is the unit/currency representing this amount.
How do we represent money so far
Till now, application development in Java either used a currency interface, or used ‘double’ or ‘BigDecimal’ for money representation. But this has a side effect when the floating point is a binary approximation of a decimal. Though the approximation is small decimal, this has its own meaning when it comes to the calculation for money. This kind of convention is good when the logic handles the value by rounding the floating point and doesn’t consider the smallest fractional values.
Though BigDecimal doesn’t cause such a floating point approximation, it is slow in calculation due to internal conversion and often requires rounding mode to handle the values represented.
Sometimes, we also use ‘long’ to represent money, which is a much better choice than the above two representations, but since these representations don’t associate a unit (currency) with them, they can easily confuse unit values— for example, dollars or euros with cent values.
Using third party libraries
We now have many sophisticated libraries from third parties that can help in bridging the gap left by money representation in our application programs. These also help in extending the features to enable custom development.
One of the popular representations is JodaMoney, which is a simple wrapper on BigDecimal and provides conventional features for money related arithmetic functions.
Another representation includes JScience, which focuses more on units, and Eclipse UoMo, a proposed open source initiative under the Eclipse Technology Project. It is intended to support unit and measurement APIs (by implementing APIs with strong unit typing), and financial APIs based on general unit and measurement implementation.
Components of the JavaMoney project
This JSR focuses on defining the interfaces and classes to be used for currencies and monetary amounts. Generally, the following areas are focused upon.
- Core: This has the data classes and interface representing currencies and monetary amounts.
- Conversion: This deals with exchange rates between currencies, and provides the API/SPI to perform the conversion of monetary amounts from one currency to another.
- Format: This defines APIs/SPIs for print formatting, and the parsing of currencies and monetary amounts, providing support for complex usage scenarios.
- Extensions: These add extended functionality like currency services, currency mapping, regions and validity services (historic data API).
Some of the key facilities of monetary functions are explained below.
This is an immutable money class and represents currency and BigDecimal amounts with any number of decimal places. An example is shown below:
BigMoney amount = BigMoney.parse(“EUR 1.20567”); amount = amount.multipliedBy(2); // EUR 2.41134 amount = amount.plusMajor(3); // EUR 5.41134 amount = amount.plusMinor(5); // EUR 5.46134 boolean negative = amount.isNegative(); // false amount = amount.rounded(4, RoundingMode.UP); String str = amount.toString(); // “EUR 5.4614”
This is a replacement of the existing currency class and allows applications to control currency data. It also includes three-digit numeric ISO code as shown below:
CurrencyUnit cur = CurrencyUnit.of(“GBP”); int dp = cur.getDecimalPlaces(); // 2 String code = cur.getCurrencyCode(); // “GBP” int ncode = cur.getNumericCode(); // String str = cur.toString(); // “GBP”
Printing currency values and units along with parsed data is also provided with a flexible builder, like Joda-Time and JSR 310. For example:
MoneyFormatterBuilder b = new MoneyFormatterBuilder(); b.appendCurrencyCode().appendLiteral(“: “).appendAmount( MoneyAmountStyle.ASCII_DECIMAL_POINT_GROUP3_COMMA); MoneyFormatter f = b.toFormatter(); String str = f.print(money); // eg “GBP: 1,234.56”
Generally, the scope of the JSR is to target all general application types, such as:
- Banking and finance
- Insurance and pension
- Mobile and embedded payment
To summarise, the scope of JavaMoney can be defined as follows:
- Provides abstractions for currency and money suitable for all target applications.
- Enhances available currencies and adds support for non-ISO currencies as well.
- Supports complex calculation rules, including calculation precision and display precision.
- Supports regional rounding rules.
- Offers basic support for foreign exchange, extendable for more complex usage scenarios.
- A plain text representation of money.
- Printing/parsing to the string.
- Support for pluralisation.
- Provides APIs for historic access of currencies and exchange rates.
- Defines a flexible query API to support complex usage scenarios for exchange rates and currencies.
- Stores a value in multiple currencies (a single value type that effectively maps the currency to the amount, where the amounts are all notionally the same by some form of currency conversion).
- Large exchange rate system (as in a system suitable for trading, such as bid/ask).
Nevertheless, there are some limitations on this front:
- It is not planned to target low latency such as algorithmic trading applications, though we should try to keep performance in mind to accommodate such applications.
- Non-decimal currencies.
JavaMoney is included with Java 9, with backward compatibility as well as a pluggable library. It is being developed under the standard JSR Spec License and Apache 2.0 License for RI (Reference Implementation) and TCK (Technology Compatibility Kit). These two modules will be developed and distributed as standalone modules and RI, and bundled with the Java 8 SE distribution.