Message Bundle Interfaces
Message bundle interfaces provide a way to internationalize exceptions or strings. A message bundle interface is
annotated with @MessageBundle. Each method in must be annotated with @Message
which will be used to determine the String used for either the return type or the message for the exception being
returned.
The value for a @Message may contain an expression.
| Expressions are in the form of ${key:defaultValue}. If the key is prefixed withsys.a system property is
used. If the key is prefixed withenv.an environment variable is used. In all other cases the properties are resolved
from theorg.jboss.logging.tools.expressionPropertiespath. If the key is not found in the properties the default
value will be used. | 
| Expressions are processed at compile time. The values will be hard-coded in the generated source files. | 
The following constraints are placed on methods in a message bundle:
- 
The return type must be one of the follow - 
A java.lang.String
- 
A java.lang.Throwableor a subtype ofjava.lang.Throwable
- 
A java.lang.function.Supplierwho’s return type fits one of the other two constraints above.
 
- 
- 
The method must be annotated with @Messageor a message must be inheritable.
- 
A method can have only one @Causeparameter.
- 
A method can only have one @Producerparameter.
| A message is inheritable if the two methods have the same name and same number of format parameters. | 
| A format parameter is a parameter that has no annotations or is annotated with one of the following annotations; @FormatWith,@Posor@Transform. | 
Example Message Bundle
@MessageBundle(projectCode = "CW") (1)
public interface ErrorMessages {
    ErrorMessages MESSAGES = Messages.getBundle(ErrorMessages.class);
    @Message("Version %d.%d.%d.%s") (2)
    String version(int major, int minor, int macro, String rel);
    @Message(id = 1, value = "Value '%s' is invalid")
    IllegalArgumentException invalidValue(Object value);
    @Message(id = 2, value = "Failure closing %s") (3)
    CloseException closeFailure(@Cause Throwable cause, @Param @Pos(1) Closeable c);
    CloseException closeFailure(@Cause Throwable cause, @Param @Pos(1) Closeable c, @Suppressed Throwable... errors);
    @Message(id = 3, value = "Parameter %s cannot be null")
    Supplier<String> nullParam(String name);
    @Message(id = 4, value = "Operation %s failed.")
    <T extends RuntimeException> T operationFailed(@Producer Function<String, T> fn, String name); (4)
    <T extends RuntimeException> T operationFailed(@Producer BiFunction<String, IOException, T> fn, @Cause IOException cause, String name);
}| 1 | The projectCodewill be prepended to messages which have anidspecified. For example withid = 1the message will be prepended withCW000001. You can control the number padding with thelengthproperty on the annotation. | 
| 2 | No idis specified for this message which means no id will be prepended on this message. | 
| 3 | The @Paramannotation tells the generator that the parameter should be used to construct theCloseException. The@Pos(1)annotation indicates the parameter should also be used when formatting the message. | 
| 4 | The @Producerannotation indicates that theFunctionshould be used to create the exception being returned. | 
| Message bundle interfaces can also contain valid message logger methods. |