Recently I encountered the problem of overriding error messages in my project created in JDeveloper using ADF/JHeadstart. I wanted to get rid of messages containing codes like JHS-00106 and JBO-27014 and replace them with my own messages. The JHeadstart Developer’s Guide briefly mentions this in the chapter 5 section “Internationalization”. However, the info in that section is kinda brief, so this article contains more info on this subject.
The JHeadstart Developer’s Guide mentions several ways to manage message resources in your application. It explains that messages can be defined in Java classes that extend java.util.ResourceBundle as well as in properties files and that the drawback of using properties files is that they cannot handle multi-byte characters properly. Moreover, it is possible to define multiple default resource bundles which allows you to define your own message bundles containing your customized messages. Finally, it says, to override error messages you need to include the message key, like “JHS-00100”, in your resource bundle and you should be fine.
Let’s focus on these last two first. Afterwards we’ll have a look on how to create a class that extends java.util.ResourceBundle and how to make sure your application uses it.
In a Struts application, the files that defines which message bundles can be used is struts-config.xml in the WEB-INF directory of the application. This file contains a line like this
<message-resources parameter="view.ApplicationResources" factory="oracle.jheadstart.view.strutsadf.JhsMessageResourcesFactory" null="false"/>
In order to define more than one message bundle, create a comma separated list of files that contains messages like this
<message-resources parameter="view.MyMessagesResources,view.ApplicationResources" factory="oracle.jheadstart.view.strutsadf.JhsMessageResourcesFactory" null="false"/>
Next, create a file called MyMessagesResources.properties in the view directory (or package if you like) in the WEB-INF/classes directory and restart the application. Done. If you’d like to have localized messages, e.g. in the Dutch language, create a file called MyMessagesResources_nl.properties and put it in the same view package and the application should pick it up.
To override the standard error messages as generated by ADF, it is in most cases suffcient to add the correct message key to the resource bundles defined in the struts-config.xml file and define your own message for it. For instance, adding the entry
JHS-00106=Search returned no matching rows
in the view.ApplicationResources.properties file will make the message “Search returned no matching rows” appear everytime a JHS-00106 error occurs.
The reason I say “most cases” originates from this Oracle forum discussion. In her post from April 21, Sandra mentions that “some types of Oracle errors are matched with the message bundles” but at this moment I am not sure exactly which types that are. I did find one error message that cannot be overridden like this, which is JBO-27014. Please note the JHeadstart Developer’s Guide mentions putting this error key into the standard messages bundles will override this error message, but it is my humble opinion this is wrong.
This brings us to the topic of extending the java.util.ResourceBundle class. The Developing Multilingual J2EE Web Applications using Oracle JDeveloper 10g document mentions there are to subclasses to java.util.ResourceBundle, namely ListResourceBundle and PropertyResourcebundle. The latter is used when using properties files as described above. Recall that using these files has two drawbacks:
- They cannot handle multi-byte characters properly
- The JBO-27014 (and probably other) error message cannot be overridden
This means we’ll have to make use of a java class that extends the java.util.ListResourceBundle class. To generate one and to make sure ADF uses it, open the System Navigator in JDeveloper and locate the Model.jpx file in the Model project. Right click this file and select “Edit Model…”. In the “Options” section you can click the “New…” button to add a message bundle class that extends the java.util.ListResourceBundle class.
The ListResourceBundle class extends most of the methods in the ResourceBundle class. The only method that needs be extended in your ListResourceBundle class extension is the getContents() method. ADF generates this method like this
protected Object[][] getContents()
{
return sMessageStrings;
}
The sMessageStrings member needs to be of type Object[][] and basically needs to be a two-dimensional array of key/value pairs. Simply create a String array containing the error code as key and the message as value and add it to the sMessageStrings array, for instance like this
private static final Object[][] sMessageStrings = new String[][] {
{"27014", "This attribute is mandatory."}
};
Please note the “JBO-” part cannot be included. If you do include it, the message will not be overridden.
My final goal is to setup the JBO-27014 error messages in such a way that they can contain placeholders like {1} and {2} which then are filled out with the correct corresponding Strings referring to the corresponding components in my web form. My colleague Lucas Jellema has contacted Steven Davelaar who pointed us to a weblog entry by Steve Muench explaining how to capture the error messages generated by BC4J like the JBO-27014 message. Besides that, ActionError handling in the current version of JHeadstart (version 10.1.2) needs a bit tweaking as this post on the Oracle forums indicates.
I need some more time to dive into this matter but once I get it to work I’ll be sure to share it with you. In case you already know how to do it, please let me know!
You have to add the customized message bundle to the bc4j projects *.jpx, in the options part of the dialog
add the resource bundle 🙂
We have used your last method
package be.iadvise.apps.serverinventory.model.messages;
import java.util.ListResourceBundle;
public class MessageBundleExceptions extends ListResourceBundle
{
private static final Object[][] sMessageStrings = new String[][] {
{“25002”, “Could not start the application. Call helpdesk.”},
{“26048”, “Application cannot connect to database.”},
{“26061”, “Application cannot connect to database.”},
{“27008”, “Application cannot connect to database.”},
{“27122”, “Application error, log a support ticket.”}
};
/**
*
* Return String Identifiers and corresponding Messages in a two-dimensional array.
* @return
*/
protected Object[][] getContents()
{
return sMessageStrings;
}
}
But he still won’t show us our custom message, he still shows the jbo errors