Recent Bloggers

Andrea Di Giorgi

3 Mensagens
26 de Dezembro de 2014

Jorge Ferrer

Staff
59 Mensagens
23 de Dezembro de 2014

Olaf Kock

Staff
90 Mensagens
18 de Dezembro de 2014

David Kubitza

2 Mensagens
14 de Dezembro de 2014

Meera Prince

19 Mensagens
4 de Dezembro de 2014

James Falkner

Staff
100 Mensagens
2 de Dezembro de 2014

Juan Fernández

Staff
17 Mensagens
28 de Novembro de 2014

Gregory Amerson

Staff
26 Mensagens
25 de Novembro de 2014

Cody Hoag

Staff
6 Mensagens
25 de Novembro de 2014

Duke H

Staff
2 Mensagens
24 de Novembro de 2014

Liferay Maven Support in Liferay 6.1 GA3

Company Blogs 18 de Junho de 2013 Por Mika Koivisto Staff

We've finally released both CE and EE versions of Liferay 6.1 GA3 and along with those releases we've also released the corresponding versions of Liferay Maven Support and Portal artifacts. The version numbers are 6.1.2 for CE GA3 and 6.1.30 for EE GA3. With this release there is one significant improvement in the Liferay Maven Plugin and that is they are no longer directly dependent on a Liferay Portal version. We could have just released one version and it would have worked with either portal version, in fact they both work with any portal version starting from 6.1.0. In the future we will probably move to a single release of Liferay Maven Support which will eventually have it's own release cycle completely independent of the portals release cycle.  

All the archetypes will now have a separate property for Liferay Maven Plugin version called liferay.maven.plugin.version. The plugin will also now require you to tell which portal version you are developing against and you'll do that by providing it liferayVersion in the configuration section. Here's a example from liferay-theme-archetype:

  
<plugin>
  <groupId>com.liferay.maven.plugins</groupId>
  <artifactId>liferay-maven-plugin</artifactId>
  <version>${liferay.maven.plugin.version}</version>
  <executions>
    <execution>
      <phase>generate-sources</phase>
      <goals>
        <goal>theme-merge</goal>
        <goal>build-css</goal>
        <goal>build-thumbnail</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
    <appServerDeployDir>${liferay.app.server.deploy.dir}</appServerDeployDir>
    <appServerLibGlobalDir>${liferay.app.server.lib.global.dir}</appServerLibGlobalDir>
    <appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
    <liferayVersion>${liferay.version}</liferayVersion>
    <parentTheme>${liferay.theme.parent}</parentTheme>
    <pluginType>theme</pluginType>
    <themeType>${liferay.theme.type}</themeType>
  </configuration></plugin>

Please remember that the plugin will still be affected any bugs in the Liferay Portal Version so if you have patches installed you should point the plugin to a patched portal bundle by setting the liferay.app.server.xxx properties. If you discover any bugs in any of the plugin mojos please report them to our MAVEN Jira project.

Liferay 6.1 GA2 Maven release

Company Blogs 8 de Agosto de 2012 Por Mika Koivisto Staff

I'm glad to announce that we have release maven artifacts for Liferay 6.1 GA2 for both EE and CE. The CE version of portal artficats are in currently in Sonatype's repository waiting to be synced to Central and EE artifacts are available for download in customer portal like before. We've also released the Liferay Maven Support project that is the plugins sdk equivalent for Maven.  Both CE and EE compatible versions are being synced to Central. Please remember that this is not supported through your portal support contract. If you find any bugs in the Maven plugin or archetypes please file them to the MAVEN Jira project. The CE GA2 version number is 6.1.1 and EE GA2 version number is 6.1.20. Remember to use a version corresponding to your running portal version as mixing versions might cause problems.

We've also added some new features and improvements.

New features

  • DBBuilder - build-db goal allows you to execute the DBBuilder to generate SQL files
  • SassToCSSBuilder - build-css goal precompiles SASS in your css and this goal has been added to theme archetype
  • JSF Portlet Archetype
  • ICEFaces Portlet Archetype
  • PrimeFaces Portlet Archetype
  • Liferay Faces Alloy Portlet Archetype

Improvements

  • Allow setting service build number and turn off auto increment for ServiceBuilder. 
  • Allow build-service and direct-deploy from the parent project for Service builder and Ext projects.

 

Creating Liferay Themes with Maven

Company Blogs 15 de Março de 2012 Por Mika Koivisto Staff

Some time ago I posted on how you can get started creating portlets with Liferay Maven SDK now I’m going to show how you can add themes to your project. If you need a refresher on how to get started check out this post.

1) Open command prompt or terminal and go to your project directory. Next we are going to create a theme using the Liferay theme template. Run:

mvn archetype:generate \
    -DarchetypeArtifactId=liferay-theme-archetype \
    -DarchetypeGroupId=com.liferay.maven.archetypes \
    -DarchetypeVersion=6.1.0 \
    -DartifactId=sample-theme \
    -DgroupId=com.liferay.sample \
    -Dversion=1.0-SNAPSHOT
For 6.1 EE ga1 use -DarchetypeVersion=6.1.10. 

Now you have your theme project in sample-theme directory with following structure.

sample-theme
sample-theme/pom.xml
sample-theme/src
sample-theme/src/main
sample-theme/src/main/resources
sample-theme/src/main/webapp
sample-theme/src/main/webapp/WEB-INF
sample-theme/src/main/webapp/WEB-INF/liferay-plugin-package.properties
sample-theme/src/main/webapp/WEB-INF/web.xml

2) Open the theme pom.xml file. From the properties section remove liferay.version and liferay.auto.deploy.dir properties. These properties should be defined in the pom.xml in your project root just as we did with the portlet project.

You should also note that there’s two additional properties liferay.theme.parent and liferay.theme.type. These set the parent theme and the theme template language just like in ant based plugins sdk. The property liferay.theme.parent however allows you to define basically any war artifact as the parent. The syntax is groupId:artifactId:version or you can use the core themes: _unstyled, _styled, classic and control_panel.

3) Now you can add your customizations in src/main/webapp. Just follow the same structure as you would do in _diffs. So your custom.css would go to src/main/webapp/css/custom.css.

4) Once you’ve done your customizations and want to create the war file just run

mvn package

It will create the war file just like with any maven war type project. Another thing it will do is download and copy your parent theme and then overlay your changes on top of it. It will also create a thumbnail from src/main/webapp/images/screenshot.png just like ant based plugins sdk does. These are accomplished by adding the theme-merge and build-thumbnail goals into the generate-sources phase.

5) Now deploy the theme into your Liferay bundle by running:

mvn liferay:deploy

Getting started with Liferay SAML 2.0 Identity Provider

Company Blogs 27 de Fevereiro de 2012 Por Mika Koivisto Staff

 

Liferay 6.1 EE comes with SAML 2.0 Identity Provider and Service Provider support via SAML plugin. If you are not familiar with SAML check out my Introduction to SAML presentation slides.

In this post we will configure Liferay to be SAML Identity Provider and configure Salesforce to be a Service Provider. After we are done we have a user that can move from Liferay to Salesforce without requiring to authenticate on Salesforce. 

You’ll need following things to complete this by yourself:

* Liferay Portal 6.1 EE GA1 Tomcat bundle
* SAML Portlet WAR
* Salesforce developer account. You can sign-up here for free.

The first thing to do is download and install Liferay. If you need help configuring Liferay refer to Liferay 6.1 User Guide. Once that is done you’ll need to configure the SAML identity provider before deploying the plugin. The IdP needs a private and public key pair for signing SAML messages. It uses Java keystore to store the them. We’ll create the keystore and they key pair using keytool that is part of the JDK. You need to pick a unique entity id for your IdP and a password that is used to protect keystore and the private key. In this example we’ll use liferaysamlidpdemo as the entity id and liferay as the password for both keystore and the key. The keystore is created in LIFERAY_HOME/data/keystore.jks as this is the default location SAML plugin will look for it. You can also configure the location and type of they keystore and will do it here just for reference.

keytool -genkeypair -alias liferaysamlidpdemo -keyalg RSA -keysize 2048 -keypass liferay -storepass liferay -keystore data/keystore.jks

You’ll be asked to provide some information that will be in the certificate with the public key.

What is your first and last name?
  [Unknown]:  Liferay SAML IdP Demo
What is the name of your organization?
  [Unknown]:  Liferay SAML IdP Demo
What is the name of your City or Locality?
  [Unknown]: 
What is the name of your State or Province?
  [Unknown]: 
What is the two-letter country code for this unit?
  [Unknown]: 
Is CN=Liferay SAML IdP Demo, OU=Unknown, O=Liferay SAML IdP Demo, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  yes

Next step is to add SAML configuration to your portal-ext.properties.

saml.enabled=true
saml.role=idp
saml.entity.id=liferaysamlidpdemo
saml.require.ssl=false
saml.sign.metadata=true

saml.idp.authn.request.signature.required=true

saml.keystore.path=${liferay.home}/data/keystore.jks
saml.keystore.password=liferay
saml.keystore.type=jks

saml.keystore.credential.password[liferaysamlidpdemo]=liferay

Now you can deploy SAML plugin by copying it to LIFERAY_HOME/deploy and starting up tomcat. Wait for the saml-portlet to be deployed and available and then open http://localhost:8080/c/portal/saml/metadata. If you have configured everything correctly you should see the IdP metadata similar to below. I’ve just shortened the data on signature and certificate elements.

<?xml version=“1.0” encoding=“UTF-8”?>
<md:EntityDescriptor xmlns:md=“urn:oasis:names:tc:SAML:2.0:metadata” entityID=“liferaysamlidpdemo”>
<ds:Signature xmlns:ds=“http://www.w3.org/2000/09/xmldsig#”>
  <ds:SignedInfo>
   <ds:CanonicalizationMethod Algorithm=“http://www.w3.org/2001/10/xml-exc-c14n#”/>
   <ds:SignatureMethod Algorithm=“http://www.w3.org/2000/09/xmldsig#rsa-sha1”/>
   <ds:Reference URI=“”>
    <ds:Transforms>
     <ds:Transform Algorithm=“http://www.w3.org/2000/09/xmldsig#enveloped-signature”/>
     <ds:Transform Algorithm=“http://www.w3.org/2001/10/xml-exc-c14n#”/>
    </ds:Transforms>
    <ds:DigestMethod Algorithm=“http://www.w3.org/2000/09/xmldsig#sha1”/>
    <ds:DigestValue>mVKz/Tv6o40+SrEF595+Gedmoo8=</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>AAJsDF8dJv5XQw6Ty1MSg7 … OXvQw==</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>MIIDjjCCAnagAwIB… </ds:X509Certificate>
   </ds:X509Data>
  </ds:KeyInfo>
</ds:Signature>
<md:IDPSSODescriptor ID=“liferaysamlidpdemo”
  WantAuthnRequestsSigned=“true” protocolSupportEnumeration=“urn:oasis:names:tc:SAML:2.0:protocol”>
  <md:KeyDescriptor use=“signing”>
   <ds:KeyInfo xmlns:ds=“http://www.w3.org/2000/09/xmldsig#”>
    <ds:X509Data>
     <ds:X509Certificate>MIIDjj …</ds:X509Certificate>
    </ds:X509Data>
   </ds:KeyInfo>
  </md:KeyDescriptor>
  <md:SingleLogoutService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect”
   Location=“http://localhost:8080/c/portal/saml/slo_redirect”/>
  <md:SingleSignOnService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect”
   Location=“http://localhost:8080/c/portal/saml/sso”/>
  <md:SingleSignOnService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST”
   Location=“http://localhost:8080/c/portal/saml/sso”/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>

Even though the IdP is configured and functioning it’s not very useful because there’s no Service Providers configured. For this example we are going to use Salesforce developer account to demonstrate single sign-on between Liferay and Salesforce. If you haven’t already signed up for Salesforce developer account do it here.

We’ll need to export the certificate from keystore because Salesforce doesn’t know how to read SAML metadata.

keytool -export -alias liferaysamlidpdemo -file liferaysamlidpdemo.crt -keystore data/keystore.jks -storepass liferay -keypass liferay

Now login to your Salesforce developer account in here. On your dashboard click on Setup. 

 

Then click on Security Controls > Single Sign-On Settings under Administration Setup.

 

Then click on Edit.

Here’s the setting you need:

* SAML Enabled.
* SAML Version: 2.0
* Issuer: liferaysamlidpdemo (this is the entity id of the IdP)
* Identity Provider Certificate: liferaysamlidpdemo.crt which you exported earlier.
* Identity Provider Login URL: http://localhost:8080/c/portal/saml/sso
* SAML User ID Type: Select Assetion contains User’s salesforce.com username
* SAML User ID Location: Select User ID is in the NameIdentifier element of the Subject statement
* Identity Provider Logout URL: http://localhost:8080/c/portal/logout (Salesforce does not support SAML Single Logout Profile)

 

Verify that your setting as correct and then click on Download Metadata. Also note the Entity Id as this will be needed on the IdP side.

Move the downloaded metadata xml to LIFERAY_HOME/data/saml/salesforce-metadata.xml. Now we need to configure the IdP to know about this Service Provider. This is done by telling saml plugin where to find the SAML metadata for Salesforce.

saml.metadata.paths=${liferay.home}/data/saml/salesforce-metadata.xml

If your Salesforce Entity Id is not https://saml.salesforce.com you’ll also need to add following lines to your portal-ext.properties. Note I’m using https://saml.salesforce.com as the entity id but you would replace it with what ever Salesforce reported it to be.

saml.idp.metadata.attributes.enabled[https\://saml.salesforce.com]=true
saml.idp.metadata.attribute.names[https\://saml.salesforce.com]=
saml.idp.metadata.name.id.format[https\://saml.salesforce.com]=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
saml.idp.metadata.salesforce.attributes.enabled[https\://saml.salesforce.com]=true

If you had your tomcat still running just restart it so that the new property value is read. Then login as test@liferay.com / test. Now click on Manage > Site Pages. Click on Add Page. Add following values:

Name: Salesforce
Type: URL
URL:  /c/portal/saml/sso?entityId=https://saml.salesforce.com 

Notice the entityId is the same Entity Id that was shown as entity id on the Salesforce Single Sign-On configuration page.

Go to Control Panel and add a new user with same email address as your Salesforce developer account. Sign out and login with that new account. Now click on the Salesforce page link. If everything was configured correctly you are redirected to Salesforce and you are signed in with your developer account. If you want to be redirected to some other page than they home page you can add a URL parameter RelayState with the page URL you want to be redirected to as the value. For example the URL could look like this /c/portal/saml/sso?entityId=https://saml.salesforce.com&RelayState=/006/o. This would take me to my Opportunities page directly.

Now sign out from Salesforce and you will be taken back to Liferay and logged out from Liferay. Now if you click on the Salesforce page it will take present you with Liferay login page and after login will take you to Salesforce.

Update: If you need to setup Liferay as SP check out my collegues post Setting up Liferay as Service Provider.

Deploying Liferay artifacts to your own maven repository

Company Blogs 21 de Fevereiro de 2012 Por Mika Koivisto Staff

As part of Liferay 6.1 release we’ve created a new package that has a convenient  script to install Liferay artifacts to your local repository or to a remote repository. This package is provide for both CE and EE releases but it is more useful for EE users because we don’t release EE versions of the artifacts to Maven Central repository.

You can download the 6.1 GA1 package from here and 6.1 EE users can download it from Customer Portal. Once you have downloaded the zip file unzip it. 

In the root of the package you’ll find build.properties. This file defines the remote repository location, repository id and optional gpg signing key and password. You can override settings in this file similarly to those in plugins sdk by creating a build.USERNAME.properties file and overriding the properties you want. If you are just deploying to you local repository there’s no need to override any settings. 

Before you begin you should make sure you have mvn in your path. For remote deployment you should also increase the available memory for maven otherwise you might get a OutOfMemoryError. For windows you can use following in your cmd prompt or set MAVEN_OPTS environment variable.

set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m

For Unix-like systems such as Linux and Mac OS X use

export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m"

To deploy to your local maven repository you can just run:

ant install 

To deploy to a remote repository such as Sonatype Nexus you need to set credential required to deploy to the repository in ${USER_HOME}/.m2/settings.xml like this:

<?xml version="1.0"?>
<settings>
    <servers>
        <server>
            <id>liferay</id>
            <username>admin</username>
            <password>password</password>
        </server>
    </servers>
</settings>

Then you need to add the repository id and repository location to your build.USERNAME.properties like this:

lp.maven.repository.id=liferay lp.maven.repository.url=http://localhost/nexus/content/repositories/liferay-release

Notice that the repository id must match the one in your settings.xml so that correct credentials are picked up. You can also set gpg.keyname and gpg.passphrase if you want the artifacts signed. Check out this blog post on how to generate gpg key and distribute the public key.

Now you can deploy it just by running:

ant deploy

Now you have following Liferay artifacts at your disposal. Their groupId is com.liferay.portal and artifactId is one listed below and version is the Liferay release number such as 6.1.0 for 6.1 GA1 and 6.1.10 for 6.1 EE1.

  • portal-client
  • portal-impl
  • portal-service
  • portal-web
  • support-tomcat
  • util-bridges
  • util-java
  • util-taglib

Getting started with Liferay Maven SDK

Company Blogs 1 de Fevereiro de 2012 Por Mika Koivisto Staff

This will be the first in series of posts on how to develop Liferay plugins with Maven. In this post we'll start by creating a new parent project for your plugins and add a portlet project to it. You need to have your maven environment setup with maven and java installed. If you don't know how to do it I would recommend reading Maven: The Complete Reference from Sonatype, Inc. The chapter 2 has good instructions on how to install maven.
 
1) Download and install Liferay 6.1.0 bundle. In these posts we assume it's tomcat bundle but you can use any bundle. I'll refer to the bundle install location is LIFERAY_HOME from now on. If you need instructions on how to install bundle please refer to Liferay 6.1 User Guide.
 
2) Create a new directory which will be your project root. This is the location where you would extract Liferay plugins SDK if you were using Ant. Then in that directory create a pom.xml file.
 
Now you should adjust groupId and artifactId to match you project. Also set the value of liferay.auto.deploy.dir to LIFERAY_HOME/deploy. This is where the plugin is copied for Liferay to deploy. The liferay.version property is set to version of Liferay you are using. 
 
3) Open command prompt or terminal and go to your project directory. Next we'll going to create a portlet project using a liferay portlet project template. Run
 
mvn archetype:generate
 
That command will create a list of available project templates like below:
 
 
Choose number 24 or what ever the number you have for com.liferay.maven.archetypes:liferay-portlet-archetype
 
Next you will be asked to choose the template version: 
 
 
Choose number 6 or what ever you have for 6.1.0 version.
 
Next you will be asked to provide groupId, artifactId and version:
 
 
For groupId use the same as in the first pom.xml. In my case it would be com.liferay.sample. For artifactId I chose sample-portlet as this is the directory it will create. Version should be the same as the project parent. Once you have confirmed the values maven will create the portlet project and add it to you parent project as module automatically.
 
Now you project structure should be something like this:
 
 
4) Go to sample-portlet directory and run 
 
mvn package
 
This will compile any classes and packages the portlet war file in target directory. 
 
5) To deploy the portlet into your Liferay bundle you can run
 
mvn liferay:deploy
 
Now you have created your first Liferay plugin project with maven and deployed it to your Liferay bundle.

Liferay 6.1 GA1 Maven artifacts released

Company Blogs 9 de Janeiro de 2012 Por Mika Koivisto Staff

 

I’m glad to announce that we have released Liferay maven artifacts to 6.1 GA1. 

All the artifacts will be pushed into the central repository through http://oss.sonatype.org where they are already available. 

This release includes following artifacts:

- portal-client
- portal-impl
- portal-service
- portal-web
- support-tomcat
- util-bridges
- util-java
- util-taglib

In addition to this we’ve packaged the Liferay artifacts into a convenient zip file called /liferay-portal-maven-6.1.0-ce-ga1-20120106155615760.zip with ant script to allow you to deploy them into your local repository easily. We will be providing this for EE releases as well since EE artifacts will not be available from Central.  

We have also released the Liferay maven plugin and archetypes for all types of Liferay plugins:

- liferay-ext-archetype
- liferay-hook-archetype
- liferay-layouttpl-archetype
- liferay-portlet-archetype
- liferay-servicebuilder-archetype
- liferay-theme-archetype
- liferay-web-archetype

I will post later some instructions on how to use those archetypes. If you’ve used the snapshot version there was one last minute change that requires you to now manually set properties liferay.version and liferay.auto.deploy.dir in your pom.xml. 

Overriding and adding struts actions from hook plugins

Company Blogs 17 de Janeiro de 2011 Por Mika Koivisto Staff

This is a new cool feature I worked on with Brian and it’s coming on 6.1 as well as 6.0 EE SP2 and 5.2 EE SP6. With this feature you can add new struts actions to portal from a hook plugin and you can override any existing action with it.

There are two interfaces com.liferay.portal.kernel.struts.StrutsAction and com.liferay.portal.kernel.struts.StrutsPortletAction. The StrutsAction is used for regular struts actions like /c/portal/update_password and StrutsPortletAction is used for those that are used from portlets.

Let’s create a new simple hook to test it out. This hook will create a new struts path /c/portal/sample and wraps an existing struts action. Start by creating a new hook plugin in your plugins SDK. I’ll call it sample-struts-action.

./create.sh sample-struts-action

Next edit the liferay-hook.xml and add following fragment:

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">

<hook>
	<portal-properties>portal.properties</portal-properties>
	<custom-jsp-dir>/META-INF/custom_jsps</custom-jsp-dir>
	<struts-action>
		<struts-action-path>/portal/sample</struts-action-path>
		<struts-action-impl>com.liferay.samplestrutsaction.hook.action.SampleStrutsAction</struts-action-impl>
	</struts-action>
	<struts-action>
		<struts-action-path>/message_boards/view</struts-action-path>
		<struts-action-impl>com.liferay.samplestrutsaction.hook.action.SampleStrutsPortletAction</struts-action-impl>
	</struts-action>
</hook>

Next we need to create the struts action like below:

package com.liferay.samplestrutsaction.hook.action;

import com.liferay.portal.kernel.struts.BaseStrutsAction;
import com.liferay.portal.kernel.util.ParamUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Mika Koivisto
 */
public class SampleStrutsAction extends BaseStrutsAction {

	public String execute(
		HttpServletRequest request, HttpServletResponse response)
		throws Exception {

		String name = ParamUtil.get(request, "name", "World");

		request.setAttribute("name", name);

		return "/portal/sample.jsp";
	}

}

Next create the second Struts action. This one will actually wrap ViewAction of message boards portlet.

package com.liferay.samplestrutsaction.hook.action;

import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.struts.StrutsPortletAction;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

/**
 * @author Mika Koivisto
 */
public class SampleStrutsPortletAction extends BaseStrutsPortletAction {

	public void processAction(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ActionRequest actionRequest,
			ActionResponse actionResponse)
		throws Exception {

		originalStrutsPortletAction.processAction(
			originalStrutsPortletAction, portletConfig, actionRequest,
			actionResponse);
	}

	public String render(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, RenderRequest renderRequest,
			RenderResponse renderResponse)
		throws Exception {

		System.out.println("Wrapped /message_boards/view action");

		return originalStrutsPortletAction.render(
			null, portletConfig, renderRequest, renderResponse);
	}

	public void serveResource(
			StrutsPortletAction originalStrutsPortletAction,
			PortletConfig portletConfig, ResourceRequest resourceRequest,
			ResourceResponse resourceResponse)
		throws Exception {

		originalStrutsPortletAction.serveResource(
			originalStrutsPortletAction, portletConfig, resourceRequest,
			resourceResponse);
	}

}

Then we need to create the JSP in docroot/META-INF/custom_jsps/html/portal/sample.jsp

Hello !

And lastly we need to create portal.properties in docroot/WEB-INF/src

auth.public.paths=/portal/sample

Now we are ready to deploy the plugin and see if it works. Just run ant deploy in your plugins sdk to deploy it.

You should see following in your tomcat console:

22:01:29,635 INFO  [AutoDeployDir:167] Processing sample-struts-action-hook-6.1.0.1.war
22:01:29,638 INFO  [HookAutoDeployListener:43] Copying web plugin for /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war
  Expanding: /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war into /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF/classes
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF/classes
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/WEB-INF
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299/META-INF
  Copying 12 files to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/webapps/sample-struts-action-hook
  Copying 1 file to /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/webapps/sample-struts-action-hook
  Deleting directory /Users/mika/Development/Liferay/git/bundles/tomcat-6.0.29/temp/20110117220130299
22:01:30,486 INFO  [HookAutoDeployListener:49] Hook for /Users/mika/Development/Liferay/git/bundles/deploy/sample-struts-action-hook-6.1.0.1.war copied successfully. Deployment will start in a few seconds.
Jan 17, 2011 10:01:39 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory sample-struts-action-hook
22:01:39,727 INFO  [PluginPackageUtil:1080] Reading plugin package for sample-struts-action-hook
22:01:39,759 INFO  [HookHotDeployListener:432] Registering hook for sample-struts-action-hook
22:01:39,770 INFO  [HookHotDeployListener:717] Hook for sample-struts-action-hook is available for use

Now try to access http://localhost:8080/c/portal/sample. It will ask you to sign in and once you sign in you should see the message Hello World! in your browser. You can add a paramer name to the url to change the message. If you access message boards it will print the message "Wrapped /message_boards/view action" in tomcat console and continue to render message boards as if nothing was changed.

Now our sample was really simple one. The return value from the execute method is the view where the request is dispatched next. This can be path to JSP, an existing struts forward or tiles definition. Returning null means that your action has handled the view already. Now you could try to return for instance portal.terms_of_use to display the terms of use.

You can download this sample plugin from svn://svn.liferay.com/repos/public/plugins/trunk/hooks/sample-struts-action-hook. The username is guest and password is empty.

UPDATE: We changed the API so that the original action is passed in so that you can also wrap it with your own logic instead of replacing. I also added a new hook property auth.public.paths so it allows you to set new public paths from hooks. I also added a StrutsPortletAction into to the sample and that demonstrates wrapping an existing action.

How do I cluster Liferay with Terracotta?

Company Blogs 31 de Agosto de 2010 Por Mika Koivisto Staff

That's a question I've head many times and in this post I will show you  just how to do that. These instructions are for Liferay 6 CE GA3 Tomcat 6.0 bundle however you can use any app server supported by Terracotta but the location and some configuration might be slightly different. So to get started you need to download:

Next step is to install Liferay and Terracotta. For the purposes of this post I won't go into great detail with the installation as both Terracotta and Liferay has good documentation. Basically the installation consist of unpacking the packages to a directory. From now on I will refer to those locations as LIFERAY_HOME and TERRACOTTA_HOME and inside LIFERAY_HOME we will have tomcat directory which I will refer as TOMCAT_HOME. Normally you would also install Liferay and Terracotta in separate servers but I will post a separate post addressing the recommended architecture. For now we can install everything on the same machine and run Terracotta with default configuration for development purposes.

Normally when clustering Liferay you need to address following components: EhCache and Hibernate, Quartz Scheduler, Document Library, Search Engine and optionally Session Replication. For Document Library and Search Engine Terracotta doesn't offer anything new so you make those centrally available the same way as before. For example SAN for DL and SOLR for Search and Indexing. So we are left with EhCache and Hibernate, Quartz and Session Replication that we can address with Terracotta. 

EhCache and Hibernate Second Level Cache

  1.  Remove ehcache.jar that is bundled with Liferay (located in TOMCAT_HOME/webapps/ROOT/WEB-INF/lib)
  2. Copy all jars in TERRACOTTA_HOME/ehcache/lib to TOMCAT_HOME/webapps/ROOT/WEB-INF/lib
  3. Copy TERRACOTTA_HOME/common/terracotta-toolkit-1.0-runtime-<version>.jar to TOMCAT_HOME/webapps/ROOT/WEB-INF/lib
  4. Create my-ehcache folder to TOMCAT_HOME/webapps/ROOT/WEB-INF/classes
  5. Create a hibernate-terracotta.xml and a liferay-multi-vm-terracotta.xml.
  6. Adjust terracottaConfig in hibernate-terracotta.xml and liferay-multi-vm-terracotta.xml to point to your Terracotta servers. Like this: <terracottaConfig url="localhost:9510"/>
  7. Add following properties to your portal-ext.properties file:
    ehcache.multi.vm.config.location=/my-ehcache/liferay-multi-vm-terracotta.xml
    
net.sf.ehcache.configurationResourceName=/my-ehcache/hibernate-terracotta.xml
    
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory

Quartz

  1. Remove quartz.jar that is bundled with Liferay (located in TOMCAT_HOME/webapps/ROOT/WEB-INF/lib)
  2. Copy TERRACOTTA_HOME/quartz/quartz-terracotta-<version>.jar and quartz-all-<version>.jar to TOMCAT_HOME/webapps/ROOT/WEB-INF/lib
  3. Add following properties to your portal-ext.properties:
    org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
    
org.quartz.jobStore.tcConfigUrl = localhost:9510
  4. Extract portal.properties from portal-impl.jar and place it in TOMCAT_HOME/webapps/ROOT/WEB-INF/classes
  5. Comment out following properties in portal.properties
    #org.quartz.jobStore.dataSource=ds

    #org.quartz.jobStore.isClustered=false
    
#org.quartz.jobStore.misfireThreshold=60000
    
#org.quartz.jobStore.tablePrefix=QUARTZ_
    
#org.quartz.jobStore.useProperties=false

Session Replication

This is highly container specific so refer to Terracotta documentation for specific instructions. Following steps are for Tomcat 6.0.

  1. Copy TERRACOTTA_HOME/sessions/terracotta-session-<version>.jar to TOMCAT_HOME/lib
  2. Copy TERRACOTTA_HOME/common/terracotta-toolkit-1.0-runtime-<version>.jar to TOMCAT_HOME/lib
  3. Edit TOMCAT_HOME/conf/Catalina/localhost/ROOT.xml and add following line right after <Context>
    
<Valve className="org.terracotta.session.TerracottaTomcat60xSessionValve" tcConfigUrl="localhost:9510"/>

Testing The Configuration

Testing your configuration is simple:

  1. Startup your Terracotta Server
    TERRACOTTA_HOME/bin/start-tc-server.sh
  2. Startup your Tomcat
    TOMCAT_HOME/bin/startup.sh
  3. Before Tomcat has fully started you should see following lines in your Tomcat console log:
    2010-09-01 21:35:40,059 INFO - Terracotta 3.3.0, as of 20100716-140706 (Revision 15922 by cruise@rh5mo0 from 3.3)
    2010-09-01 21:35:40,566 INFO - Successfully loaded base configuration from server at 'localhost:9510'.
  4. Now browse http://localhost:8080 to verify that your portal is running. 
  5. Now launch Terracotta Developer Console to verify that EhCache, Hibernate, Quartz and Sessions are seen by Terracotta. You can launch dev console with following command:
    TERRACOTTA_HOME/bin/dev-console.sh
  6. Once you are connected to your Terracotta you should see Ehcache, Hibernate, Quartz and Sessions under My application which indicates that all of them are connected and recognized by Terracotta. Now you can use Dev Console to see what's inside your cache or session. 

Closing Remarks

Now as you can see it is quite easy the cluster Liferay with Terracotta express installation. Now if you want to use the DSO approach it is whole another beast as it involves tedious instrumentation. If you are a Liferay EE customer and want to get supported version of both Liferay and Terracotta contact your Liferay sales rep and ask about Liferay Terracotta Edition. 

Using Freemarker in your theme templates

Company Blogs 24 de Agosto de 2010 Por Mika Koivisto Staff

Freemarker is a template language very similar to Velocity. Starting from Liferay 6.0 Liferay supports also Freemarker templates in themes and Web Content templates. In this post I will show how you can use Freemarker in your themes.

Getting started

To get started you'll need Liferay Portal 6.0 GA3 as well as corresponding Plugins SDK. Once you have setup your Portal and Plugins SDK we can start by creating a new theme plugin in PLUGINS_SDK_ROOT/themes folder.

To create the theme issue following command:

./create.[sh|bat] my-freemarker "My Freemarker"

Then go to my-freemarker-theme directory and open build.xml in your favorite editor.

In build.xml add theme.type property with value ftl above theme.parent property like this:

<property name="theme.type" value="ftl"></property>
<property name="theme.parent" value="_styled"></property>

Then you need to create docroot/WEB-INF/liferay-look-and-feel.xml with following contents:

<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 6.0.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_6_0_0.dtd">

<look-and-feel>
	<compatibility>
		<version>6.0.0+</version>
	</compatibility>
	<theme id="my-freemarker-theme" name="My Freemarker">
		<template-extension>ftl</template-extension>
	</theme>
</look-and-feel>

Now you run:

ant deploy

Congratulations you’ve just made your first Freemarker based theme. Now you can override base theme files in docroot/_diffs folder just as you would normally except template files now have extension .ftl instead of .vm.

Freemarker syntax

Freemarker syntax is slightly different from Velocity and it is much more strict. With Freemarker you won't be able to get a way with trying to use undefined variables and you should also note that null value means it's undefined. To test if value exists you can use double question mark after the variable name like this:

<#if someVariableName??>
Variable exists
</#if>

For full syntax reference check out Freemarker website.

Pre-defined theme variables

Most of the variables present for Velocity templates are also available for Freemarker templates. Only Velocity specific tools were removed you can accomplish everything and more with Freemarker build-ins. Here's some examples how to format a java.util.Date type variable with Freemarker build-ins:

${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdated?string("EEE, MMM d, ''yy")}
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}

You can find all the variables available for Freemarker templates from com.liferay.portal.freemarker.FreeMarkerVariables class and docroot/html/themes/_unstyled/init.ftl

Macro libraries

Most of the macros available to Velocity templates are also available for Freemarker templates. The only difference is the syntax how they are used. We provide a macro library with namespace liferay so that it won't get mixed with your own macros. You can take a look at portal-impl/src/FTL_liferay.ftl to see full list of macros and use it as an example to build your own macros. Here are some commonly used macros:

<@liferay.css file_name=“some.css” />

<@liferay.js file_name=“some.js” />

<@liferay.language key=“my-key” />

<@liferay.breadcrumb />

<@liferay.docbar /> 

Tag libraries

Yes, you read it correctly. You can use taglibs in your Freemarker templates. This is something unique to Freemarker and it is limited to only templates in themes. To import a portal taglib to your template just add following line to your template:

<#assign aui=PortalJspTagLibs["/WEB-INF/tld/liferay-aui.tld"]>

Now you can use any tag within that taglib just if it was a macro library. Here's an example how to add a Alloy UI input field:

<@aui.input name=“aStringLiteral” label=“Test” />

Have fun trying this out and if you find any glitches do report them to our issue tracker.

Liferay Maven SDK

Company Blogs 15 de Dezembro de 2009 Por Mika Koivisto Staff

Starting to recover from jetlag after a two week trip Los Angeles and Liferay retreat. One of the things we finally made some progress during the developer retreat  is providing official maven artifacts for Liferay as well as porting our plugins sdk to Maven. Things are not quite completed but I will provide some instructions here for all early adopters.

So our goal is to provide our CE releases through our own public repository as well as provide means for our EE customers to install the EE versions artifacts to their local maven repository.

If you have ever worked with enterprise projects using maven you already know how important a local maven repository and proxy is. For those not so familiar with Maven a proxy is a server that proxies your requests to public Maven repositories and caches the artifacts locally for faster and more reliable access. Most maven proxies can also host private repositories used for hosting your company's private artifacts. Having a local proxy / repository makes your maven builds much faster and more reliable than accessing remote repositories that might even sometimes be unavailable.

1. Installing a maven proxy / repository

First step is to install and setup Nexus. Nexus is a open source maven repository manager that can proxy to other repositories as well as host repositories. If you just want to try things locally you can skip this step.

  1. Download latest Nexus such as nexus-webapp-1.4.0-bundle.zip
  2. Follow the installation directions of the Nexus book http://nexus.sonatype.org/documentation.html
  3. Startup nexus
  4. Open your browser to your newly created nexus (if you installed it locally it could be accessed by opening http://localhost:8080/nexus)
  5. Login as administrator (default login is admin / admin123)
  6. Go to Repositories and click Add -> Hosted Repository
  7. Give the repository following information and click save
    • Repository ID: liferay-ce-releases
    • Repostory Name: Liferay CE Release Repository
    • Provider: Maven2 Repository
    • Repository Policy: Release
  8. Create another hosted repository with following information
    • Repository ID: liferay-ce-snapshots
    • Repository Name: Liferay CE Snapshot Repository
    • Provider: Maven2 Repository
    • Repository Policy: Snapshot

Now you have a repository ready for Liferay's Maven artifacts. Next step is to configure your maven to be able to upload artifacts to that repository.

 2. Configuring Maven Settings

Open your $HOME/.m2/settings.xml (if the file does not exist create it). Add the servers segment to your settings.xml

<?xml version="1.0" encoding="UTF-8"?>
<settings>
     <servers>
          <server>
               <id>liferay</id>
               <username>admin</username>
               <password>admin123</password>
          </server>
     </servers>
</settings>

You might also want to make your Nexus as your maven proxy. To do that just add following xml segment to your settings.xml right before servers element.

<mirrors>
     <mirror>
          <id>local</id>
          <name>Local mirror repository</name>
          <url>http://localhost:8080/nexus/content/groups/public</url>
          <mirrorOf>*</mirrorOf>
     </mirror>
</mirrors>

3. Installing Liferay Artifacts to Repository

Next we will install the Liferay Maven artifacts to your repository. First you need to checkout Liferay code from the SVN. 

svn --username guest co svn://svn.liferay.com/repos/public/portal/trunk portal-trunk

Guest user does not require password.

Then create a release.${username}.properties file and add

maven.url=http://localhost:8080/nexus/content/repositories/liferay-ce-snapshots

Build Liferay artifacts by running

ant clean start jar

Now you can deploy the Liferay artifacts to your maven repository by running

ant -f build-maven.xml deploy-artifacts

If you only want to have them locally without a maven repository you can run the install task instead of deploy

ant -f build-maven.xml install-artifacts

Now you can add Liferay dependencies to your maven project. Following artifacts are available:

<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>portal-client</artifactId>
	<version>5.3.0-SNAPSHOT</version>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>portal-impl</artifactId>
	<version>5.3.0-SNAPSHOT</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>portal-kernel</artifactId>
	<version>5.3.0-SNAPSHOT</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>portal-service</artifactId>
	<version>5.3.0-SNAPSHOT</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>portal-web</artifactId>
	<version>5.3.0-SNAPSHOT</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>util-bridges</artifactId>
	<version>5.3.0-SNAPSHOT</version>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>util-java</artifactId>
	<version>5.3.0-SNAPSHOT</version>
</dependency>
<dependency>
	<groupId>com.liferay.portal</groupId>
	<artifactId>util-taglib</artifactId>
	<version>5.3.0-SNAPSHOT</version>
</dependency>
NOTE portal-impl and portal-web are provided for maven plugins and should never be added as dependency to your Liferay plugins.

 4. Installing the Liferay Maven SDK

To take full advantage of Maven we are porting the functionality of out ant based Plugins SDK to Maven. To use it you need to install it locally. To install the Liferay maven plugins and archetypes go into support-maven folder and run

mvn install

Now the Liferay Maven SDK is installed and ready to use. We've implemented a portlet archetype and deployer plugin.

5. Creating a Portlet Plugin

Move to the folder where you want to create your portlet and run

mvn archetype:generate

From the list select liferay-portlet-archetype and provide your project groupId, artifactId and version for the portlet project.

You're portlet project's pom.xml has two properties liferay.auto.deploy.dir and liferay.version. These properties are usually moved to your parent pom.xml or settings.xml so that you don't have to adjust them for every single plugin you create. Set the liferay.auto.deploy.dir to point to the Liferay autodeploy directory of your Liferay bundle. This is where the deploy plugin will copy your portlet. Now you are ready deploy your newly created portlet. You can deploy it by running

mvn liferay:deploy

6. Future Plans

We are also in the process of adding archetypes for themes, hooks and layouts as well as providing portlet archetypes for different types of portlets like JSP, Spring MVC, JSF etc. I will blog about it once they are done.

A special thanks goes to Thiago Moreira and Brian Chan for making this possible. Also for the community and customers for putting pressure to have this done.

If you are using 5.2.3 CE and want to take advantage of Maven for building Liferay portlets Milen Dyankov a Liferay community member has done also great work on a Maven SDK for 5.2.3 CE. You can find more about it from GitHub

SiteMinder integration is here

Company Blogs 3 de Outubro de 2008 Por Mika Koivisto Staff

You've been heard! Out of box SiteMinder integration is here.

Computer Associate’s (CA) SiteMinder is a centralized web access management system that enables user authentication and single sign-on, policy-based authorization, identity federation, and auditing of access to Web applications and portals.

Liferay has out of box SiteMinder integration as of recent Liferay 5.1.2 release. The integration is based on CAS integration and only supports authenticating with screenName. It also knows how to properly terminate SiteMinder session. SiteMinder is usually connected to a LDAP so this integration is also able to import users from LDAP.

You can enable it either throught portal-ext.properties or UI just like with CAS or OpenSSO.

Enabling from portal-ext.properties:

##
## SiteMinder
##

    #
    # Set this to true to enable CA SiteMinder single sign on. If set to true,
    # then the property "auto.login.hooks" must contain a reference to the class
    # com.liferay.portal.security.auth.SiteMinderAutoLogin and the
    # "logout.events.post" must have a reference to
    # com.liferay.portal.events.SiteMinderLogoutAction for logout to work.
    #
    siteminder.auth.enabled=true

    #
    # A user may be authenticated from SiteMinder and not yet exist in the
    # portal. Set this to true to automatically import users from LDAP if they
    # do not exist in the portal.
    #
    siteminder.import.from.ldap=true

    #
    # Set this to the name of the user header that SiteMinder passes to the
    # portal.
    #
    siteminder.user.header=SM_USER

Enabling from Liferay UI:

SiteMinder settings

Mostrando 12 resultados.
Items 20
de 1