Using MF2 with Java
A Technical Preview implementation of MF2 is available in ICU, the International Components for Unicode library. Beginning with version 75.0, ICU includes MF2 implementations in Java and C++.
For documentation on the Java implementation, see the ICU API guide. For more introductory content, see the ICU User Guide page on using MF2 with ICU in Java. This page may not be as up-to-date as this documentation and some examples may use an older version of the MF2 syntax.
Quick start Jump to heading
The following instructions use command-line tools and presume a Linux system.
The Tech Preview implementation of MF2 in ICU4J continues to evolve, so to ensure consistency with this documentation, it's best to build ICU from source. Building ICU takes some time, but only needs to be done once (unless further changes occur to the API).
git clone https://github.com/unicode-org/icu.git
cd icu/icu4j
mvn package -DskipTests
The last command builds the .jar
files for ICU4J in a subdirectory
of the icu
directory that the git checkout uses.
It's best to avoid installing globally, since it may override the version
of ICU that comes with your distribution, and break things that depend on ICU.
If you don't want to build ICU from source, ICU 76 should be fairly close to the version of the MessageFormat syntax and APIs described on this site, but some differences may exist, such as the syntax of
.match
(whether it selects on expressions or variables). As of this writing, ICU 76 is a release candidate that can be downloaded from github. In the future, it might be sufficient to upgrade ICU using your system package manager.
A simple client program Jump to heading
Now, let's write a simple program that uses the MF2 API
import com.ibm.icu.message2.MessageFormatter;
import java.util.HashMap;
import java.util.Map;
public final class TestMessageFormat {
private static final boolean testMessageFormat() {
MessageFormatter mf = MessageFormatter.builder()
.setPattern("Hello, {$userName}!").build();
Map<String, Object> arguments = new HashMap<>();
arguments.put("userName", "John");
String result = mf.formatToString(arguments);
return result.equals("Hello, John!");
}
public static void main(String[] argv) {
System.exit(testMessageFormat() ? 0 : 1);
}
}
Before we look at how to compile and run this program, let's go through what it does.
MessageFormatter.builder()
Jump to heading
The call to MessageFormatter.builder()
creates a mutable builder
object. MessageFormatter
is immutable, so like other immutable
classes in ICU, it's constructed using the builder pattern.
The code immediately calls setPattern()
on the builder to set
the message for this formatter, and then calls build()
,
giving an immutable MessageFormatter
object.
Message arguments Jump to heading
In ICU4J, message arguments are simply a Java Map
with string
keys and Object
values. The code creates an argument map called
arguments
, then adds an argument to it with the name "userName"
and value "John"
.
Formatting to string Jump to heading
Finally, we call the MessageFormatter
's formatToString()
method
on the arguments. Note that the message (pattern) is fixed for each
MessageFormatter
objects, but it can be called repeatedly on
different argument maps, so the same formatter can be applied to
different arguments.
Building and running the program Jump to heading
To compile this program, save it to a file named TestMessageFormat.java
.
Then set your CLASSPATH
to include the main .jar
file for ICU:
declare -x CLASSPATH=$HOME/icu/icu4j/main/core/target/core-76.1-SNAPSHOT.jar:$CLASSPATH
This line will need to be changed according to the ICU version you are using -- in this case, version 76.1.
And finally, compile and run the program with:
java TestMessageFormat.java
You can ignore the deprecation warnings, as these are just telling you that the MF2 API is a tech preview API that should not be depended on in production.
For more complicated experiments, you'll want to use Maven or your preferred build system. See the ICU user guide. As a reminder, you will need to build ICU from source and depend on it in your project in order to use the MF2 syntax as described in this documentation.
This program has no output, but you can check the exit code to see that the string comparison succeeded and the output of the formatter was correct:
$ echo $?
0