You probably know the basic installation instructions for Liferay Bundles: „unzip and run startup.sh“ - with this you get to a working Liferay installation in a minute. It will run with all defaults - which might not be what you want in production.

This is part 5 of a series. All the chapters are linked at the bottom of this article - I recommend to start with chapter 1. This chapter is an extension to chapter 3 - an aspect that you'll not run into when you just follow my recommendation. But if you ignore those recommendations, there's something you might want to know. Just as before, please note that I'm using Apache httpd as the webserver of my choice. If you are more familiar with any of the others: Feel free to search/replace the name. It's the principle that I'd like to discuss, not the name or origin of the webserver.

Tomcat (or: my appserver) speaks https too...

because I'm used to it and I have it anyway just to get access to mod_rewrite

because it supports a lot of different configurations and has a lot of documentation (and implementations) readily available (Let'sEncrypt anyone?)

because... security...

What's more secure when Apache httpd handles encryption?

Httpd, being a separate process, typically runs as a different user than tomcat. Further more, it's started as root and drops those privileges once configured. And here's the main reason: You can store your private server key (the crown jewels of a web server) to be readable only to root. And when you're running on a separate server, you even have that level of protection between your Appserver and application (Liferay).

If your appserver handled encryption, it would need access to your private key as well. Granted, the private key in a Java keystore is typically password protected. The only problem is that the password also needs to be read by the user that tomcat is running as. So basically you can't really store the private key (that never must escape your control) in a way that the appserver can't read it.

Any security hole in either appserver or application might expose your filesystem to the outside - and it'd be a very bad idea to leak your private key. You might not even know when it escapes - I find it's a lot harder to properly protect the private key when you only have the appserver doing everything from serving application data to handling connection encryption.

And did I mention that just mod_rewrite alone has saved me hours for quickly fixing issues in production? If you've not yet considered an extra Apache httpd: let this chapter be the trigger for changing your setup. And if you did: Congratulations. Great choice.

Two episodes (or an eternity) ago, I spoke to Jorge Ferrer, Liferay's VP of Engineering. We didn't have enough time to finish the conversation, so we continued a while after - and then I buried the recording /o\. Anyway, apart from it being still from "before the release of the current version", it's still relevant stuff, I feel bad about missing to post it. Check for yourself - here it finally is.

As before, we're speaking about various internal and external topics and I've also been teasing him a bit.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. Make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on radioliferay.com.

Or just download the MP3 here

Trackback URL:

Related Assets:

Liferay comes with so many features that it's hard to judge when a feature is a good solution for a given problem. I'd like to shine some light onto some of these features and common misconceptions about them because it's easy to abuse them for purposes for which they're not well suited - despite making the impression they might. CC BY-ND 2.0 by S. Benno

Today it's all about Session Replication, commonly seen as an intended setup in clusters.

What does Session Replication solve? Often, clusters are configured for "sticky sessions". When a user visits a site for the first time, the loadbalancer assigns a random server to serve this user's requests. On subsequent requests in the same session, the user continues to use this single server - as it has all the necessary server-side state already initialized and ready to go.

Server side state?

Yes, I'm aware that stateless systems would be more ideal and eliminate the whole question of session replication, but that's not what we're dealing with in the world of tightly permission controlled intranets, utilizing more and more high-level libraries that abstract away all the implementation details.

When the server that serves your requests goes down, the loadbalancer would transparently balance you over to another server in the cluster. However, that server has never seen you. It can't do anything with your session id - and so you find yourself logged out and annoyed.

Session Replication to the rescue: Just configure your application server to persist all of the session information and distribute it among the cluster nodes - and you're set. Ain't technology great? It just works.

However,

if you're running a cluster because you need to balance high load (as opposed to having a second server for high availability of your otherwise bored server), session replication adds significant overhead to every single request served. If you're not ready to pay that price, you might want to look for different solutions.

Here's some checklist to go through - see if you really need session replication:

How often do you anticipate a server to go down unplanned?

How many people do you anticipate to be in the middle of a complex transaction (that they'd have to restart) while that happens?

How many multi-step transactions do you have that could be impacted by such an outage?

Have you measured the impact of switching on/off session replication under load?

And here's an alternative solutions checklist: Systems and configurations that might do the trick for you and save you from configuring session replication:

Implement a Single Sign On (SSO) system - this way a user can be automatically logged in again when being balanced to a new server. For single-step transactions that might be all you need.

Implement your multi-step transactions so that they are stateless - combine this with SSO and you might not even realize that you've been rebalanced.

Implement your multi-step transactions on the business layer instead of the UI layer. That way you're independent of session storage - combine with SSO to be able to transparently find the user's data. Anything below the UI layer naturally won't utilize session data.

You see that SSO is the elephant in the room: By transparently keeping a user logged in, you've helped them with the main burden and problem point. My personal expectation is that Session Replication is the wrong or unnecessary configuration for 90% of implementations. It's solving the wrong problem, or implicitly charges an intransparent and high price. That's not to say that you must not use it - just be aware that you most likely are not in the 10%.

And a disclaimer: The 90/10% numbers are a personal expectation - there's no science (that I'd be linking here) and they might as well be inaccurate - in both directions.

You can find good reasons for implementing Session Replication. It just should not be the default choice, IMHO. I rather try harder to avoid it. And if it's unavoidable: Measure! Know the impact and the cost.

Today I'm welcoming a repeat guest and a new one: Jim Hinkey (of episode 21 fame) and Cody Hoag - both from Liferay's documentation and knowledge management team. This episode has unfortunately suffered from various disturbances in the space-time-continuum: I had it sitting on my disk for quite a while. The Javadoc Contest that we've "started" in this episode was actually published/announced in the meantime and unfortunately ended recently. Congratulations to Sébastien and Marcellus. However, not to render the call for action in this episode useless, let's start another one soon - there can't be enough Javadoc, and I admit that we have still plenty of opportunities to write new documentation left for you. Please subscribe to the comments on Cody's winner's announcements to see the update - I'll also mention it on a Radio Liferay episode once it's been restarted. But I'll also put a word in for you if you already write the javadoc now.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. Make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on radioliferay.com

As the exploration begins, I'm sure everybody first looks for their pet peeves. There's something that's been nagging me in 6.1 and 6.2 - and unfortunately I couldn't get my fixed theme regression merged into master - partly because of my missing CSS design skills, partly because I started lobbying too late, when only critical fixes were accepted. And partly because there was an impending update to the DOM which would have rendered the fix invalid almost immediately after committing it.

Turns out that my 6.2 patch is not invalidated by whatever has been introduced in Liferay 7, and it's trivial for you to fix the issue - and easy to bring into your own themes (everybody has their own theme anyways - right?). Here's the problem again:

When you drag and drop portlets on the page, Liferay does not provide an indicator, where you can drop it. While that's easy and intuitive for your stereotype 2-columns layout, it gets more tricky with the more complex layouts that provide multiple rows. Like in this example (showing the fixed version where you can see the dropzones once you start dragging):

As you can see, the visual appearance could use some improvement, but the technical requirement has been met. That's the caveat of having me work on theme issues: I'm able to make things look different - if you want them to look nice, you better ask someone else ;). Well, the arena is open and your suggestions for improvement are accepted and welcome.

The good news: The CSS that worked for 6.2 still works for 7.0 - no need to re-learn anything about the DOM for Liferay 7 - just add this CSS to the page (e.g. through the "Public Pages / Configuration / Look and Feel / CSS", alternatively private or individual pages) or to your own theme, and you're set:

You might also want to vote for LPS-40571 and LPS-53664 to get this feature out-of-the-box again.

Trackback URL:

Related Assets:

Today I'm welcoming a repeat guest, Jorge Ferrer, Liferay's VP of Engineering. I've had the great opportunity to ask him a lot of questions that provide deep insight into what's running behind the scenes in the engineering team. We didn't have enough time, so this is part 1 of our conversation, to be continued in episode 58. I need to squeeze in the (already recorded) episode that contains more information about the Javadoc Contest (please participate). Those episode links will work once the two episodes are public)

Jorge gives an update on various internal as well as external topics. I'm also teasing him a bit, and hope that this episode will be as insightful for you as it was for me.

We're talking about these (and more) topics

the engineering team passed the 150 people mark, distributed world wide.

Communication in a team that's distributed through the world, tools

Some nasty german guy recently took Jorge's #3 contributor place on the public forums

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. Make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

Or just download the MP3 here

Trackback URL:

Related Assets:

In this episode I'm talking probably one last time to James Falkner about upcoming changes... James was the first guest on Radio Liferay (back in episode 1 - as well as others) and now - at least temporarily until episode 56 is published - will be the last. We're talking about upcoming changes, and sadly it looks like this will be his last appearance on this program.

If you know what the background of this story is already, you'll understand that I think full shownotes for this episode are not really appropriate. However, here are a few references if you want to follow up on some of the details:

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. Make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

In this episode, recorded at Liferay's Devcon 2015 in Darmstadt/Germany, I'm talking to Scott Nicklous and Neil Griffin. Scott is the specification lead for JSR-362 - otherwise known as the Portlet Specification 3.0 - and Neil serves as Liferay's representative on the expert group.

JSR 362 and its impact on UI, there's a Client-Side standard (on ECMA script) for the first time in the portlet spec

The big question: When will it be done? (Some time 2016)

Early Draft Review Spec available, ~80-90% of content is expected to be there (That's the statement from Devcon, in October 2015)

Reference Implementation (to prove that the spec can be implemented) and TCK still missing (again, October 2015)

Reference Implementation and TCK will be implemented under the Apache Pluto project, help required

New Features include Bean-Portlet-Approach (portlet methods specified through Annotations in any Managed Bean), portlet.xml file no longer required if Annotations used

specifies a JS API despite being a JSR, which covers traditionally only Java

Dependency to JavaEE: Minimum is JavaEE 7, e.g. Servlet 3.1 etc.

Portlet Spec is not part of the JavaEE, but extends some of its elements.

CDI

JSR 378: Portlet 3.0 bridge for JSF (where Neil is the spec lead), being built in parallel with JSR-362

Multiplatform Support, Websocket, Devices

The E-Mail Archive of the specification process is public - contribution and comments are very welcome

Follow @RadioLiferay on twitter for news about the latest episodes, and occasionally more.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. Make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

I met repeat guest Nate Cavanaugh, Liferay's Director of UI Engineering, at this year's Devcon and he answered all UI-based questions that we could quickly think about - specifically with regards to Liferay 7.

As we recorded this on site at Devcon, you'll hear more background noise than usual - Auphonic did their best to clean the recording, and they did a great job.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. If you like this, make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

A continuation of last week's episode, Milen Dyankov stepped in as a co-host and helped me ask the right questions: Ray Augé answers all sorts of questions about the Modularization in Liferay 7 and what to do with your existing investment in Liferay Plugins - what to do with the plugins you already have, where you will have to re-learn and what you can, should or shouldn't continue to do..

As we recorded this on site at Devcon, you'll hear more background noise than usual - Auphonic did their best to clean the recording, and they did a great job.

Here are some of the topics that we talked about:

Portlets:

If you're not interacting with Liferay, e.g. a pure JSR-286 portlet: No changes required

JSF: Last kinks are worked out - test the more complex the JSF implementation is

If you're using Liferay API: You'll have to resolve API changes - e.g. recompile and check if the API is still valid. Check these breaking changes - well documented, huh? And even better: The document is machine-readable and there will be migration tools (future episode planned)

If the service is still in Liferay's core: No change needs to be made.

If the service is now in a module: Check if the package was updated. Fix if necessary and if the migration tool didn't do it for you.

Circumstances under which Liferay automatically "translates" WAR file into OSGi bundles - and the caveats

Extensions to Liferay MVC portlet: Check for the nature of those changes

The use of CDI - especially when the appserver's implementation/resources are utilized - still requires some work.

Everybody who's doing really advanced stuff on sophisticated frameworks is welcome to try it out now and let us know now if there are any problems that remain

How little of OSGi can I get away with?

Hooks

Many of the hooks - especially on services and models will continue to work, but won't have more power than in 6.2. They're prime candidates to be converted to an OSGi module as this will enable them to tap into a lot more extension points in Liferay 7.

Struts Action Hooks probably need changes - while they still work, most of the underlying actions have been reimplemented without Struts \o/, so possible overloads in Struts actions won't be taken into account for the new implementation.

(most likely: You need to convert to an MVC Command, injected as an OSGi module. There are samples available)

Liferay 7 has a lot more extension points than prior versions. The documentation is being made available on dev.liferay.com - obviously this is still work in progress, but is scheduled to be there until release.

How can IDE and other tools help identifying which extension points are in use? And how to make lots of friends within the Liferay Community

Overriding Language Keys is quite simple - choose "global" or "per portlet" - those are the two available scopes that a translation can live in.

For migration you might have to decide which scope your changes should go into.

Encoding still is done in UTF-8

JSP-Hooks: The elephant in the room: Seems to be very popular, but always has aimed at the implementation rather than to an API.

As drastic UI changes happened in Liferay, these implementation need to be implemented on the new infrastructure, leveraging new techniquest (e.g. Lexicon). Also, most of the functionality has been moved into modules - JSP-Hooks only affected the core jsps...

New options: JSPs can be deployed as proper OSGi bundles.

There's still danger because technically the implementation is unchanged compared to earlier versions

New fragment modules enable you to override JSPs in any portlet - not only core ones. But you shouldn't limit yourself to JSP-overrides: There are more ways to change Liferay's UI, e.g.

replace the render-phase of a portlet through a portlet filter.

A new "dynamic include" API to inject extension points at very specific places - e.g. at those UIs commonly targetted by overrides. (let us know which are missing) Application Adapters

Ext

Ext Plugins work just like before (in core). But most likely, the implementation has changed anyway, so that you need to make sure your code is still valid for the current version - but that's what you expected when you started writing that ext anyways, right?

Of course you'll have to check if your changes still are contained in Liferay core. If they're extracted to a module, ext won't be yours any more (for these changes) Ideally, ext will be the easiest plugin, as it probably will be a lot smaller than before.

We haven't covered all possible questions and are planning a "Listener Questions" episode. Please ask your questions in the comments to the blog article for this episode to get them answered in the next episode with Ray.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. If you like this, make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

Another Devcon "private" session - I missed his presentations, but got the summary right when he was done: Ray Augé took the time to answer all sorts of questions about the Modularization in Liferay 7. In fact, he answered so many questions that we made it a 2-episode recording. This week it's about the motivation for modularization: What problem does it solve? Next week will be more technical, telling you about the implications of the updated architecture to your code.

As we recorded this on site at Devcon, you'll hear more background noise than usual - As usual, Auphonic did their best to clean the recording, and they did a great job.

Here are some of the topics that we talked about:

OSGi in Liferay 6.2 vs Liferay 7.0

Modularization of Liferay 7.0

Surprisingly (not!), modularization is not yet fully done, but it came a lot further than expected initially

How much do you have to re-learn to build plugins for Liferay 7

James: Community Roadmap Talk from Devcon (note: Ray also had several presentations at Devcon, you'll find his recordings there as well)

Now everybody should be able to work the same way: Internally in Liferay's core as well as externally, in the plugins.

Ant vs Maven vs others? What's the story with Liferay's supported Build environments? More energy will go into build tools other than the SDK

Of course we cover a release date :) I'm getting a very rough one from Ray :)

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. If you like this, make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

Wow, 50 episodes already. At this year's Devcon I spoke with Jens Bruhn. He's Software Architect at Prodyna AG, a Liferay Partner and the author of Nabucco Script Center, a Liferay App available on the Marketplace. He also convened the "Pimp my Scripting Engine" workshop at Liferay's Devcon 2015, which I missed. But this only provided a perfect reason and excuse to speak to him.

As we recorded this on site at Devcon, you'll hear more background noise than usual - As usual, Auphonic did their best to clean the recording, and they did a great job.

For the visuals, please see the screenshots in this article as well as the plugin's homepage.

Here are some of the topics that we talked about:

The Elevator Pitch: What's Nabucco Script Center?

Scripting in Liferay: The native script console, its use and its shortcomings (solved in NSC)

a short demo of Script Center. It makes sense to check the screenshots alongside, or even install the plugin:

various scripts (for example: Reset Terms of Use Acceptance) and instruct content editors to execute this script whenever they change the actual Terms of Use Article)

Automatically run scripts (again, same example, this time executed automatically on every update of the article) - comparable to a model listener plugin for Liferay's Service Builder

Scheduled Script execution. And basic sanity checks: When deactivating user accounts, you might want to have a few exceptions to your rules, e.g. in order to not lock out administrators that can help you gaining back control, but are not logging in every day.

Prodyna has scripts available on the app's homepage - e.g. What happened during the last 24 hours? How many users logged in yesterday? Basic data on usage on the start page ("heartbeat"). Warn authors in time before review dates of their content. Assign permissions based on categorization of content.

Fine grained permissions can be granted per script, e.g. just because you're able to upload/edit a script you might not be able to execute it - and vice versa.

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. If you like this, make sure to write a review for the podcast directory of your choice - or find everything about Radio Liferay on liferay.com/radio.

It's been a long time and finally... Radio Liferay is back with several episodes in the queue. Today, Tomáš Polešovský starts of by talking about Liferay's security team and -procedures as well as his work within that team. Tom has already been a guest on Radio Liferay's ancient episode 9

Here are some of the topics that we talked about:

The glorious glamorous days one has on the security team (consisting mostly of email, tickets, pullrequests)

You'll find this episode - and make sure that you don't miss any of the future episodes - by subscribing to http://feeds.feedburner.com/RadioLiferay. You can also subscribe on itunes.: Just search for "Radio Liferay" or just "Liferay" in the podcast directory. If you like this, make sure to write a review for the podcast directory of your choice - or leave your feedback on www.liferay.com/radio.

English Summary: As it's a german language event: This is about a community meeting that will largely be held in the german language, although everybody is welcome and there are plenty of english speaking people there. If you're in Vienna/Austria, you'll be able to parse the meeting time and location from the text above. Please register 1 week in advance, so that we can let the caterer know how many people to expect.

I'm slowly back to my regular sleep rhythm, after the highly anticipated sleep deprivation week that Devcon always is. Those ~450 participants that were there and made it the biggest and greatest Devcon so far will have seen that Liferay becomes a lot more serious in terms of messaging while still staying accessible on all levels. I've seen lots of connections being made and can attest that Liferay seems to be one of the companies and products with the most accessible team in the background.

Project Managers, Engineers, Supporters, Consultants, Legal- and Sales-people have been available for customers and community. They gave information about the current product, the roadmap and collected feedback and new ideas for future versions.

We've started with the always informal and extremely productive unconference at day 0 - this format was offered for the third time and was sold out long before the event. If you want to participate next year: Be sure to register as early as possible. If you don't know what to expect at an unconference: Come and see for yourself - prepare to be surprised.

For the first time ever we also had to close the community meetup registration in order to guarantee enough space for everyone and enough air to breathe. Sorry for that to those that weren't able to come, take this as a hint that early registration really helps us to plan for such an event.

This year we introduced a new Priority Check In, welcoming Liferay Certified Developers on the red carpet they deserved, and several goodies. We'll make it even more priority next year, promised. If nothing else - take this as a motivation to be certified as a Liferay Developer before you come to Devcon next year.

Devcon itself was the biggest (by quantity as well as quality) Devcon we had so far. 450 attendees and long two days of sessions and workshops. You can find all of them in the agenda - very soon the slides and videos will be available as well.

Octoberfest, the big party at Devcon, was fun. And while James is still uncertain if there was some hidden agenda with his barrel-opening, he did a great job. Here's what could also have happened

In case you had to leave before the raffle, nothing bad has happened to you: All the winners were still present and while you missed some great content in the end, at least you didn't miss the additional luggage. I'm still wondering how some of the winners transported their prices back home.

Would you like to re-live Devcon? I want to, as I've missed so many presentations. You'll find some summary in the tweets, hashtagged with #LRDevcon, also there's a flickr-album and I'm sure that you'll find other resources. Stay tuned for the Recap Site, which will be updated once all the material is ready and the video recordings are postprocessed. I've recorded several episodes for Radio Liferay, which will be published during the next weeks.

If you have more photos that you took during the event, please upload them through the app and they'll appear in the flickr stream.

And if you missed the event due to continental restrictions, consider to come to the North American Symposium in November in Chicago or Brazil Symposium in São Paulo. If it were only national restrictions we have more european options with technical sessions this year in Spain, UK and Italy. Or just keep updated on everything - business and technical - on our events page.

Thank you

A big Thank You goes to the team that made this all possible. If you want to express your gratitude, flood @PBrusset and @Thirelu with your thank-you-tweets (or postcards to the german office) - Pascal and Ruth did the heavy lifting, supported by a big team. They will forward your notes to the whole team.

Liferay comes with so many features that it's hard to judge when a feature is a good solution for a given problem. I'd like to shine some light onto some of these features and common misconceptions about them because it's easy to abuse them for purposes for which they're not well suited - despite making the impression they might. CC BY-ND 2.0 by S. Benno

This chapter is about modifications that are commonly done to Liferay's out-of-the-box portlets.

It's easy to modify the OOTB-portlets: For the UI side you can introduce JSP hooks. On the action-handling side, you can override Struts-Actions (for example). You can go even further and fiddle with request parameters (e.g. in servlet filters), but let's keep it at the first two options for now.

Why does Liferay's Portlet not do what I want?

Liferay (the portal) is a platform that must be everything to everybody. As a platform vendor, Liferay (the company) must implement Liferay (the portal) with as broad applicability as possible. You (the implementor of a specific portal) on the other hand typically need to focus on one very specific problem: Your portal. You don't need all this flexibility and configurability beyond your own usecases. You're just interested in implementing your own requirements.

Consequently, some of Liferay's implementations might be overly generic for you. You can be happy that they are, because that means that there's a very good chance that there's an overlap with your requirements. And if it isn't big enough an overlap, you can still customize Liferay's portlets and UI to match your requirements. Knowing that you can change the UI with "just a simple JSP hook" is tempting. If all you need is a simple change to a simple UI, go for it. The more complex either your change or the changed Liferay component is, the more you should refrain from such a quick fix.

What to do when OOTB is not enough?

So what - you need a change to a complex UI. There are JSP-Hooks and Struts Action overloads. They might do what you want, and are readily available, quickly done. Are they always the tools that you should use? Well...

There are two aspects that you should keep in mind when thinking about JSP hooks and changing Liferay's OOTB-portlets in general: Maintainability of your changes and the fact that customizations are global to the whole portal. Any customization that you're doing to a portlet will be available everywhere (I'm ignoring Application Adapters here, but you'll get the point).

The elephant in the room is Maintainability. If you're looking at Liferay's JSPs, most of them - especially the more flexible, configurable ones - are not the files that you want to touch. Imagine yourself changing them, and then receiving an update from Liferay. Be it the next CE GA version or the next EE Servicepack. When this update changes the file that you've customized as well, you're up for a three-way merge. Enjoy. Potentially on every update. Rinse, repeat. Probably not what you're looking forward for.

What other options do you have?

All other things being equal (which they never are), I personally value maintainability higher than any other aspect of a customization. Particularly higher than quick implementation. For that reason, sometimes I rather suggest custom portlets that do exactly what you want them to do - no configuration, no nothing. Consider the options: For something that's close, but not 100% of Asset Publisher, you can hard code exactly the functionality that you'd like to see in your own tiny custom hard-coded portlet, or modify Asset Publisher to pay attention to just one more option.

If you know Liferay, you'll know that Asset Publisher is a very powerful portlet, possibly the one with the most configuration options. Maintaining your changes in Asset Publisher's JSPs will be really hard - particularly because there are so many conditions that need to be taken care of. Typically a more complex component attracts more bugfixes than a very simple component, so the odds of three-way-merges are quite high. Writing your own hard coded plugin on the other hand is guaranteed not to interfere with any future updates of Liferay.

Have you just heard a suggestion to hard-code portlets?

Yes indeed. Hardcode as much as makes sense in your portal: In your portal, you need to take care of your requirements. Your requirements are typically not as broad as Liferay's. You don't (always) need to implement a generically configurable system. At least you don't need the configurability to the same level as Liferay does. Where Liferay needs an "Asset Publisher" (just the name is quite abstract), you might need an "Interesting Facts" portlet. The criteria for interesting facts can totally be hardcoded - you might want to configure the number of items shown, maybe some more, but not 20+ options like Asset Publisher does.

If all you have is a hammer...

...the world looks like a nail. This article is meant to add more tools to your toolbox. Just because Liferay makes its UI available for customizations this doesn't mean you must always use this technique to implement your customizations. Create your own simple navigation portlet, if Liferay's is insufficient for you. Create your Web Content filter by accessing the CMS-API instead of modifying Asset Publisher. Think simple, think maintainable. The more of the core you change, the harder you'll resist to updating your portal, even on a minor update - let alone on a security update. And that will bite you sooner or later.

If the message sounds vaguely familiar, here it is again, with a more specific example. And yes, the complexity that I'm suggesting here is: A few hours of creativity for creating the new plugin, rather than the same hours of trying to understand and patch any of Liferay's existing portlets.

You can still do that, but choose wisely when you'll actually change vs when you create your own portlet. Whatever you do: Remember that most effort will go into the maintenance of your code. Optimize the maintenance time.

Do you remember the article that I wrote in March? It talked about Liferay's limitation to have each overloaded JSP only customizable from one hook. The limitation was not enforced, so deploying multiple hooks that overload the same JSP lead to undefined behaviour, potentially deleting the original JSP. CC BY 2.0 by David GoehringLuckily that has been fixed (currently in EE only, feature needs to be enabled), but I still like my version better: It's more verbose in its error messages. And then - there's more: The very same limitation (albeit not as destructive) is in effect for Struts Actions: If you override the same Struts Action from two different plugins, the last deployed plugin wins, the first one's Action will be forgotten. And when we inspect this further, we have some undefined behaviour as well: Let's say Hook A and Hook B override the same Struts Action and are deployed in that order. Now only Hook B's version will ever be executed (as it was deployed last).

In case Hook A is now undeployed, the runtime system will detect that Hook A intended to override the Struts Action and remove the customization. Now, despite the fact that Hook B is still deployed, its Struts Override is no longer deployed. Luckily, this is not destructive like with JSPs, but you might still pull out your hair when you're debugging such a situation. Let me save your hair - I know how it feels to walk around with little hair. Mine is not enough (and too short) to pull it out:

An updated HookDeployer \o/

The hook that I've presented in the old blog article received an update and now is aware of Struts Actions. You can go to github, build the ext plugin and deploy it. Be aware that the code is "Proof of Concept" quality. CC BY 2.0 by David Goehring and yours truly Before using it in production you should really validate that it does what you expect.

About the implementation

If you look at the code, you'll see that there's a relatively small class that just does the checking. In case everything is right, it delegates to the original deployer. This is why I expect this code to be compatible with all 6.2 releases (and potentially even 6.1 without checking). One way to write maintainable ext plugins is to add new code in new classes and delegate to the original classes: If the original classes are changed in some future release, the additional code has a good chance to go without changes. It's Liferay's business to change the implementation, thus I've avoided to change the original HookHotDeployListener class.

Check out the code on github - fork and send pullrequests: Again, note the "Proof Of Concept" disclaimer. Please try, test & inspect on it out on your platform & version. I deliberately won't tell you which version I've tested it on to force you to test :)

Like in March (this is the same plugin as back then): I can't make it available on marketplace, as it's an ext-plugin. Sorry.

Trackback URL:

Related Assets:

It looks like I'll stay on this™ side of the atlantic ocean this year, so I'm concentrating on introducing the big events that I'm attending next and link to the others, in the hope that I'm not missing any. If you are in other parts of the world: All of our events are worth going to and you'll get your personal share of ideas, contacts and great conversations.

I got my first share of Liferay knowledge during one of these events (yes, it was a while ago) - and since then, all the events continued to amaze me on communication of knowledge as well as on getting to know other customers as well as Liferay staff. This is the prime opportunity to meet&greet and get your questions answered.

We will open the season with another great combination in Darmstadt/Germany. For the second year in a row we're having Liferay Portal Solutions Forum and the Liferay Developer Conference in the same venue in Darmstadt - and I'm looking forward to your participation. Here's what the two events are about

Liferay Portal Solutions Forum Germany

This is a german language event, focussed on the business side of Liferay. Due to the event language, it feels appropriate to announce it in german language. If you don't understand this next block, the event is not for you, but scroll down past the box, there's more. If you do understand it and it resonates: Register.

Liferay Devcon

The technical event for Enterprise IT and Devs on 7.-8. October 2015. Meet the community, learn everything there is to Liferay on the technical side. Come one day early to the Unconference (but hurry, it's already almost sold out)

Lets meet at DEVCON 2015

Featuring over 40 in-depth sessions and technical workshops, the 2-day Liferay Developer Conference is a great opportunity to build your Liferay expertise and apply fresh knowledge and perspectives to your current and future projects. Watch our our recap video and learn more.

More information on the event's homepage. Note that Early Bird Registration savings are open until 11. September, but the Unconference will probably sell out sooner than that is already sold out - We'll register on a first-come, first-served basis.

There are great savings if you register early, in groups, as Liferay customers or as a repeat guest (Alumni). Don't miss them.

If you're coming to Devcon, note that there's yet another Community Meetup in Darmstadt the night before DevCon (6. October). Registration is free and necessary if you want to get free drink vouchers. (If you have been at those events earlier, you'll know the drill)

Other events

I promised you, we have more. Some are later this year, some are on the "other" side of the ocean (it's all a matter of standpoint). Here's what you should pay attention to if LPSF-DACH and Devcon are not for you due to continental or language restrictions - and no regret if you can't meet me there (quite ego-centric, huh?) - my other colleagues and the community of Liferay-Users are well worth meeting too - say "Hi" from me ;)

Liferay Symposium North America

Liferay Symposium Brazil

Are you new to Liferay? Found Liferay and want to know what it can do for you? Or are you with Liferay and still remember the time when you were new and unexperienced? Where did you come from and what was the biggest problem you faced? Can you ever learn enough? And how do you keep up with the current trends and new features?

A platform as big as Liferay spans several technologies and areas of best practices that are beneficial to know of. Nobody can know everything - there's always a learning curve. At the beginning, it's quite steep. Some argue that it's flattening the more you know. Some argue that it gets steeper: The more you know, the more you know what you don't know.

I'd like to give you pointers to resources that are available to you, in order to learn about Liferay, resources that help you avoid steep detours, when there are flatter direct connections. This is meant to be (eventually) comprehensive but I'm sure that it will never be complete. It's just what I remember while I write this article, the previous ones in the series and the follow ups (yes, there are more, see the list at the end)

Today's Target Audience: Today there will be something for everybody

As this is all about training, let me start with an actual story from one of the trainings that I led. This is a good summary of the reason to consider working with a well-trained team:

My (best, but) least anticipated training experience

Once upon a time (back in 2011, one and a half year after I became a Liferay Trainer) I was sent to a customer to conduct an onsite "Portal Administrator" training with their development team (The name of this class recently changed to "Mastering Liferay Fundamentals"). The team that I was meant to train was highly experienced in Liferay, developed plugins and customizations for solid three years back then. They've had high-profile Liferay people on site, among them even one of our core engineers that we never send out (don't ask).

Now, "Mastering Fundamentals" is basically giving an overview over what Liferay can do - the whole backend, user management, page management, sites, organizations, portlets and out-of-the-box functionality. It's approaching everything from the feature- and front-end side. It felt like 3 years too late for that team - they must have found every single feature already long time ago - or so I thought. Trust me, I was really nervous. I expected getting through the class in record time, followed by a lot of complex and challenging questions on their project. (not that I'd mind challenging questions, but I didn't know their project at all. And I like to make a good impression)

Instead of finishing early and lots of complicated questions, we finished the class right in time (after two days), with the participants constantly checking back to each other - "Wow - did you know Liferay can do this? Remember how it took us 3 weeks to implement similar functionality? And now we'll have to maintain that code". I was stunned.

So, what do we learn from this story?

Even as a well experienced developer it makes sense to get the a nontechnical introduction to the platform. If the only toolset you have at hand is your compiler, you'll think along its lines. If you know what you build on, know the infrastructure that you're integrating with, you can use it to your advantage and just configure it to make the required features available. Maybe tweak them a bit.

Of course a developer can solve all problems you throw at them, typically with some more code. But new code might not always be the best way to solve every problem. If all you have is a hammer, the world looks like a nail.

And, by the way, some years later, one of those students recognized their class when I told this story at an event (without revealing their identity). He confirmed that they had the same experience.

The best maintainable software feature is one that you don't need to write, because it's already done. Know what's available for your to tweak and you can utilize it with ridiculously low effort.

So - what are your options?

Liferay has several training classes, readily available. You can either join us at one of the public trainings or schedule a trainer to come to your location and have a private training with just your team. Let's go through them and identify the target audiences. For a full description I've linked the full course topics and contents in the headlines:

This is the class that the story above was about. Fundamentals are really good for everybody who has a saying in the structure of a portal. Those who will have to configure Liferay to meet the needs of all stakeholders. You'll learn about many features that Liferay has out-of-the-box.

It's also a great way to make sure you don't develop the same features that Liferay already brings with it - so at least some of your developers should have a deeper knowledge of the platform.

This course is also offered online. The online version is spanning three days, with the afternoons free of class.

Any portal/portlet developer should know what we cover in this course. From relating the portlet API to the servlet API over service builder, utilizing Liferay MVC, Liferay's runtime-configurable permission system and customizing Liferay on many different levels, it provides the basic tools to explore Liferay from an API point of view.

With this course you'll be able to write your own applications, extend Liferay and know where to look for when you want to customize it. It should contain most (apart from some experience and routine) of what you need for getting certified as "Certified Professional Developer" .

From the feedback that I've had about "Developer 1" training: Everybody has gotten something from that class - even the more experienced developers that thought they already know everything. In fact, we're coming with several interesting bonus exercises for the more experienced students so that you definitely don't get bored just because you're quicker than the newbies.

Are you setting up Liferay systems? Configure them? If you're responsible for maintaining, tuning, backing up and the general server health, this is your class. You'll learn about all of these topics, set up a cluster, and get to pick the brain of an experienced trainer on so many topics. We'll come with a ready-to-go VM, but you can also bring your own appserver and database for installation.

Your portal should look like your portal. To adopt the Look&Feel you'll need a theme - this is the one custom plugin that everybody typically has. We'll cover the basic structure of Liferay's themes, principles and building blocks and build a custom theme. This covers best practices, responsive layouts, tipps & tricks and more. Naturally, the result won't look like your CI, but you'll have experienced all the different extension points and can easily use this knowledge for the implementation of your own theme.

Some HTML and CSS knowledge is required - we'll just adopt it to the Liferay world and help you build a well maintainable theme.

If you're responsible for the content side of Liferay, you might want to learn more about its CMS, go in depth in workflow, the Asset Framework, Structured content, Staging and how to build and maintain the content of your portal. This class is for you then. We're setting up Liferay on your own computer so that you go home with your own installation and can continue working on it after the class.

It's number 2, so it must be more advanced than number 1, right? Well, this class starts exactly where "Developing for the Liferay Platform 1" stops and picks up the resulting code from that course, refining it further. If your portal makes good use of Liferay's internal concepts like Assets, Workflow and features like Rating, Commenting, this course is for you. Same if you want to be even better prepared for the certification.

Just remember: You really should take the first course before the second as all the ground works is layed out there and your trainer might not explain the "old" concepts and code again (out of respect for those who indeed have been in "Developer 1").

Who's the trainer?

All of Liferay's classes are led by experienced trainers. When we're certifying trainers, we're paying attention to their experience as well as their teaching style. Every trainer is able to go beyond just covering the course curriculum. So, of course you should bring your questions with you.

Check the list of upcoming trainings in your region, timezone and language. Also, check the shiny badges on the personal profile page (here's mine) that you can show off with. You'll get them after each of the trainings that I mentioned if you take them straight from the source - Liferay - or from one of our certified training partners.