Wednesday, March 6, 2013

Customizing the Control Panel sections in liferay

Customizing the sections that are present in the control panel are flexible in liferay. You can control these sections from portal-ext.properties.

For customizing My Account, input a list of sections that will be included as part of the user form when updating a user in the My Account portlet.


#users.form.my.account.main=password,organizations,sites,user-groups,roles,categorization
#users.form.my.account.identification=addresses,phone-numbers,additional-email-addresses,websites,instant-messenger,social-network,sms,open-id
#users.form.my.account.miscellaneous=announcements,display-settings,comments,custom-fields


For customizing Users under Users and Organization, input a list of sections that will be included as part of the user form when updating a user.

#users.form.update.main=details,password,organizations,sites,user-groups,roles,personal-site,categorization
#users.form.update.identification=addresses,phone-numbers,additional-email-addresses,websites,instant-messenger,social-network,sms,open-id
#users.form.update.miscellaneous=announcements,display-settings,comments,custom-fields


Thursday, February 21, 2013

Log4j Logging in Liferay 6.1 on Websphere Application Server

In order to have log4j logging we need to have the log4j.xml or lo4j.properties in the classpath so that log4j will pick this configuration file and start logging accordingly. Ofcourse this is one of the methods for configuring the log4j.

We had a situation where we were using a third party api and to my surprise, it has log4j.xml in its jar file. I know it is ridiculous but it does and we can't get rid of this jar. To make scenario more complicated, this is present in the shared library and loaded before any other portlet app is loaded, as the default class loading policy is "Parent First".

Given the above scenario, configuring the logging with log4j in Liferay 6.1 on WAS became bit tricky. We had two options here

Option 1:

Changing the class loading policy to "Parent Last" on the portlet application (using WAS admin console) should do the trick. But it leaves the hooks, if at all present in your application, to behave strangely and almost make them not to work as expected.  

Option 2:

Rename the lo4j.xml and load it explicitly using the Servlet Context Listener. To make it more modular, create a context param for the log4j config file name and send it as a argument. All this configuration has to go into web.xml

We leaned towards Option 2, thus avoiding the night mares with liferay hooks that would be introduced with Option 1


Tuesday, February 5, 2013

Dynamic Query

Liferay API provides means of accessing the liferay default entities via its liferay API. There would be situations where you need to access a entity with parameters, other than the methods provided by liferay. In which case, dynamic query will be a handy way. It is also a method in the liferay API where you can add the custom query to retrieve the entity that you require.

Here is the sample code


ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
or if this service builder method is being called from external portlet better use 

ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader( "<<portlet_id>>" );
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
                           AssetCategoryProperty.class, classLoader).add(
                           PropertyFactoryUtil.forName("categoryId").eq(categoryId));


List<AssetCategoryProperty> liAssetCategoryProperty = AssetCategoryPropertyLocalServiceUtil
                           .dynamicQuery(dynamicQuery);

Here in the above example, I am trying to retrieve the properties that I define on the Asset Category. By default there is no method provided by liferay API (AssetCategoryPropertyLocalServiceUtil) to retrieve the AssetCategoryProperty using the category id. Hence Dynamic Query comes into picture.

SAML Portlet On Websphere 8.0

Deploying the saml-portlet plugin on the websphere throws exception (NullPointerException) resulting saml-portlet not deploying properly.


§

Websphere doesn't initialize filters (InvokeFilter) on startup, but rather, on the first call. This is different from Tomcat, which initializes during the application startup. The root of the issue (in Websphere) is that InvokerFilter is not yet initialized and set into the context at the time when used in HookHotDeployListener, which is why there is a null context and throws NPE.

http://www-01.ibm.com/support/docview.wss?uid=swg1PM62909

So the workaround is to set the following custom properties in the web container:

com.ibm.ws.webcontainer.initFilterBeforeInitServlet = true
com.ibm.ws.webcontainer.invokeFilterInitAtStartup = true

To specify web container custom properties in Websphere:
  1. In the administrative console click Servers > Server Types > WebSphere application servers > server_name > Web Container Settings > Web container .
  2. Under Additional Properties select Custom Properties.
  3. On the Custom Properties page, click New.
  4. On the settings page, enter the name of the custom property that you want to configure in the Name field and the value that you want to set it to in the Value field.
  5. Click Apply or OK.
  6. Click Save on the console task bar to save your configuration changes.
  7. Restart the server.
Once these configurations are made saml-portlet deploys correctly and runs perfect.

Setting/Getting the Custom Field (Expandos) values

At times during the development, we might end up defining the custom fields on the liferay default entities(User, Organization etc.,) in order to squeeze in the custom attributes that the project requirements dictates. Once they are defined (in the control panel), we can use the below methods to retrieve them

Method 1:

First get the entity here in our example User by using one of the relevant API methods

User user = UserLocalServiceUtil.getUserById(userid);

For setting the value

user.getExpandoBridge().setAttribute(IConstants.EXPANDO_USER_JOB_DESCRIPTION, "some desc" );

For retrieving the value


user.getExpandoBridge().getAttribute(IConstants.EXPANDO_USER_JOB_DESCRIPTION);

Method 2:

Some times due to some security restrictions (from where you access this method) the above method doesn't work.In which case we end up using the Expoandos API to set and get the values from the custom attributes

User user = UserLocalServiceUtil.getUserById(userid);

ExpandoTable table = ExpandoTableLocalServiceUtil.getTable(user.etCompanyId(),User.class.getName(), ExpandoTableConstants.DEFAULT_TABLE_NAME);
ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(user.getCompanyId(),User.class.getName(), table.getName(), "Custom Field Key" );
String strSsouserScreenNamePrefix =  ExpandoValueLocalServiceUtil.getData(user.getCompanyId(),User.class.getName(), table.getName(), column.getName(), user.getUserId(), StringPool.BLANK);

Friday, October 26, 2012

Liferay Password Retrival - Password Decryption

Liferay passwords can not be retrieved from the database. By default liferay uses MD5 hashes for password encryption. MD5 hashes are designed to be non reversible. When you call the method onthe user object as user.getPassword(), it wsill retrieve the encrypted password.

You can change this feature and store the plain password with out encryption by setting the property in the portal-ext.properties as passwords.encryption.algorithm=NONE.

This will store your password in plain text. This means your db admin would be able to see all including admin's password. Also, be aware that you have to set this before you first server start up.  Because changing password encryption may result in not being able to login.

When the first time the user is registered the user will get the email notification with password. This is achieved as the the email is sent in the same session as the user registration. The password is stored in the SessionMessages and retrieved from there (rather than the database) while sending the email.

Friday, September 7, 2012

Installing LIferay 6.1 on Websphere 8.


Liferay install and liferay home directory


  1. Create the Websphere Application Server.
  2. Deploy liferay.war
  3. Create the liferay home folder and create portal-ext.properties with the following properties            liferay.home=e:/myapps/liferay/sandbox         auto.deploy.dest.dir=e:/myapps/liferay/sandbox/websphere-deploy
  4. Create websphere-deploy in the liferay home folder.
  5. Once the liferay is installed, it will create all other necessary folders in the liferay home directory(data, deploy, logs)


Deploying Liferay Portlets in Websphere

Deploying the liferay portlets on websphere is 2 step process

  1. Put the .war in the deploy folder. Here the liferay will massage the .war file and add the necessary liferay dependent files and moves it to websphere-deploy folder. 
  2.        Install the application (.war) in the websphere-deploy folder from the admin console.


Specifying the portal-ext properties to liferay.war


Need to specify the liferay about the portal-ext.properties. So we do this by adding the app server JVM argument. For doing this do the following


Open Websphere Admin Console
Select the App server you created, on which you install liferay
In the configuration tab, Server Infrastructure-->Java and Process Management--> Process definition --> Additional Properties ---> Java Virtual Machine ---> Generic JVM arguments, add the following

-Dfile.encoding-UTF-8
-Dexternal-properties=e:/myapps/liferay/sandbox/portal-ext.properties

And in the Custom Properties add the following
java.net.preferIPv4Stack =true
java.net.preferIPv6Addresses=false

Adding the Shared Libraries and class loaders

Liferay requires the shared jars that it provides along with the liferay war file.

Change the Class Loader Order and add the shared libraries path

Application Servers --> <<App Server Name>> Class Loader --->
Class Loader Order = Classes loaded with parent class loader first

Application Servers --> <<App Server Name>> Class Loader ---> Additional Properties ---> Shared liferay references ---> and here create the library name  where is created in the:  Environment ---> Shared Libraries to refer the shared libraries folder of the liferay.

That is pretty much it. You are ready to go.