Liferay.com

Friday, September 18, 2015

Tomcat windows click on startup.bat disappering

Start tomcat with catalina.bat run option

C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27\bin>catalina.bat run
Using CATALINA_BASE:   "C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27"
Using CATALINA_HOME:   "C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27"
Using CATALINA_TMPDIR: "C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27\
Using JRE_HOME:        "C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27/
Using CLASSPATH:       "C:\lr\liferay-portal-6.1.20-ee-ga2\tomcat-7.0.27\
Error occurred during initialization of VM
Could not reserve enough space for object heap

You will know the issue why it was disappearing. Fix it based on error accordingly. In this particular case I reduce -XX:MaxPermSize value from 512m to 256m


Tuesday, March 3, 2015

Configure Test Mail Server Tool

Steps 2 configure Test Mail Server Tool
1) download & install Test Mail Server Tool from below link - once installed changed the port to 2525

 http://www.toolheap.com/test-mail-server-tool/

2) configure liferay mail settings accordingly (Server Administration > Mail )



no user details given while configuring mail settings in Liferay

3) open eml file viewer installed from below link, browse to mail path to store received email (C:\Users\Nagendra Busam\Desktop\Mail Sent to Local Server) . As I have testing this on Windows 7, it is doesn't have eml viewer by default installed this.
http://www.freeviewer.org/eml/

4) created user to check whether default MESSAGE if not configured mail server shows up (as below)

][MailEngine:592] Failed to connect to a valid mail server. Please make sure one is properly configured. Could not connect to SMTP host: localhost, port: 25

If not showing up you have configured your mail server properly

Thursday, February 26, 2015

Change Liferay site name to different name


1) Go to the place show in control panel, do the change to Name field


2) through portal properties

I think you need to change company.default.name property value to whatever you want to

Thanks.

Wednesday, September 24, 2014

Quick checking of API methods - Groovy Script (at Control Panel > Server Administration > Script)

Here are some snippets,

======================================================
Case 1 : here I am checking whether a particular User Group & Role exists
======================================================

import com.liferay.portal.service.UserGroupLocalServiceUtil
import com.liferay.portal.service.*
import com.liferay.portal.util.*
import com.liferay.portal.kernel.util.PropsUtil
import com.liferay.portal.kernel.util.PropsKeys

companyId = CompanyLocalServiceUtil.getCompanyByMx(PropsUtil.get(PropsKeys.COMPANY_DEFAULT_WEB_ID)).getCompanyId()
out.println(companyId );

try{
// Get User Group(s)
def customGroup = UserGroupLocalServiceUtil.getUserGroup(companyId , "My Org Admin")
out.println("User Group exists : Agency Admin :"+customGroup)

// Get role(s)
def customRole = RoleLocalServiceUtil.getRole(companyId, "My Org Admin")
out.println("Role exists : Agency Admin :"+customRole)

def groupIds = [customGroup.getGroupId()] as long[]
GroupLocalServiceUtil.addRoleGroups(customRole.getRoleId(), groupIds)
}catch(Exception){
out.println("My Org Admin -- UG not exists")
}

======================================================
Case 2 : updating one of my custom field
======================================================

import com.liferay.portal.service.*
import com.liferay.portal.util.*
import com.liferay.portal.kernel.json.*
import com.liferay.portal.kernel.util.PropsUtil
import com.liferay.portal.kernel.util.PropsKeys
import com.liferay.portal.model.RoleConstants

companyId = CompanyLocalServiceUtil.getCompanyByMx(PropsUtil.get(PropsKeys.COMPANY_DEFAULT_WEB_ID)).getCompanyId()
out.println(companyId );

try{
role = RoleLocalServiceUtil.getRole(companyId, RoleConstants.ADMINISTRATOR)
users = UserLocalServiceUtil.getRoleUsers(role.getRoleId())
out.println(users)
out.println(JSONFactoryUtil.looseSerialize(users))
out.println(">>>>>>>>>>>>>>>>>>>>>. groovy iterate")
users.each() { it ->
println it
field = it.getExpandoBridge().getAttribute("sbm-user-id", false)
out.println("initial value :"+field)

if(!field){
it.getExpandoBridge().setAttribute("sbm-user-id", it.getEmailAddress())
}

out.println("end value :"+it.getExpandoBridge().getAttribute("sbm-user-id", false))
}


}catch(Exception){
out.println("Administrator role not exists")
}

Hope it helps some body :)

Thanks.


Tuesday, September 23, 2014

Grabbing permission keys of a custom role from control panel

We ran into a use case where we need to automate creation of custom roles having several hundreds of permission keys.

It's kind of tire some to grab each & every one either by looking into source code or grabbing using some browser tools.

I wrote a simple java script to grab keys for each portlet. We need to go to each portlet level to grab exact keys.

It will print in console relevant permissions for that particular portlet. I am using 6.2 for you reference

HOW TO TEST

>> After you navigation to your custom role, particular portlet - CTRL+SHIFT+J (in chrome)
>> paste below code & hit enter - it will spill relevant keys on console.

/*
Start
*/

var topPortletTxt = AUI().one('#_128_permissionContentContainer').one('h3').text();
var topGeneralNode = AUI().one('#_128_permissionContentContainer').one('h4');
var topGeneralTxt;
if(topGeneralNode != null){
topGeneralTxt = topGeneralNode.get('firstChild').get('textContent');
}

console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + topGeneralTxt + ' > ' + topPortletTxt + '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<');

var resourcePermissionsFull = "";

var resourcePermissionStartOpen = '';

var resourcePermissionEnd = "
";
var resourcePermissionActionStart = "";
var resourcePermissionActionClose = "
";
var topLevelResourceId = AUI().one('#_128_portletResource').val();

var commentStart = '';
resourcePermissionsFull = resourcePermissionsFull + commentStart + topGeneralTxt + ' > ' + topPortletTxt + commentEnd + '\n';
resourcePermissionsFull = resourcePermissionsFull + resourcePermissionStartOpen + topLevelResourceId + resourcePermissionStartClose;

var generalResourcePermissionsAll = "";
topGeneralNode.get('nextElementSibling').all(':checked').each(function(node1) {
        console.log(node1.val());
        if (node1.val().indexOf(topLevelResourceId) != -1) {
            generalResourcePermissionsAll = generalResourcePermissionsAll + resourcePermissionActionStart + node1.val().replace(topLevelResourceId, '') + resourcePermissionActionClose;
        }
    }

);

resourcePermissionsFull = resourcePermissionsFull + generalResourcePermissionsAll + resourcePermissionEnd;

console.log("resourcePermissionsFull : Top > \n\n" + resourcePermissionsFull);

// Related portlet permissions
/*
var relatedPortletsTxt = AUI().one('#_128_relatedPortletResources').ancestor().get('previousElementSibling').get('textContent');

var resourcePermissionsFull = resourcePermissionsFull + commentStart + topPortletTxt + ' > ' + relatedPortletsTxt + commentEnd + '\n';

var resourcePermissionsAll2 = "";
AUI().one('#_128_relatedPortletResources').get('nextElementSibling').all(':checked').each(function(node2) {
            console.log(">>" + node2.val());
var resourceId = parseInt(node2.val(), 10);
var resourcePermissionStartTemp = resourcePermissionStartOpen + resourceId + resourcePermissionStartClose;

resourcePermissionsAll2 = resourcePermissionsAll2 + resourcePermissionStartTemp;
resourcePermissionsAll2 = resourcePermissionsAll2 + resourcePermissionActionStart + node2.val().replace(resourceId, '') + resourcePermissionActionClose;
resourcePermissionsAll2 = resourcePermissionsAll2 + resourcePermissionEnd;

}
);
console.log("resourcePermissionsAll2" + resourcePermissionsAll2)

resourcePermissionsFull = resourcePermissionsFull + resourcePermissionsAll2;

console.log("resourcePermissionsFull : After Related portlet permissions > \n\n" + resourcePermissionsFull);
*/

// Resource permissions

var topResourceTxt = AUI().all('.permission-group').get('previousElementSibling').get('firstChild').get('textContent');

AUI().all('.permission-group h5').each(
    function(node) {
        console.log(topResourceTxt + ' > ' + node.html());
        resourcePermissionsFull = resourcePermissionsFull + commentStart + topResourceTxt + ' > ' + node.html() + commentEnd + '\n';

        var nodeIdPackageConv = node.get('id').replace('resource_', '').replace(/_/g, ".");
        console.log(nodeIdPackageConv);
        var resourcePermissionStartTemp = resourcePermissionStartOpen + nodeIdPackageConv + resourcePermissionStartClose;
        var resourcePermissionsAll = "";
        node.get('nextElementSibling').all(':checked').each(function(node2) {

            console.log(">>" + node2.val().replace(nodeIdPackageConv, ''));
            resourcePermissionsAll = resourcePermissionsAll + resourcePermissionActionStart + node2.val().replace(nodeIdPackageConv, '') + resourcePermissionActionClose;
        })
        resourcePermissionsFull = resourcePermissionsFull + resourcePermissionStartTemp + resourcePermissionsAll + resourcePermissionEnd;
    }
);

console.log("resourcePermissionsFull : Final > \n\n" + resourcePermissionsFull);

/*
End
*/

Hope it helps some body :)

Thanks.

Friday, July 18, 2014

Useful portal properties

########### you can hide Openid, Create Account,Forgot Password links by setting below properties in portal-ext.propeties. ###########
##
## Company
##
company.security.send.password=false

company.security.login.form.autocomplete=false

company.security.send.password.reset.link=false

company.security.strangers=false

company.security.strangers.verify=false

##
## OpenID
##

open.id.auth.enabled=false


Set below property to false in portal-ext.properties file if your liferay application server has concurrency issues with deploying large WARs.
auto.deploy.unpack.war=false


########### You can hide Liferay Version by adding below property in portal-ext.properties file ###########
# to hide Liferay Version
http.header.version.verbosity=partial


##  Steps to Change Liferay Context path:
##  Step 1: go to {liferay.home}\conf\Catalina\localhost\ROOT.xml
##  Rename ROOT.xml to required name. Eg. if you want context as portal then you have to rename ROOT.xml as portal.xml
##  Step 2: open portal.xml edit as below.
##   
##  Step 3: Add following property in portal-ext.properties
##  portal.ctx=/portal 

##  Done, restart your server. then access your server using : localhost:8080/portal

P.S. some properties are compiled by gather from online resources

Saturday, July 12, 2014

How to change maximize & minize icon in 6.2

There was a peculiar use case I ran into when i am working on a project.

Portlet icons needs to be changed in following scenarios
1) default maximize icon
2) icon we have with portlet once maximized
3) icon we have with portlet once minimized

Here is the CSS code snippet for the same.
/*to change icono f maximize to icon-resize-full*/
.aui .icon-plus:before {
    content: "\f065";
}
/* to change icon next to Restore when portlet minimized to icon-plus*/
.aui .icon-resize-vertical:before{
 content: "\f067";
}

Hope it helps somebody - Cheers :)

Wednesday, July 2, 2014

VelocityVariables.java in 6.2

Liferay 6.2 prior versions we used to have VelocityVariables.java, this has been changed in 6.2.


This is changed across into different files

VelocityTemplateContextHelper

TemplateContextHelper


Thursday, April 3, 2014

JSON object parameter passing

I came across a scenario where I need to use Liferay's JSON API for display certain no of documents under each folder depending upon configuration/preferences selected/set.

I need to display certain # of records order by modified date descending order

I didn't find a one workable example when I googled for certain time, here comes the savior - liferay documentation helped me in this regard to say frankly

https://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/json-web-services

Here is the code snippet I used

        var groupId = '<%= themeDisplay.getLayout().getGroupId() %>';
        var folderNames = ["Folder 1", "Folder 2", "Folder 3"]; //The names of the folders you wish to pull from and display;
        var auth = "<%= AuthTokenUtil.getToken(request) %>"; //url to the file that prints out the p_auth token

        function ajax(url, func, type) {
            result = '';
            jQuery.ajax({
                type: 'GET',
                url: url,
                func: func,
                dataType: type,
                async: false,
                success: function (data) {
                    result = data;
                }
            });
            return result;
        }

        jQuery(document).ready(function () {
            var html = '';
            var quickHitshtml = '';
            var whitePapershtml = '';
            var noOfDocsToDisplay = '<%= noOfMarketCommentaryDocs %>'; // reading value from preferences
            jQuery.each(folders, function (i, item) {
                if (jQuery.inArray(item.name, folderNames) > -1) {
                    var files = ajax("/api/jsonws/dlapp/get-file-entries/repository-id/" + groupId + "/folder-id/" + item.folderId + "/start/0/end/" + noOfDocsToDisplay + "/+obc:com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator?p_auth=" + auth + "&callback=?", 'files', 'jsonp');
                }
            });
        });

please add relavent imports & porltet/theme should be loaded with jQuery

Liferay AUI 2.0 modules

Saturday, November 16, 2013

Some useful notes :)

p_p_lifecycle

p_p_lifecycle=0 > render url

p_p_lifecycle=1 > action url

p_p_lifecycle=2 > serveresource url



you might be have seen p_p_lifecycle in query string many times BUT might be not knowing exactly what is each value exactly mean

It is important to know what are the possible values for p_plifecycle & how they can be helpful, might be useful in forming friendly urls (of Freindly url routes feature of Liferay)

Liferay Sample plugins

For latest version of Liferay released you will have at

You will have plugins for other versions tagged appropriately here

Tuesday, November 12, 2013

Browsing through different Alloy UI versions documentation


As of writing this post we have 1.0.x, 15.x & 2.0.x Alloy UI versions available

For API documentation related to exach version you can browse as below

http://alloyui.com/api/ - This points to latest documentation always (which is 2.0.x)

http://alloyui.com/versions/1.0.x/api/

http://alloyui.com/versions/1.5.x/api/

How to navigate to different versions from http://alloyui.com/, you will some selectable kind of option at ALLOYUI as show below



Hope it helps some people who have hard time finding out AUI documentation

Using Liferay.provide - to add global java script function

An example function

Liferay.provide(window, 'existingUser', function(sessionId, buttonClicked) {
var A = AUI();

var hrefDefaultVal = A.one('#openServeyWindow').getAttribute('href');
var jsAtt = sessionId;
A.one('#openServeyWindow').setAttribute('href', hrefDefaultVal+jsAtt);

A.one('#openServeyWindow').setAttribute('onclick', "saveEntry('${count}','${newSessionIdPK}','${recentSessionIdPK}','"+buttonClicked+"' );");

if (navigator.appName == 'Microsoft Internet Explorer') {// as AUI simulate is not working in IE, handling through window.open
var elem = document.getElementById("openServeyWindow");
if (typeof elem.onclick == "function") {
   elem.onclick.apply(elem);
}
window.open(A.one('#openServeyWindow').getAttribute('href'));
}else{ // other browsers
// click working fine with below command for IE, redirect is not happening
A.one('#openServeyWindow').simulate('click');
}

closeRmiWindow();
window.location.replace('${lastAccessedPageUrl}'); // to redirect to previous page
},
['node-event-simulate']
);

Somehow this works well compared to (it seems because of lazy loading aui does with aui:script use attribute)
 
// whole function code from above

Wednesday, October 9, 2013

Fast Plugin Development (tomcat)


This is really useful when working on plugin development & making frequent changes to jsps/java files.

If you have Service builder as part of your plugin & you changed any of XXXLocalServiceImpl.java/XXXServiceImpl.java file(s) - after you re-run service builder, you may need to re-deploy/restart the server. Service builder re-run seems messes up context (with auto-reload)

I did used this setup long back though (5.2 EE sp3) BUT found this is very helpful

http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Fast+Development+of+Liferay+Plugins+with+Tomcat

Njoy fast dev..ing

Saturday, May 18, 2013

Direct SQL insert statements to Liferay out-of-the-box tables

UseCase

I came across a scenario where i need to insert some values into default liferay table on my custom portlet deployment. Particularly ListType table..

FYI, I am using Liferay 6.1 EE GA2

Two approaches came into my mind

1. Using Hook's upgrade process approach

Step 1: portal.properties file of your portlet should have below entries

# to run insert statements
release.info.build.number=110
release.info.previous.build.number=100
upgrade.processes=com.aon.org.admin.upgrade.UpgradeProcess_1_1_0


Step 2: liferay-hook.xml should have below entry



Step 3:

package com.test.org.admin.upgrade;

import com.liferay.portal.kernel.upgrade.UpgradeProcess;

public class UpgradeProcess_1_1_0 extends UpgradeProcess {

public int getThreshold() { return 110; }

protected void doUpgrade() throws Exception {
// your upgrade code here. } }

runSQL("insert into ListType (listTypeId, name, type_) values (22000, 'local-client-address', 'com.liferay.portal.model.Organization.address')");
runSQL("insert into ListType (listTypeId, name, type_) values (22001, 'global-client-address', 'com.liferay.portal.model.Organization.address')");
}
}


That's it, you are good to go, it will insert relevant data into respective ListType table.


2. Using SqlUpdateFactoryUtil Liferay API method to insert according to my needs in my Entity (I have service layer if you don't have one you can create a facade i.e., entity without columns)


Step 1: For e.g., if your entity name is Dummy, in DummyLocalServiceUtil add below method

        public void insertStaticData(){


/**
*
*
*
insert into ListType (listTypeId, name, type_) values (22000, 'local-client-address', 'com.liferay.portal.model.Organization.address');
insert into ListType (listTypeId, name, type_) values (22001, 'global-client-address', 'com.liferay.portal.model.Organization.address');
*
*/
// DataSource dataSource = (DataSource) PortalBeanLocatorUtil.locate("liferayDataSource");
String insertQuery = "insert into ListType (listTypeId, name, type_) values (22002, 'local-client-address', 'com.liferay.portal.model.Organization.address')";

SqlUpdate _sqlUpdate = SqlUpdateFactoryUtil.getSqlUpdate(orgTypePersistence.getDataSource(), insertQuery, new int[]{});

int count = _sqlUpdate.update();
System.out.println("after update : no of records update : count length : "+ count);
}

Step 2: add an application startup events using hook, add below entry to portal.properties


application.startup.events=com.aon.org.admin.util.OrgStaticDataStartUpAction

Step 3:


package com.test.org.admin.util;

import com.test.org.management.service.OrgTypeLocalServiceUtil;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.kernel.events.SimpleAction;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.model.ListType;
import com.liferay.portal.service.ListTypeServiceUtil;

import java.util.List;

public class OrgStaticDataStartUpAction extends SimpleAction {

@Override
public void run(String[] ids) throws ActionException {
// get types
List types = null;

try {
types = ListTypeServiceUtil.getListTypes("com.liferay.portal.model.Organization.address");

boolean recordsExists = true;
for (ListType listType : types) { // need to check for our custom values local & global if not add
if(!"local-client-address2".equalsIgnoreCase(listType.getName()) && !"global-client-address".equalsIgnoreCase(listType.getName()) ){
continue;
}else{
recordsExists = false;
}
}

if(!recordsExists){
LOGGER.info("Record not exists: starting insert");
OrgTypeLocalServiceUtil.insertStaticData();
LOGGER.info("Record not exists: end insert");
}
}
catch (Exception e) {
//type = new ListTypeImpl();

LOGGER.warn(e);
}
}

private static final Log LOGGER = LogFactoryUtil.getLog(OrgStaticDataStartUpAction.class);

}

Hope this will be helpful to some people. Blogging after long time - cheers :)

Wednesday, November 30, 2011

How to access custom portlet services in velocity template

By default we will have following property which won't allow us to use serviceLocator variable in velocity templates.

    #
    # Input a comma delimited list of variables which are restricted from the
    # context in Velocity based Journal templates.
    #
    journal.template.velocity.restricted.variables=serviceLocator


In order to access you need to change that property as below


journal.template.velocity.restricted.variables=


Default findServce(serviceName)  method (what we normally use) searches @ portal level where as other one with extra parameter as shown here  findService(servletContextName, serviceName) searches @ particular portlet level

TO add more to it here are the method signatures & implementations in ServiceLocator.java

        public Object findService(String serviceName) {
                Object bean = null;

                try {
                        bean = PortalBeanLocatorUtil.locate(_getServiceName(serviceName));
                }
                catch (Exception e) {
                        _log.error(e, e);
                }

                return bean;
        }


        public Object findService(String servletContextName, String serviceName) {
                Object bean = null;

                try {
                        bean = PortletBeanLocatorUtil.locate(
                                servletContextName, _getServiceName(serviceName));
                }
                catch (Exception e) {
                        _log.error(e, e);
                }

                return bean;
        }



HoW tO uSe


Suppose i have an custom Entity named MyEntity(defined through service.xml)


#set ($myEntityService = $serviceLocator.findService("", "com.rnd.common.portlet.service.MyEntityLocalService"))


I have a column named count under MyEntity, i can access as below


#set ($count =$myEntityService.getCount())


$count 


Hope that helps :)


Please feel free to add your comments. Cheers

Tuesday, November 29, 2011

How to open HSQL DB tables of Liferay in eclipse


Earlier i blogged about how to connect to HSQL DB from command prompt using HSQL Database Manager. Now as per request i have blogged to connect to HSQL DB form Eclipse

> Open Data source explorer in Eclipse

> Right click on Database Connections > New, you see screen looking like below as shown in Figure.1

> Type hsql as showing screen below & select HSQLDB - Give a name to your DB connection

Figure.1



> Do as described in Figure.2 below(Point to a Liferay DB which is using HSQL)

Figure.2
> You will see screen like below in Figure.3, once done close this window

Figure.3
NOTE : Here jar file you will using should point to the hsql.jar you have for Liferay installation under tomcat/lib/ext (Below is the screen shot for the same)





> Now you have to give proper Liferay DB name & Database location - Give DB connection other will be populated automatically. Check the save password check box. In my case DB location is

D:\projects\liferay\lr52sp3\liferay-portal-5.2-ee-sp3\data\hsql\lportal

You change this path according to your Liferay instance DB running on HSQL


> You can test the connection as show below


 > Click on Next from above screen, you see below screen check for connection profile & click finish


> You will be redirect to Datasource Explorer, which looks like below




Please feel free to add comments.

Cheers :)

How to open HSQL DB tables of Liferay

Some times we may need come across vague where we have to check few things immediately. Need to make some new version of Liferay up & running quickly, have to check DB for reference

As we all know default DB that Liferay uses in HSQL DB.

Here are the quick steps to how to open HSQL DB table entries in Liferay


Step 1: Download HQSLDB from http://hsqldb.org. Extract into some folder (eg. D:\hsqldb)

Step 2: You can use the HSQLDB DatabaseManager to view this database. Run the following from the command line to invoke the tool.

    java -cp D:\hsqldb\lib\hsqldb.jar org.hsqldb.util.DatabaseManager

    In the "Connect" dialog, select the following options:
    Type: HSQL Database Engine Server
    Driver: org.hsqldb.jdbcDriver
    URL: jdbc:hsqldb: (In my case i have my Liferay installation @ D:\projects\liferay\lr523\liferay-portal-5.2.3\data\hsql so i have to give path as jdbc:hsqldb:D:/projects/liferay/lr523/liferay-portal-5.2.3/data/hsql/lportal for URL)
    User: sa
    Password:

Please see the attached image for reference of settings we need to provide


That's it now you should be able to see all the tables. Database interface may not be quite intuitive as other commercial/open-source DB interfaces. Please check the below image for ref



UPDATE : Check the blog for how to connect to HSQL DB using Eclipse

http://btnkumar.blogspot.com/2011/11/how-to-open-hsql-db-tables-of-liferay_29.html

Please feel free to provide feedback if any

Cheers :)