Skip to content

How to read the file in Liferay (outside of portlet)?

Say I have 3 modules in a Liferay project, A, B and language. Module A is a normal module with portlet in it. Module B, however, is a portletless module, it is nothing more than a plain Java utility module. language module is something like what is described in the “Localizing Your Application” article in Liferay’s Help Center.

Now, I have one file in each of these modules. file in the language module contains properties that are to be shared between modules A and B and file in modules A and B contains properties specific for each module.

Now, this Help Center’s article has defined what to do to enable reading from those files in a module. However, this article says that it is required to configure a portlet in the module where file is located.

That step may work for the module A in my case, but for module B I can not do this since module B is portletless.

Inside the module B I tried reading the file with the following code: com.liferay.portal.kernel.language.LanguageUtil.get("locale", "key");

However, this does not work. It does not find the keys which I put in the B‘s file. However, interestingly enough, what it finds are keys from the language‘s file.

So, surprisingly invoking get method of the LanguageUtil class inside the B module works, just it reads unwanted file.

My question here is, how can I configure Language Utilities to read the file from the portletless b module instead of the language common language module?



There are several layers to unfold here:

Liferay has pulled together almost all of its localization keys into a single module. From a product perspective, this is great, as it allows central handling of overrides, avoids duplicates, and even enables a UI to change those common keys.

For custom extensions, centralization is not such a great thing, and you’d rather come with your own translations in your custom modules (or explicitly use the default ones).

Enter OSGi: With using LanguageUtil, my understanding is that you’re using the “current bundle” perspective, and LanguageUtil will only check Liferay’s own central translation repository. What you can (and likely should) do is to utilize ResourceBundleUtil in such a way:

ResourceBundle bundle = ResourceBundleUtil.getBundle(locale, this.getClass().getClassLoader());
String result = ResourceBundleUtil.getString(bundle, key, parameter);

Instead of this.getClass().getClassLoader(), you can of course provide any other class’ loader, but it should give you a hint. This provides the bundle in which the translation is located.

Encapsulate this in a method that defaults back to any other localization that you’d like (could be another bundle, or Liferay’s global one), and you’ll find your translation.

Of course, you can also deploy a plugin that adds to Liferay’s own translations, but personally, I prefer not to go that route. There’s always potential to run into conflicts with other modules that try to translate the same key differently, or for Liferay to introduce the same key at some point in time (and it doesn’t play well with an individual portlet’s translation)