Recent Posts
-
July 04, 2010
Liferay Portal 6 Enterprise Intranets review
A few weeks ago I was asked by Packt publishing to review the new Liferay Portal 6 Enterprise Intranets book. Going through over 650 pages took me some time but finally I'm ready to share my thought about it.
By now you are probably scanning the text for something like "In general this is ____ book". Don't bother, I'm not going to generalize in this post. In fact, what you put in place of ____ depends on who you are, what is your Liferay background, and what you expect to learn.
-
May 03, 2010
Writing Liferay portlet to display a file in a way "tail -f" does
Don't know about you but I can't imagine debugging enterprise class applications without having "tail -f /path/to/log.file" running in dedicated console window. During development and testing phases (assuming work is done "in house") there is usually no problem with this approach as the whole team have access to servers' log files. This is not always the case with staging and production environments though. These days a lot of companies execute strong security policies which sometimes means that application is only accessible via HTTP. In such case, depending on how you SLA looks like, "log files provided on demand via e-mail or FTP" may not be an option.
Facing this kind of problem in recent Liferay based project, made me think about creating a portlet capable of displaying log files. Something like WWW based version of "tail -f". This is how Tailgate was born (for those of you looking for solution here is download page). The rest of this post will concentrate on explaining why it was not "a max 2h of coding" as I thought in the begging.
-
April 05, 2010
Custom global markup portlet
What would you do if a customer demands to "integrate" his Liferay based corporate portal with Google Analytics, Geminus, ClickTale, Crazy Egg, and whole bunch of other analytics tools available out there?
As you probably know, such services typically provide some piece of javascript (code or file) which needs to be added to every page of monitored web site. Each service also provides unique customer code/key (which is either already part of the javascript provided or needs to be placed in specific place). Regardless of whether using all of them at the same time is a smart thing to do, there are a few technical problems to solve:
- How to add custom code to every portal page
- How to deal with unique codes/keys through development, testing, staging, production phases
- How to minimize the impact of changing/removing custom code in production environment
-
October 09, 2009
Creating Liferay portlet with liferay-maven-sdk
This post will demonstrate how liferay-maven-sdk can be employed to build a Liferay portlet using Liferay’s Service Builder feature. For this purpose we will create service-builder-portlet which is capable of displaying a list of players and adding a new player to this list. The model, persistence layer and data access services will be generated by
Service Builder
.But first things first. Download and install
liferay-maven-sdk
if you haven’t done so already (have a look at Download and Install page for instructions). Onceliferay-maven-sdk
is installed in your local repository, you can create the portlet.So enter the folder (or create one) where you keep your portlets and execute
mvn archetype:generate
you should see a list of available archetypes starting withChoose archetype: 1: local -> liferay-portlet-archetype (Liferay portlet archetype) 2: local -> liferay-theme-archetype (Liferay theme archetype) 3: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate, Spring and JSF) 4: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with Hibernate, Spring and Spring MVC) ... Choose a number: (1/2/3/4/...) :1
Type
1
and press enter to chooseliferay-portlet-archetype
. Then providegroupId
,artifactID
,package
andversion
. For example:Define value for groupId: : com.commsen.liferay.examples.portlet.servicebuilder Define value for artifactId: : service-builder-portlet Define value for version: 1.0-SNAPSHOT: : 1.0 Define value for package: com.commsen.liferay.examples.portlet.servicebuilder: :
Additionally you may execute
mvn eclipse:eclipse
to setup Eclipse IDE if, that is what you are using! At this time your portlet skeleton is ready and you may compile it and even create WAR, but it of course does nothing special.Let’s now add data model and services. Create file
service-builder-portlet/src/main/webapp/WEB-INF/service.xml
:<?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_5_2_0.dtd"> <service-builder package-path="com.commsen.liferay.examples.portlet.servicebuilder"> <namespace>SB</namespace> <entity name="Player" local-service="true" remote-service="true"> <!-- PK fields --> <column name="playerId" type="long" primary="true" /> <!-- Other fields --> <column name="name" type="String" /> <column name="active" type="boolean" /> <column name="score" type="int" /> <column name="birthday" type="Date" /> <column name="description" type="String" /> <!-- Order --> <order by="asc"> <order-column name="name" /> </order> <!-- Finder methods --> <finder name="ActivePlayers" return-type="Collection"> <finder-column name="active" /> </finder> </entity> </service-builder>
The portlet projects created by
liferay-portlet-archetype
contain maven profile withlifray-maven-plugin
’sbuild-service
goal attached togenerate-sources
phase. To runServiceBuilder
you need to activate the profile:mvn -P build-service package
If you read carefully the messages you will realize that service and persistence classes were generated in
service-builder-portlet/src/main/java-service-api/
folder. Also there should be a few implementation files inservice-builder-portlet/src/main/java/
.Now we’ll add custom methods. Open the following file
service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/service/impl/PlayerLocalServiceImpl.java
and paste this code:public void addPlayer(String name, boolean active, int score, Date birthday, String desc) throws PortalException, SystemException { long playerId = CounterLocalServiceUtil.increment(); Player player = PlayerUtil.create(playerId); player.setName(name); player.setActive(active); player.setScore(score); player.setBirthday(birthday); player.setDescription(desc); PlayerUtil.update(player, false); } public List<Player> getAllPlayers() throws PortalException, SystemException { return PlayerUtil.findAll(); }
We added methods to the implementation class. The next time we compile the code we need to activate the
build-service
profile again in order forService Builder
to react on the change and regenerate the API and interfaces. If you want to try it now simply executemvn -P build-service compile
Now we can start using these services in our portlet. Open
service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/JSPPortlet.java
and add this method@ProcessAction(name = Constants.ADD) public void addPlayer(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException { String name = ParamUtil.getString(actionRequest, "name"); boolean active = ParamUtil.getBoolean(actionRequest, "active"); int score = ParamUtil.getInteger(actionRequest, "score"); String description = ParamUtil.getString(actionRequest, "description"); int year = ParamUtil.getInteger(actionRequest, "birthday_year"); int month = ParamUtil.getInteger(actionRequest, "birthday_month"); int day = ParamUtil.getInteger(actionRequest, "birthday_day"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.DAY_OF_MONTH, day); try { PlayerLocalServiceUtil.addPlayer(name, active, score, calendar.getTime(), description); } catch (Exception e) { throw new PortletException("Failed to add player", e); } }
This method handles adding players to database by calling the method we created earlier. To complete the portlet we only need the JSP page which displays the list and render HTML form to add users. The page source code is available here.
That’s all! We can now create WAR file (
mvn package
) deploy it and add some players to our database! For more details have a look at portlet’s source code available in examples/service-builder-portlet folder ofliferay-maven-sdk
. -
April 26, 2009
Run GWT application in "hosted mode" from maven
It seems to get more and more cloudy in the IT world these days . It's a matter of time before the rain (of applications) starts. When this happen one will need the proper tools, to be able to add his/hers own few drops.
So I though it's about time to start experimenting with Google Web Toolkit. What I like the most about GWT is it's "hosted mode". The fact that Java code changes reflect the GUI right away and one don't have to wait for generate, compile, build, deploy, ... steps to complete is really speeding up the development process.
Since 99% of my projects use Maven the first thing to look for (after reading GWT tutorials) was a GWT maven plug-in. No surprise here - there is one (http://mojo.codehaus.org/gwt-maven-plugin). The GWT docs and gwt-maven-plugin docs gives a lot of information how to create and build GWT applications. Unfortunately the released version of gwt-maven-plugin (1.0 at the time of writing) does not support hosted mode.