| Summary: | Externalize Strings generates code with unhandled exception MissingResourceException | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Dan Kehn <kehn> |
| Component: | UI | Assignee: | Dani Megert <daniel_megert> |
| Status: | RESOLVED WONTFIX | QA Contact: | |
| Severity: | minor | ||
| Priority: | P3 | CC: | daniel_megert |
| Version: | 3.0.1 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
Using a super class isn't possible since this would bind Externalize String to the runtime. Externalize String must work with "normal" Java code as well. Another idea is to lazy create the bundle inside getString so that the exception can be handled there. Daniel, comments. Good point, Dirk. A common superclass could be optionally specified on the current Externalize Strings dialog under the "accessor class" field. If you want to get fancy, auto-select / prefill the accessor superclass field if the classpath / plug-in <requires> clause includes the "standard" implementation. For extra credit, add a settable default in the Java preferences. To create the resource bundle lazily makes most sense to me. For the superclass request we could think about offering a template for the message class, but on the other hand that's a bit overkill; the user is already free to change that class as they want after it is created. Wouldn't be bad it we add a comment to 'BUNDLE_NAME' to not change this field name as the NLS-wizard needs this to recognize it as a NLS-class Moving to Dani! |
The Source > Externalize Strings... choice generates a resource bundle wrapper that looks something like this (using "Hello, World" template): --- begin --- public class Messages { private static final String BUNDLE_NAME = "helloworld.messages";//$NON-NLS-1$ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle .getBundle(BUNDLE_NAME); private Messages() { } public static String getString(String key) { try { return RESOURCE_BUNDLE.getString(key); } catch (MissingResourceException e) { return '!' + key + '!'; } } } --- end --- Subsequent uses of this wrapper look like this: --- begin --- public void run(IAction action) { MessageDialog.openInformation( window.getShell(), Messages.getString("SampleAction.0"), //$NON-NLS-1$ Messages.getString("SampleAction.1")); //$NON-NLS-1$ } --- end --- The problem is the static initializer private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); If the bundle isn't found, whatever method that happen to be the caller will get the unchecked exception MissingResourceException, which it will very likely not handle. In the case of "Hello, World", the result is "Could not create action delegate for id: helloworld.SampleAction Reason: Plug-in helloworld was unable to load class helloworld.SampleAction." Perhaps this was intentional, i.e., the resource bundle wrapper didn't want to 'eat' the error. I think a better solution would be to log an error and return the key. It would be prudent, whatever the choice, to put this code into a common wrapper superclass (e.g., org.eclipse.runtime.core.AbstractMessages) where it could (a) define the common methods that are currently generated in the RB wrapper, and (b) be corrected release-to-release if errors / improvements are necessary.