Community
Participate
Working Groups
We have seen various scenarios where switching the locale on the fly (mostly to get the new language) would be useful. This is especially true in RCP scenarios. Currently there are a few issues preventing this from working: - There is no locale switch lifecycle/notification mechanism. Various plugins will cache resource bundles and other things that are based on the locale. These caches would need to be flushed - classpath: it is possible for people to specify classpath entries based on the NL setting. For example, one could run special code for Japanese. If you switch to or from Japanese the classpath has to be updated. This is hard in general - registry caching: The registry is optimized to avoid resource bundle loading by pre-translating any available strings. - I'm sure there are others. It may be possible to allow for switching if people opt out of the optimizations described above which depend on static locale settings.
See bug 44824 for more interesting comments. (will mark as a duplicate of this)
*** Bug 44824 has been marked as a duplicate of this bug. ***
This may require a fix from bug #71594.
Moving confirmed bugs/enhancements out of the "inbox"
*** Bug 106999 has been marked as a duplicate of this bug. ***
Any plan on adding this enhancement in 3.2? This is an important feature to our product.
No plans for this in 3.2. This is a very fundamental problem as switching locales would require a new lifecycle to tell all plugins and data structures to relocalize. A worthy goal but not one we can tackle right now. Going forward we would greatly appreciate any patches or other help you can supply in this area.
See also notes in bug 106999.
Granted that one has to restart the workbench, is there a way to programmatically set what locale eclipse should start with at next start up? I would like to provide the user with a selection screen. If it means he have to restart - that's fine. Is there a way to set a preference or something for the next start?
there is no such option currently. We may well end up with something that allows you to programatically edit the config.ini and eclipse.ini files as part of the new provisioning work. If that were to happen then you would be able to change the configuration to use a particular locale but not just for the next run, rather for all subsequent runs.
*** Bug 222706 has been marked as a duplicate of this bug. ***
Just a few random thoughts on this issue: Since OSGi is getting more ground in Eclipse recently I propose to use the OSGi EventAdmin to notify users of the locale about a locale switch. There would be an extender that sets the systems default locale during runtime and posts a new event like: event.topic=java/util/Locale/Update locale.old=old locale ISO name locale.new=new locale ISO name All NLS classes would be OSGi EventHandlers themself and subscribe to this topic. However to do that, they would need a BundleContext which they have only if there is a Bundle-Activator defined in a standard manner. Another approach would be to not use the EventAdmin but let the NLS class register themself in a White-Board pattern approach inside OSGi. The Locale Extender could then call all registered NLS services and tell them to refresh. Similar the Eclipse AbstractUIPlugin and Registries would have to register themself as Locale change listeners. interface LocaleChangeListener { void localeUpdated(Locale newLocale); } AbstractUIPlugin and the Extension Registries that deal with localized bundle content based on the current Locale would have to implement this interface and refresh their caches if the locale is switched. Inside the system you should not call Locale.setDefault, but rather use the DynamicLocaleSwitcher OSGi service that the Locale Extender bundle registers. interface DynamicLocaleSwitcher { void switchLocale(Locale newLocale); } It would in turn set Locale.setDefault(newLocale) and fetch all LocaleChangeListener services and call them (in a background thread). We could introduce this behaviour step by step into all RCP related code. RCP could even provide a standard command + handler for all this. If you like the ideas I could sketch out a test bundle and RCP plugin and post it here.
since NLS is very low level we should shoot to avoid additional dependencies that will then wbe required by absolutely everyone. In this case perhaps we can use service factories to make a NLS service for each bundle. I've not really thought about this direction but it seems there should be support already for much of this workflow. Having said that, the use fo services may be a problem for startup performance. With 5000 bundles in a configuration, having the NLS services registered proactively (even using DS) may be quite a drag.
I'm not sure we should focus on the dynamic switching of locales. If we solve the issue of supporting multiple locales at once (think server-side), would that help solve the issue of switching locales on the fly? I think it could if the default case always looked at the currently set locale to pick the correct locale string to return. But I don't think the current way clients use the NLS class will make this easy since they simple access static fields to get locale strings. Currently the NLS class cannot support multiple locales because each translated message gets assigned to a static String field. This makes the message access very fast and gets rid of the message keys which helps with the memory overhead. But this unfortunately locks the classes extending NLS into a single locale at one time. Any solution we come up with should preserve as much of the performance optimizations we currently have as possible. I wondered if we could add some helper methods to the NLS class that would load multiple NLS class instances (one per locale) but that is not possible since you can only load a class once per class loader ;-). Ultimately we want the locale string lookup to be a simple field access. Perhaps we can think of a way to index the static fields in some way so the message strings can be kept in a String[] for quick lookup. So code like this: String message = MyNLSClazz.SOME_MESSAGE; Would change to something like this: String message = MyNLSClazz.get(MyNLSClazz.SOME_MESSAGE); The constant SOME_MESSAGE would have to be an int instead of a String. MyNLSClazz could use some static initializer to initialize its static int fields to incrementing ints. Under the covers the MyNLSClass.get() method would use the int passed in to index into an internal array loaded with the current local.
Agreed. we should remember that the current model was put in place with a very close eye towards space. That computation includes the space required for the literals and the literal names. Things like dynamic proxies and aspect weaving might help here somewhat. Tom Schindl and I chatted last night and he seemed to have some ideas in this direction.
However I would not like to have a dependency on aspectj or something like that in a base class. I think since nobody actually writes NLS classes by hand, the approach of Thomas could be the way to realize that. Could even use some reflection to re-assign the static fields after the local switched. But still you have the problem that the UI is usually created statically and the created controls, tooltips etc would not be notified about a new locale. A new locale could also mean that the texts of controls become longer or shorter and the UI would have to be re-adjusted. So the programmer would have to take that into account anyway. Some form of notification has to be sent. The various managers that create UI resources out of extensions could implement that without the programmers help, but the controls the programmer creates would have to be either recreated or at least change their texts and then re-adjusted.
yup. the introduction of multi-locale does not remove the need for locale switching lifecycle. Multi-locale support would be tied somehow to a session and, for example, in the RAP case may mean that sessions can have different locales, the locale of a session does not change. As for weaving etc, I suspect that the required modifications can be done at build time. For reference, check out the original design docs around the current NLS approach. We don't want to lose the benefits... http://www.eclipse.org/eclipse/platform-core/documents/3.1/message_bundles.html
I understand why the NLS class was introduced. I think we could just use the same load() method that uses reflection to refill the NLS classes fields when a locale switch event occurs. I was currently only focusing on RCP apps and forgot that server side applications should handle localization differently depending on some kind of session object. But maybe to get this rolling we should first try to implement this step by step. I would start with a that all NLS classes save themself inside a global list upon creation. A new static method inside NLS would allow the change of the locale. public static setLocale(Locale locale) { for all NLS in our list { item.load(); } } We could check how much more memory this would cost us. Maybe a command line setting or preference could be used to disable dynamic locale switching in environments where memory is more important.
would be interesting to know how well this actually works. It will tell us something about the need for lifecycle notification on locale changes. Are you proposing to supply a patch?
Yes Jeff I could work on a patch. But not this week anymore. Are there any deadlines? I think since its an API change it will have to go into 3.6 anyway.
agreed. we will have to cycle on this a few times as well. Ultimately locale switching should be addressed in conjunction with multi-locale.
(In reply to comment #19) > I understand why the NLS class was introduced. I think we could just use the > same load() method that uses reflection to refill the NLS classes fields when a > locale switch event occurs. I was currently only focusing on RCP apps and > forgot that server side applications should handle localization differently > depending on some kind of session object. But maybe to get this rolling we > should first try to implement this step by step. > > I would start with a that all NLS classes save themself inside a global list > upon creation. > A new static method inside NLS would allow the change of the locale. > > public static setLocale(Locale locale) { > for all NLS in our list { > item.load(); > } > } > > We could check how much more memory this would cost us. Maybe a command line > setting or preference could be used to disable dynamic locale switching in > environments where memory is more important. > I think a static list of NLS classes will be problematic because the classes that extend NLS come from bundles. The list would have to be weak references to prevent pinning of the class loader. I prefer my approach in comment 15 because it does not involve switching the locale down in the guts. It only keys off of the default locale set by the VM and switches automatically. Any listeners to locale switching can be made higher up. BTW, the extension registry also needs much work to support multiple locales and locale switching.
(In reply to comment #21) > Yes Jeff I could work on a patch. But not this week anymore. Are there any > deadlines? I think since its an API change it will have to go into 3.6 anyway. > (In reply to comment #22) > agreed. we will have to cycle on this a few times as well. Ultimately locale > switching should be addressed in conjunction with multi-locale. > Perhaps this can be done in e4 immediately with an eye to backport to 3.6?
(In reply to comment #15) > I'm not sure we should focus on the dynamic switching of locales. If we solve > the issue of supporting multiple locales at once (think server-side), would that > help solve the issue of switching locales on the fly? Supporting multiple locales at once is also a problem we needed to solve in RAP (http://www.eclipse.org/rap), and we are still in need of a general solution in order to allow development of RCP and RAP applications from a single code base. Thus, providing support for multiple locales would be a great benefit for RAP (and probably other server-side projects as well). And I agree that solving this issue first is a good preparation for dynamic locale switching support. From my point of view, a solution needs to involve several steps: 1) The NLS class must support different locales, as already discussed. There is already another bug for this: bug 226340, would it make sense to switch the discussion on this specific topic over to this bug? 2) The extension registry must support reading in different locales. Currently, translatable strings in extensions are resolved once and the results are cached. See bug 244468. 3) There must be a mechanism to obtain the default locale for the current user. For 1), we already have a solution for RAP that we'd like to contribute to the discussion. Jeff and I thought about a way to integrate this solution into the NLS class. Jeff also came up with a simple solution for 3). I will shortly attach a patch that includes both to bug 226340.
regarding point 2) of your comment. Also user created extensions must have a way to be notified about locale changes. I think the white-board-pattern is still the way to go. Have a Platform.setLocale method that propagates the new locale to interested listeners. That way we could step by step make the registry ready for that change. The problem remains with already created UI widgets. They usually use the setText method and layout the interface base on the initial text. All the controls would have to set their text again and this can not be done automatically. The programmer has to keep a dynamic locale switch in mind always himself. He must then react to a locale switch in the appropriate way. One way to perform a semi-automatic approach would be to have each SWT widget, that can have localized text set to it, know where to update its text from. This could be done by the widget register itself as an listener for locale changes and use its widget data that contains the key into a NLS class. However even simple form controls such as labels that have composited text would not be able to update themselves. So the burden is still on the programmer who creates the user interface controls to update them when the locale is switched.
(In reply to comment #26) Philipp, you're referring to switching locales on the fly (what this bug is actually about). Thomas Watson suggested in comment 15 to solve the multi-locale problem first (if I understand correctly), and that's also the idea of my proposal. I think if we have a solution, that supports multiple users with different locales (but without dynamic locale changes), this would help for a lot of cases and it would also be a good preparation to supporting dynamic locale changes. Of course, there must be some notification infrastructure for this. Would it make sense to add this problem as point 4) ?
I understood that we first should try to find a solution for multiple locales support. I just wanted to remind us that this is solving only the first part of the problem. The UI still has to update itself then. Which could be very well a point 4 on your list/agenda.
Thinking about this a bit more I wonder if the mult-locale and locale-switching problems are the same. Ralf and I looked at multi-locale stuff and the main body of work was to all for the lookup of messages dynamically based on the "current" locale (however that is defined). Locale switching is really about the lifecycle. It would apply in single locale as well as multi-locale situations. Taht is, say a server has sessions and that the session users are able to switch locales. There we would have multiple concurrent locales in a global sense but only one per session. In, for eample, a RAP application there would still need to be a lifecycle change broadcast so that the views can update themselves. Summary, these are all related but we could do them independently.
(In reply to comment #29) I agree, they can be separate and locale switching will need some kind of lifecycle event mechanism to inform interested parties of the change. My main thought was if we could support multiple locales then it may be easy to build some notion of session/context (or default locale) switching on top that would switch between the different locales on the fly.
yeah these are definitely related but you may have to switch locales within a session. This sort of usecase will inform the design of the locale switching stuff. For example, locale listeners (whatever we call tehm) will want the ability to hear only about changes for the session they are in. That means that the session identifier (whatever) has to be part of the registration. Otherwise all listeners would have to do the filtering work and it is not as extensible. So do we have a good bug to track the multi-locale work? Ralf enumerated a few but it would be good to have one that captured the overall problem...
(In reply to comment #31) > So do we have a good bug to track the multi-locale work? Ralf enumerated a few > but it would be good to have one that captured the overall problem... I opened bug bug 275658 for supporting multiple locales.
Eclipse 4 adds a ILocalChangeService service for switching the local at runtime. This requires that plug-ins use the new Message service. See the blog posts from Dirk how to use this: http://blog.vogella.com/2013/11/05/new-message-extension-update/ http://blog.vogella.com/2014/03/14/eclipse-luna-m6-localization-update/ I think this feature request can therefore be marked as fixed.