You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
It is very important that these guidelines for log and error (exception) messages are followed throughout the Weld codebase for a number of reasons:
JBoss projects require a printed message format of SEVERITY [Module/Category] ERRORID Localized message
For example:
ERROR [WeldBootstrap] WELD-45434 No Deployment structure specified.
The same format should be used for exception messages.
The category used should be relevant to the user, and should not simply be the class which logged the message.
Only error, info, and warn are required to be localized, as debug and trace are mainly for developers and jboss internal usage.
Weld uses slf4j with cal10n for providing localized messages, with a couple of enhancements to support this JBoss message format requirements.
cal10n includes a verification plugin for Maven, which checks that all keys present in the enum exist in the message bundle (for the required locales specified on the enum) and vice versa.
To ensure that the categories are kept relevant to the user, the Category enum is used to define the category. You should carefully consider whether the message to be printed fits into an existing category before adding one.
It's important to only log exceptions that are relevant to the user at DEBUG and above. Any messages logged to aid in debugging the library should be logged at TRACE.
Level | Usage |
---|---|
FATAL | Library is likely to/will crash and be unusable from then on |
ERROR | A definite problems that will affect user regardless of how the use the library |
WARN | Likely to be a problem that will affect the user regardless of how the use the library, or a something otherwise logged at FATAL that can be recovered from |
INFO | Lifecycle low volume (e.g. Library version), things that are of interest to a user |
DEBUG | Messages that will aid the user in debugging why their application is not working |
TRACE | Messages that will aid the library developer debug problems in the library (e.g. when the user reports a problem |
cal10n requires the use of an enum as the message key. All enums are stored in org.jboss.weld.logging.messages, and generally follow the naming pattern <Categoy>Message.
Message id's are blocked by category, 6 digits long, and zero padded. Initially a category is allocated a block of 100 ids, more blocks are allocated if needed. A message id must be specified by annotating the enum constant with @MessageId("XXXXXX"). Message id's are not included in the resource bundle text.
Messages may contain parameters, following the standard MessageFormat.
To obtain a logger, add a static import on loggerFactory(), and call loggerFactory.getLogger(Category.Foo) to obtain a LocLogger :
import static org.jboss.weld.logging.LoggerFactory.loggerFactory() import static org.jboss.weld.logging.Category.FOO import static org.jboss.weld.logging.messages.FooMessage.* ... private static final LocLogger log = loggerFactory.getLogger(FOO); ... log.info(BAR, parameter1, parameter2);
You may also obtain a XLogger to log exceptions.
In general, exceptions should be rethrown. However, occasionally, an exception should be caught and logged (for example if a thread has been spawned). If an exception must be logged, you should log the message at the relevant level, and the stack trace at debug, using an XLogger.
As exceptions are normally used to report errors, it is essential the exception message is internationalized as well. Weld uses cal10n to provide localization services for exception messages. To obtain the message conveyer, call loggerFactory().getMessageConveyer();. Each exception should take the message key, as well as a number arguments in it's constructor:
import static org.jboss.weld.logging.LoggerFactory.loggerFactory; import static org.jboss.weld.logging.messages.BeanMessage.USER_DEFINED_DECORATOR_DISALLOWED; ... private static final IMessageConveyor messageConveyer = loggerFactory().getMessageConveyor(); ... public <E extends Enum<?>> ForbiddenArgumentException(E key, Object... args) { super(messageConveyer.getMessage(key, args)); }
In general, it is recommended that constructers available on the superclass are overridden and made to throw an UnsupportedOperationException to prevent their use in error.
Note: in the future it is intended that the exception classes will use getLocalizedMessage(), however this has no effect on the API of the exception class.