Thursday, June 27, 2013

Liferay 6: Monitoring tomcat.

The Liferay tomcat bundle is available for download on http://www.liferay.com/downloads/liferay-portal/available-releases and instant use. It ships pre-configured with hypersonic database and you can switch to mysql, oracle, etc for permanent solutions.

When moving your site or solution to production server there is always uncertainty on how much the load will be coming at peak time, how many request the tomcat will be able to server with Liferay. Although the Apache tomcat comes with tomcat-manager application that allows you to monitor all the resources via JMX beans. but since this have been removed in Liferay-tomcat bundle thus it is hard to monitor the resources and threads the tomcat server is consuming. Thus to over come this shortcoming, below are the steps to enable the monitoring in the tomcat:

Server Details
Liferay: 6.1.2 GA2 Enterprise
Tomcat Bundle: 7.0.27
Java 6

Step 1:
Stop the running Liferay tomcat server and clean the temp and work folder.

Step 2:
Download the vanilla apache tomcat server of the same version and unzip it at some temporary location.

Step 3:
Copy host-manager and manager application <tomcat>/webapps directory to liferay installation at <liferay-tomcat-bundle>/tomcat-7.0.27/webapps

Step 4:
Create a manager.xml file at location <liferay-tomcat-bundle>/tomcat-7.0.27/conf/Catalina/localhost.
And the following content to it and save it

<Context antiResourceLocking="false" privileged="true" useHttpOnly="true">
 
 </Context>
Step 5:
Now open file <liferay-tomcat-bundle>/tomcat-7.0.27/conf/tomcat-users.xml in edit mode. And the below content inside the tag <tomcat-users>.

<tomcat-users>
...

  <role rolename="tomcat"/>
  <role rolename="manager-gui"/>
  <role rolename="standard"/>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="manager,admin,standard,manager-gui,tomcat"/>

...
</tomcat-users>

Step 6:
Now restart the tomcat server and go to the URL: http://localhost:8080/manager/html and you will be prompted for username and password which should be the same as defined above.



And now you can monitor the tomcat resources and can tune them accordingly.



Monday, May 13, 2013

Java Reflection API: Calling methods

Moving forward from my previous article: Java Reflection API: Constructing Objects

Using Java Reflection you can inspect the methods of classes and invoke them at runtime. This is done via the Java class java.lang.reflect.Method. Below are the details to achieve the same:

Obtaining Methods
You can obtain the methods from the Class object:
Method[] methods = mClass.getMethods();

The Method[] array will have one Method instance for each public method declared in the class.

If you know the precise parameter types of the method you want to access, you can do so rather than obtain the array of all methods. This example returns the public method named "mMethod", in the given class which takes a String as parameter:
Method method = mClass.getMethod("mMethod", new Class[]{String.class});
If the method trying to access takes no parameters, pass null as the parameter type array:
Method method = mClass.getMethod("mMethod", null);
Parameters and Return types
To access details about method parameters and return types, do the below:
Class[] parameterTypes = method.getParameterTypes();

Class returnType = method.getReturnType();
Calling methods

The null parameter is the object you want to invoke the method on. If the method is static you supply null instead of an object instance. In this example, if mMethod(String.class) is not static, you need to supply a valid mObject instance instead of null;

The Method.invoke(Object target, Object ... parameters) method takes an optional amount of parameters, but you must supply exactly one parameter per argument in the method you are invoking. In this case it was a method taking a String, so one String must be supplied.
Method method = mClass.getMethod("mMethod", String.class);
Object returnValue = method.invoke(null, "value-1");


Java Reflection API: Constructing Objects


Moving forward from my previous article: Java Reflection API: Introduction

Using Java Reflection API, you can instantiate objects at runtime and invoke class constructors.
Getting Constructor
To get the list of all public constructors declared use the below code:
Constructor[]
constructors = mClass.getConstructors();

Here Constructor[] is an array of type java.lang.reflect.Constructor. However If you have the precise parameter types of the constructor you want to access, you can do so rather than obtain the array all constructors. Below example returns the public constructor of the given class which takes String as parameter:
Constructor constructor
= mClass.getConstructor(new Class[]{String.class});

Further to read all the input parameters of a constructor, do like this:
Class[] parameterTypes =
constructor.getParameterTypes();

Do the below to create an object using Java Reflection:
Constructor constructor = mClass.getConstructor(String.class);
Object mObject = constructor.newInstance("argument-1");
Next post in the series is Java Reflection API: Calling Methods

Java Reflection API: Introduction

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.  It enable applications to perform operations which would otherwise be impossible. An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.
Thus Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.

The Drawbacks of reflection are:

  • Performance overhead
  • Security restrictions
  • Exposure of internals
Creating a Class Object when you don't know the class name at runtime:
String className = ??? //get fully qualified classname at runtime
Class mClass = Class.forName(className);
The Class.forName() method may throw a ClassNotFoundException if the class cannot be found on the at runtime.

You can access the modifiers ("public", "private", "static" etc.) of a class via the Class object. 

int modi = mClass.getModifiers();
Now using java.lang.reflect.Modifier , you can check the modifier info, for example:
Modifier.isAbstract(modi);

You can access the constructors of a class like this: 
Constructor[] constructors = mClass.getConstructors();
You can access the methods of a class like this:
Method[] methods = mClass.getMethods();
You can access the fields of a class like this:
 Field[] fields = mClass.getFields();
Next post in the series is Java Reflection API: Constructing Objects

Tuesday, April 23, 2013

Liferay: using DynamicQuery in a velocity template.

Consider a scenario if you have 1000 records in a Dynamic Data List (DDL) record set. You need to show only 20 latest records. One ways is to bring all the records and use a loop to show the records and break when a counter is greater then 20, this will cause slowness in page as you are bringing the complete record set.

To overcome this consider if you bring only latest 20 records from database something like at most list screens in liferay where pagination is used. Below is the set of lines that will allow you to achieve this;



#set ($ddlRecordSet = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalService'))
#set ($ddlLocalService = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalService'))

#set ($recordSetId = $getterUtil.getLong($reserved_record_set_id.data, 0))
#set ($DDLrecordClass = $portal.getClass().forName("com.liferay.portlet.dynamicdatalists.model.DDLRecord"))
#set ($dqfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil"))
#set ($ofu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.OrderFactoryUtil"))
#set ($rfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil"))
#set ($q = $dqfu.forClass($DDLrecordClass))
#set ($V = $q.add($rfu.eq("recordSetId", $getterUtil.getLong($recordSetId))))
#set ($V = $q.addOrder($ofu.desc("modifiedDate")))
#set ($records = $ddlLocalService.dynamicQuery($q,0,20))
#set ($recordTitle = $ddlRecordSet.getRecordSet($recordSetId))
#set ($title = $recordTitle.getName())

You can modify the dynamic query as per your needs to order data on different columns.