Wednesday, May 30, 2012

Grails groovy.lang.MissingPropertyException: No such property: portletResponse

Problem:

Using the Grails Porlet plugin, I submitted an action request which would in turn invoke the actionView method of the generated portlet. However I received the following error, when I try to use the auto injected variable 'portletResponse':

groovy.lang.MissingPropertyException: No such property: portletResponse

Discussion:


I decided to dump out all the attributes for the request object as follows:

    def actionView = {
        logger.info("actionView")
        
        
        for (String attrName : request.getAttributeNames()) {
            logger.info("Name="+attrName+"    Value="+request.getAttribute(attrName))
        }
        portletResponse.setRenderParameter("prp-1", "value-1"); // <-- portletResponse is supposed to be auto injected
    }

Then when I viewed the output I saw the following in the logs:

2012-05-30 23:48:28,703 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.servlet.include.request_uri    Value=/apf-portal/Apf/invoke
2012-05-30 23:48:28,703 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.servlet.include.context_path    Value=/apf-portal
2012-05-30 23:48:28,704 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.servlet.include.servlet_path    Value=/Apf
2012-05-30 23:48:28,704 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.servlet.include.path_info    Value=/invoke
2012-05-30 23:48:28,704 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=com.liferay.portal.kernel.servlet.PortletServletConfig    Value=org.apache.catalina.core.StandardWrapperFacade@19a5b51
2012-05-30 23:48:28,704 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=grails.portlet.name    Value=Apf
2012-05-30 23:48:28,705 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=grails.portlet.config    Value=com.liferay.portlet.PortletConfigImpl@1647724
2012-05-30 23:48:28,707 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.portlet.config    Value=com.liferay.portlet.PortletConfigImpl@1647724
2012-05-30 23:48:28,708 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=com.liferay.portal.kernel.servlet.PortletServletResponse    Value=com.liferay.portal.kernel.servlet.StringServletResponse@faa1b4
2012-05-30 23:48:28,708 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=INVOKER_FILTER_URI    Value=/Apf/invoke
2012-05-30 23:48:28,717 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.portlet.response    Value=com.liferay.portlet.ActionResponseImpl@13a1d01
2012-05-30 23:48:28,718 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=PORTLET_ID    Value=Apf_WAR_apfportal
2012-05-30 23:48:28,730 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=com.liferay.portal.kernel.servlet.PortletServletRequest    Value=com.liferay.portal.servlet.NamespaceServletRequest@3858a8
2012-05-30 23:48:28,731 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.portlet.portlet    Value=org.codehaus.grails.portlets.GrailsDispatcherPortlet@9a5b5c
2012-05-30 23:48:28,740 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=WINDOW_STATE    Value=normal
2012-05-30 23:48:28,740 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=org.codehaus.groovy.grails.WEB_REQUEST    Value=ServletWebRequest: uri=/c/portal/layout;client=127.0.0.1;session=ED170D76D6BB5AF372ED336B020604E5;user=2
2012-05-30 23:48:28,754 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.portlet.lifecycle_phase    Value=ACTION_PHASE
2012-05-30 23:48:28,754 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=javax.portlet.request    Value=com.liferay.portlet.ActionRequestImpl@14480c8
2012-05-30 23:48:28,761 [http-bio-8080-exec-104] INFO  portal.ApfPortlet  - Name=com.liferay.portal.kernel.servlet.PortletServletFilterChain    Value=com.liferay.portlet.FilterChainImpl@62fa4e

As you can see, the attributes highlighted in red can give you access to the portletRequest and portletResponse objects.

Solution:

After dumping out the attributes you can now get the PortletRequest and PortletResponse as follows:


        PortletResponse portletResponse = request.getAttribute("javax.portlet.response")
        PortletRequest portletRequest = request.getAttribute("javax.portlet.request")


grails portlet plugin actionView not invoked

Problem:


I was using the Grails plugin for creating Portlets found here: http://grails.org/plugin/portlets

I created the Portlet code by invoking the following command: 
grails create-portlet MyFirst

This automatically created the Portlet class which contains the following code snippet:


    def actionView = {
        //TODO Define action phase for 'view' portlet mode
        portletResponse.setRenderParameter("prp-1", "value-1");
    }

The following the instructions as documented, I invoke the following command to generate the view for the portlet:

grails generate-portlet-views com.company.MyFirst
It creates several files with one of them being the view.gsp file. This file has a snippet as shown:


<form action="${portletResponse.createActionURL()}">
    <input type="submit" value="Submit"/>
</form>


The trouble was, when I goto submit the form, the actionView method never gets invoked. Only the renderView method get's invoked:

Solution 

The problem was that the form did not declare a POST method. I modified the view.gsp as follows:


<form action="${portletResponse.createActionURL()}" method="post">
    <input type="submit" value="Submit"/>
</form>

Reference:

 

Tuesday, May 29, 2012

Native SQL query using Hibernate causes ArrayIndexOutOfBounds

Problem:


In hibernate I was trying to use a native SQL query to retrieve records from the database when I encountered an ArrayIndexOutOfBoundsException on the following piece of code:


                String sql = "SELECT * FROM fcs f"
                SQLQuery query = session.createSQLQuery(sql)                
                //query.setString(0, barcode.toString())
                try {
                    list = query.list()   // <-- ERROR HERE
                } catch(Exception e) {
                    //e.printStackTrace()
                    logger.error(e)
                    ByteArrayOutputStream baos = new ByteArrayOutputStream()
                    PrintWriter pw = new PrintWriter(baos)
                    e.printStackTrace(pw)
                    pw.close()
                    byte[] array = baos.toByteArray()
                    String exp = new String(array)
                    logger.error(exp)
                }

As you can see, I managed to dump out the stacktrace which looked as follows:


Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
   at org.hibernate.type.TypeHelper.disassemble(TypeHelper.java:146)
   at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:106)

The important thing to notice about this stacktrace is that the error happens out of the StandardQueryCache.

Solution:


In grails, by default the standard query cache was enabled. To workaround the issue, I've disable it in the DataSource.groovy file as follows:


hibernate {
    cache.use_second_level_cache = false
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}

References:


Grails Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

Problem: 

When using mySQL Hibernate to convert a database value to a Timestamp I get the following error:

Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

 Solution:

 append the zeroDateTimeBehaviour=convertToNull parameter to end of the URL configuration as follows:

jdbc:mysql://localhost:3306/facs?zeroDateTimeBehavior=convertToNull

References:


Thursday, May 24, 2012

Grails data binding does not work on injected methods

Problem:

For Grails projects, you can use inject whole method definitions in the BootStrap.groovy file.

However, there is a drawback to method injection:

Grails will not be able to perform data binding on an injected method

 For example if we define the following method in BootStrap.groovy:

Bootstrap.groovy
domainClass.metaClass.getAttributeMap = {
   return new Map()
}

And then we our GSP file:

GSP file
<g:textField name="attributeMap[123].value" />

Grails will not be able to bind the value of the input element in the GSP defined by "attributeMap[123].value", to the domain object through the injected method getAttributeMap() .

Workaround:

Method injection has a lot of advantages and it would be a shame if you had to give it up simply because data binding could not work. Oneway around this problem, is to define a concrete method that will internally invoke the injected method.

For example,


     public Map<String, Attribute> getAttributeMapForDataBinding() { // <--- Define concrete method
         return this.getAttributeMap() // <--- Invoke the injected method
     }

Then in your GSP you can have:
<g:textField name="attributeMapForDataBinding[123].value" />

Sunday, May 13, 2012

Spring STS plugin manager issue

Problem: The Plugin Manager window does not appear

I am using Spring STS 2.9.1 when I encountered an issue where the Plugin Manager was refusing to show up

Discussion:

My first instinct was to try a newest release of Spring STS which at the time was 3.0.0.M1
I downloaded and installed it, and was able to successfully open the plugins manager. YAY!
At first, I thought I was finished and ready to continue coding. Then when I went to open up a file, just about any file, I get a NullPointerException. I realized this version had it's own set up problems, that I was not ready to deal with.

I returned back to version 2.9.1 and found a way to patch it up. The solution is below:

Solution:


I managed to find a patch with a fix to the "Grails support" extension from a nightly build. To do this, in the STS menu select:

Window -> Preferences -> Install/Update-> Available software sites


Under "Available software sites" add the following sites:
  1. http://dist.springsource.com/snapshot/TOOLS/nightly/e3.7
  2. http://download.eclipse.org/mylyn/snapshots/3.7/
 Then click "Ok" and close the window.


 To activate the update process do the following:

Help -> Check for Updates

Follow the instructions to perform the update and restart STS.

And your good to go!

References:


Liferay LDAP com.liferay.portal.UserScreenNameException

I was attempting to configure Liferay to use LDAP.

After configuration was complete, I attempted to login using my LDAP credentials and I encountered this error:


com.liferay.portal.UserScreenNameException
I looked around for answers and it appears that the "Screen name" parameter is sensitive to space characters and underscores as mentioned in this forum:

http://www.liferay.com/community/forums/-/message_boards/message/5681334

So I switched the "Screen name" value from "cn" to "uid", and this resolved the issue