Over the past few months at work, I have been tasked with finding a solution to run a Portal / CMS system.   I went through a number of CMS systems, and Portals, doing the research and trying to find the feature sets that we required. I ended up making numerous recommendations to my Director.  In the end one stood apart from the rest (mainly due to request by my Director), and that was Liferay.

Not being a JAVA house, I somewhat scratched my head at the request before me, as Liferay is basically Java development and I don’t have a strong JAVA background.  But I quickly learned that it does support things other than JAVA, however you still CANNOT get away from the fact that it is JAVA under the hood of it all, and you will be at one point in time forced to modify portlets or extend the default environment of Liferay (currently version 6 as I write this up).

So, what Liferay does support (at least what matters to me) is PHP, Groovy, and Coldfusion (as it turned out — read on…).  PHP is supported and works pretty good, a developer could quite happily create PHP content driven Portlets with very little work.  Groovy (something a few members of my team use — yes I know, java related) is also supported, and you can essentially create ‘Groovlets’ (Groovy portlets).  But the real gem, is that Coldfusion 9 can create portlets, and those are compatible running on-top of JBOSS / Liferay.

Anyway, the important thing for me (and my team) is that Liferay 6 + Coldfusion = doable.  To install Coldfusion under Liferay 6, you will need the following:

  1. Download Liferay 6 with JBOSS (latest CE, or buy the EE license)
  2. Download Coldfusion 9 (developer — free license — limited to 3 ips I believe, if you need to test)
  3. Compile Coldfusion 9 as a deployable WAR file (which you will have Liferay auto deploy for you).

Assuming you know how to deply something via Liferay, you should now have Liferay 6 w JBOSS running, and ColdFusion 9 deployed under all that as a WAR. You should be looking at the browser window that pops up (by default on a Windows system, if that is what you choose to develop on).  The URL should be something like

http://localhost:8080/web/guest/

You can change that URL to

http://localhost:8080/cfusion/CFIDE/administrator/

and complete the standard ColdFusion setup (data sources, session sharing with JAVA, etc).

Once all that is setup, you can create your very own portlet, I will take the quick route to show you how to get started, there are many other settings / options to configure if you want to categorize / customize your portlet for Liferay use. I will probably write about some of those methods in the future depending on interest.

Ok, back to work. At this point we should have the following done:

  1. Liferay 6 with JBOSS running
  2. ColdFusion 9 under Liferay as a WAR file that was auto deployed (from the deploy folder)
  3. ColdFusion 9 administrator section reviewed and configured to your liking.
  4. Your default browser open with Liferay

Once all those are done, let us navigate to the folder that contains the root cfusion directory:

C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war

Once inside that folder, we will go into WEB-INF and modify (or create if they do not exist) the following files:

  1. liferay-portlet.xml
  2. portlet.xml
  3. web.xml

Here is what you should have (we will make a Hello World portlet — surprise):

liferay-portlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_5_2_0.dtd">
<liferay-portlet-app>
	<portlet>
		<portlet-name>helloWorld</portlet-name>
		<use-default-template>true</use-default-template>
	</portlet>
	<role-mapper>
		<role-name>administrator</role-name>
		<role-link>Administrator</role-link>
	</role-mapper>
	<role-mapper>
		<role-name>guest</role-name>
		<role-link>Guest</role-link>
	</role-mapper>
	<role-mapper>
		<role-name>power-user</role-name>
		<role-link>Power User</role-link>
	</role-mapper>
	<role-mapper>
		<role-name>user</role-name>
		<role-link>User</role-link>
	</role-mapper>
</liferay-portlet-app>

portlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0">
	<portlet>
		<portlet-name>helloWorld</portlet-name>
		<display-name>Hello World</display-name>
		<portlet-class>coldfusion.portlet.ColdFusionPortlet</portlet-class>
		<init-param>
			<name>cfcName</name>
  			<value>portlets.helloworld.hello</value>
  		</init-param>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>VIEW</portlet-mode>
			<portlet-mode>EDIT</portlet-mode>
		</supports>
		<portlet-info>
			<title>Hello World Portlet</title>
		</portlet-info>
	</portlet>
</portlet-app>

portlets.helloworld.hello using dot notation (portlets / helloword are folders, and hello is our CFC file), we define the PATH to the portlet CFC here we will be putting our hello.cfc file into the location

C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war\portlets\helloworld\

and inside that we place a blank text file hello.cfc (we will get to that in a bit).

web.xml:

	...
	<servlet>
		<servlet-name>WSRPProducer</servlet-name>
		<servlet-class>coldfusion.bootstrap.BootstrapServlet</servlet-class>
		<init-param>
			<param-name>servlet.class</param-name>
			<param-value>org.apache.axis.transport.http.AxisServlet</param-value>
		</init-param>
		<load-on-startup>101</load-on-startup>
	</servlet>
    <servlet>
        <servlet-name>helloWorld</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
        <init-param>
        <param-name>portlet-class</param-name>
        <param-value>coldfusion.portlet.ColdFusionPortlet</param-value>
        </init-param>
        <load-on-startup>16</load-on-startup>
    </servlet>
	...
     <servlet-mapping>
        <servlet-name>helloWorld</servlet-name>
        <url-pattern>/helloWorld/*</url-pattern>
    </servlet-mapping>
	...

This file should definitely exist (if I recall correctly), you will need to put this snippet (above) just UNDER the servlet definition WSRPProducer. Also the entry requires two parts, the servlet definition, and the servlet-mapping (they CANNOT be together, per DTD definition), so you will need to have all your servlet definitions above your servlet-mappings (or it just won’t re-deploy cfusion).

Ok, phew, we got that done. If you have problems, email me, if I have time I might help you 😉

Next we need to create a small Hello World Portlet, so lets get back to our empty hello.cfc file that we put into

C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war\portlets\helloworld\hello.cfc

hello.cfc:

<cfcomponent extends="CFIDE.portlets.ColdFusionPortlet">
	<cffunction name="doView" returntype="void" output="true">
		<cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object">
		<cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object">
	Hello World from ColdFusion inside Liferay !!!!
	<br/><br/>
	Running under Liferay hosted on JBOSS, this file will reflect updates immediately when modified. No need to compile or any other crud!
	</cffunction>
	<cffunction name="processAction" returntype="void" access="public" output="false" hint="Called by the portlet container to allow the portlet to process an action request.">
		<cfargument name="actionRequest" type="any" required="true" hint="A javax.portlet.ActionRequest java object">
		<cfargument name="actionResponse" type="any" required="true" hint="A javax.portlet.ActionResponse java object">
	</cffunction>
    <cffunction name="doHelp" returntype="void" output="true">
        <cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object">
        <cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object">
		<h1>ColdFusion Help</h1>
        <p>This is a Help message for the Hello Portlet.</p>
    </cffunction>
    <cffunction name="doEdit" returntype="void" output="true">
        <cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object">
        <cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object">
		<h1>ColdFusion Edit</h1>
        <p>This is a Edit message for the Hello Portlet.</p>
    </cffunction>
	<cffunction name="init" returntype="void" access="public" output="false" hint="Called by the portlet container to indicate to a portlet that the portlet is being placed into service.">
        <cfargument name="portletConfig" type="any" required="true" hint="A javax.portlet.PortletConfig java object">
		<cflog text="In init of Hello World from ColdFusion portlet">
	</cffunction>
</cfcomponent>

With the above code, that should get you your first ColdFusion 9 portlet for Liferay. If you watch you log (cmd prompt window running while Liferay is active) it will show that cfusion reloaded with 1 portlet active, it should look like something below.

19:38:38,455 INFO  [PortletHotDeployListener] 1 portlets for cfusion are available for use
08/02 19:39:14 INFO License Service: Flex 1.5 CF Edition enabled
08/02 19:39:14 INFO Starting Flex 1.5 CF Edition
19:39:14,503 INFO  [[/cfusion]] ColdFusionStartUpServlet: ColdFusion: Starting application services
19:39:14,503 INFO  [[/cfusion]] ColdFusionStartUpServlet: ColdFusion: VM version = 1.5.0_16-b02
08/02 19:39:14 Information [main] - Starting logging...
08/02 19:39:14 Information [main] - Starting license...
08/02 19:39:15 Information [main] - Invalid ColdFusion 9 license.
08/02 19:39:15 Information [main] - Invalid ColdFusion 9 license.
08/02 19:39:15 Information [main] - Developer Edition enabled

Once that is done, you will find your ‘Hello World’ portlet under the ‘Undefined’ catagory of ‘Adding’ portlets to the page under liferay. Enjoy! Happy CF9 Portlet’ing.

Questions? Leave a comment, I’ll try to get to it. I am assuming that you have some sense of using Liferay here, I am not going to train you how to use it, unless you pay me 😉



8 Comments to “Liferay and Coldfusion 9 Portlets… yes you can!”

  1. Benjamin Wong | January 17th, 2011 at 1:47 AM

    When I decided to do some reading about this guess who turned up on top 😉

    Anyway nice read =)

  2. Stijn Dreezen | September 6th, 2011 at 3:00 AM

    I followed your walkthrough, and everything works fine, liferay is running, coldfusion is running, it pefectly restarts when you touch a .xml file in the WEB-INF dir.

    I can also view the CFC in a browser, no errors there.
    The only problem is that liferay does’t seem to pick up the portlet (no INFO [PortletHotDeployListener] 1 portlets for cfusion are available for use).

    I copy-pasted the code from your site, and i verified everything multple times, but still no go.

  3. Jakub | September 8th, 2011 at 11:50 PM

    @Stijin, you may need to modify the portlet path (dot notation). I used the example portlets.Helloworld.hello (portlets is a folder inside the cfusion/ dir, Helloworld, is a subfolder of portlets, and hello is the ‘hello.cfc’ file). If you do not see the message that the portlet is ready for use it means that the CFC was NOT registered by Liferay for use in the ‘add application’ dropdown in Liferay. Yes, you can view the CFC directly, BUT you cannot utilize it like you want to inside Liferay 6.

  4. John Eastvold | January 30th, 2012 at 6:16 PM

    Hi Jakub,

    Wondering if you have any ideas on an issue that we’re encountering. We’ve installed and configured Coldfusion and deployed a Hello World portlet (with the help of your post and others. Thx!). We’ve done this on our dev box and we’ve found that if we restart the portal, our ColdFusion configurations have been wiped out and it’s as if we’ve just installed it and it needs to be setup and configured. But, our portlet files are still present. Any thoughts would be appreciated.

    John

  5. Jakub | February 1st, 2012 at 10:35 AM

    John, I haven’t experienced this CF clearing, have you gone in and configured your CF environment? Are you able to save settings / review the backend CF administrator?

  6. John Eastvold | May 25th, 2012 at 3:44 PM

    Hi Jakub,

    I wanted to share our resolution for the question I asked below and see if you had any thoughts on our current issue. Also, for context, we are working in a ‘flavor’ of Liferay called Luminis which is produced by Ellucian (formerly Sungard). We are a college and they are a higher education software company.

    We found that as ColdFusion and other apps are deployed, they are first put into a temp directory before being put in their live location. Not sure how that stripped out all the configuration settings (datasources, etc.), but with some suggestions from Ellucian, we found the fix.

    We had to create a context.xml file (or modify the “exsisting”) to have the entry prior to deployiong the cfusion.war. This disallowed the caching to the temp folder that liferay creates (at least in Luminis). The context.xml file is in (or goes in) the cfusion/METS-INF folder.

    On to our new issue. We’ve been successful with helloworld.cfc and even been able to return our username from our CAS from within the portlet (since Ellucian decided to obfuscate the internal username for multilingual reasons). We are now attempting to incorporate some web service calls that require the use of SOAP envelopes. We have this functioning in our stand-alone ColdFusion environment. A lot of what I needed was provided here (http://onlineanthony.blogspot.com/2010/05/using-ws-security-for-soap-in.html) by Anthony Israel-Davis. It was very helpful due to the web service that we’re accessing’s need for security headers. If you look through his tutorial you’ll see that it requires two .jar files be added to ColdFusion. This worked without issue in our stand alone environment. Now as we move this into our portlet we seem to have a class path issue. We are receiving the error:

    Object Instantiation Exception.
    Class not found: org.apache.ws.security.WSConstants

    This is my first ColdFusion installation done ‘deployment style.’ I’ve only worked in stand alone environments before and I’m not much of a Java guy. Does this error mean anything to you?

    Thanks in advance for any insight or ideas you can provide.

    John

  7. John Eastvold | May 29th, 2012 at 11:01 AM

    Jakub,

    I notice that I forgot to share the code that’s causing the error. It comes from trying to create a Java object from the .jar files that are added to ColdFusion. Here’s the line:

    variables.WSConstantsObj = CreateObject(“Java”,”org.apache.ws.security.WSConstants”);

    Here’s a link to the .cfc that’s being used:

    https://github.com/anthony-id/cfWSAuthenticator/blob/master/src/WSAuthenticator.cfc

    Any suggestions or insight would be appreciated.

    John

  8. Paulbaylis1 | August 5th, 2012 at 5:49 PM

    John, did you ever get an answer to your problem? I’m experiencing the same thing.

Leave a Comment