JournalVmUtil in Liferay 6.1

11 Jul

Disclaimer – Following is not the best or optimal solution. If you have better suggestion please write in comments

JournalVmUtil was present upto Liferay 5.2 and then deprecated in Liferay 6.0 and then completed removed in Liferay 6.1. If you are upgrading to 6.1 and make extensive use of JournalVmUtil you can do the following.

Extend VelocityTemplateParser.java. Following code example is just a sample. Feel free to add any pre-processing or post-processing as required

package com.myexamples.mypackage;

import com.liferay.portal.kernel.templateparser.TemplateNode;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portlet.journal.util.VelocityTemplateParser;

import java.util.List;

/**
 * @author parasjain
 */
public class MyVelocityTemplateParserImpl extends VelocityTemplateParser{
    public List getNodes(Element element) throws Exception {
        return getTemplateNodes(element);
    }
}

Now inject MyVelocityTemplateParserImpl in your velocity templates and just call getNodes method like this

#set( $articleTemplateNodes = $myVelocityTemplateParser.getNodes($articleXmlDocument.getRootElement()) )

No theme found for specified theme id abc_WAR_xyztheme

11 Jul

As far as my experience is concerned, this error means that your database is referring to theme which is not present. To make sure run the following commands

select distinct themeid from layout;
select distinct themeid from layoutset;

Now go to liferay’s Control Panel -> Plugin Configuration -> Theme Plugins tab and click on the theme in question. See the
Plugin ID of the theme. It should match what is there in layout and layoutset tables. If it doesn’t then you have to either change themeid or update database tables. If you happen to update DB don’t forget to restart or clear DB cache.

Changing Liferay Password in database

12 Jun

Note : Use caution while trying this for the production installation. For production, it’s better to use technics like “Forgot Password”

If you forget password for your local admin account in Liferay, then stop the server and run the following command

update user_ set passwordEncrypted=0, password_='mynewpassword', passwordReset=1 where userId=10196;

 

Where mynewpassword is your new password. Now restart the server. This time you should be able to login with your new password. As soon as you login, Liferay should prompt you for password change. Change your password and try to remember it this time ;)

How to set lower_case_table_names in MAMP

4 Nov

Environment – Mac OS X
I have struggled a little to set lower_case_table_names =2 for mysql using MAMP. I have unsuccessfully tried configuring /etc/my.cnf and ~/.my.cnf. Finally (with a little help) I found that they are setting this value in MAMP/bin/startMysql.sh . Location of this file might differ because in your version of MAMP.
My config file looks like this

# /bin/sh
/Applications/MAMP/Library/bin/mysqld_safe --port=3306 --socket=/Applications/MAMP/tmp/mysql/mysql.sock --lower_case_table_names=2 --pid-file=/Applications/MAMP/tmp/mysql/mysql.pid --log-error=/Applications/MAMP/logs/mysql_error_log &

Change this file to set it to required value. As you might have guessed, you can use the same approach to update other params like log-error location, or port number (port number can be changed from MAMP preferences too)

Luke – Incompatible format version: 2 expected 1 or lower

24 Feb

I was trying to analyze my Lucene index generated by Nutch and I was getting this error when I selected Lucene index directory

Incompatible format version: 2 expected 1 or lower
And on the console it had

org.apache.lucene.index.CorruptIndexException

I got away with this using latest Luke Jar (luke-all-1.0.1). You can download it from
http://code.google.com/p/luke/downloads/detail?name=lukeall-1.0.1.jar

generate-all No domain class found for.. error in grails

22 Jun

Short Story: Provide fully qualified domain class name(class name with the package) to the generate-all command

Long Story:

If you have recently moved from pre-1.3 to latest grails version(1.3.2 as of today) and suddenly you have started getting this error

No domain class found for name Book. Please try again and enter a valid domain class name

on generate-all command


grails generate-all Book

then don’t panic. As of grails-1.3.2, when you create a new domain class, it is generated in a package. For example, in my case my Book.groovy is generated under mylib package(mylib is the name of my application)

generate-all command requires you provide fully qualified class names. This is true for even older versions like 1.1.1.

Issue this command instead


grails generate-all mylib.Book

I wish they made this point clear in their documentation at http://grails.org/doc/latest/ref/Command%20Line/generate-all.html

Exact Target Client in Java

17 Jun

Disclaimer – Most of the code in this post are from the code samples provided by Exact Target. I have encountered little difficulties in using the code samples. Therefore I am writing this post to document how I made it work finally. Hope it helps.

Recently, We have implemented Grails/Java client for Exact Target .net webservices. We have use Axis 1.4 to generate the exact target client. ET provides very good samples and examples. Our implementation was derived from one of the sample project they have provided.

Important Note: Exact Target has released new version of webservices recently. If that is the case then this post may not be of much help. This post is based on the following environment. If your environment is different then YMMV.

Java 5+, Axis 1.4, Exact Target Partner API 1.0, Apache Ant

These are the steps we have followed

i) Create a new java project and have the structure similar to this

Few files to take note of.

  • build.xml
  • etframework.wsdl
  • Code generated by wsdl2java will be in src/com.exacttarget.wsdl.partnerapi package
  • com.exacttarget.samples.Axisv14.client.ClientTest is used to test the client and com.exacttarget.samples.Axisv14.client.PWCBHandler is the implementation of Password Callback Handler
  • jars in the lib folder . These jars may be required to make things work.
  • client_deploy.wsdd is used by the framework
  • Generated client jar will be put in dist/lib/ folder
  • Folder build/com will have the compiled classes.

Normal java project stuff. Shouldn’t be new to you!

Now let’s get our hands dirty

ii) Open the PWCBHandler.java and update your api username and password


/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.exacttarget.samples.Axisv14.client;

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

/**
 * Modified WSS4J callback handler to accept user and password information from properties file via ClientTest.
 * The original class from Apache required hard-coded values for this information. This class may be further
 * modified for production usage so that this information is fetched from any external store, such as a database.
 *
 * @author Erik Gfesser
 */
public class PWCBHandler implements CallbackHandler {
 public static String user = "myusername";
 public static String password = "mypassword";

 public void handle(Callback[] callbacks) throws IOException,
 UnsupportedCallbackException {

 for (int i = 0; i < callbacks.length; i++) {
 if (callbacks[i] instanceof WSPasswordCallback) {
 WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
 String id = pwcb.getIdentifer();
 if(user.equals(id)) {
 pwcb.setPassword(password);
 }
 } else {
 throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
 }
 }
 } //end method handle
} //end class PWCBHandler

For your reference here is how client_deploy.wsdd looks like

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
<globalConfiguration>
 <requestFlow>
 <handler type="java:org.apache.ws.axis.security.WSDoAllSender">
 <parameter name="action" value="UsernameToken"/>
 <parameter name="user" value="myuserid"/>
 <parameter name="passwordCallbackClass" value="com.exacttarget.samples.Axisv14.client.PWCBHandler"/>
 <parameter name="passwordType" value="PasswordText"/>
 </handler>
 </requestFlow>
</globalConfiguration>
</deployment>

And last but not the least, here is the build.xml

<project basedir=".">
 <property name="build.dir" value="build"/>
 <property name="lib.dir" value="lib"/>
 <property name="resources.dir" value="resources"/>
 <property name="src.dir" value="src"/>
 <property name="dist.dir" value="dist"/>

 <path id="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath">
 <fileset dir="${lib.dir}">
 <include name="*.jar"/>
 </fileset>
 </path>

 <path id="client.lib.classpath">
 <fileset dir="${dist.dir}/lib" >
 <include name="*.jar" />
 </fileset>
 </path>

 <target name="init">
 <mkdir dir="${build.dir}"/>
 <mkdir dir="${dist.dir}/lib"/>
 </target>

 <target name="generate.client" depends="init">
 <taskdef resource="axis-tasks.properties"
 classpathref="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath"/>
 <axis-wsdl2java url="${resources.dir}/META-INF/etframework.wsdl"
 output="${src.dir}"
 verbose="false"
 debug="false">
 <mapping namespace="http://exacttarget.com/wsdl/partnerAPI"
 package="com.exacttarget.wsdl.partnerapi" />
 </axis-wsdl2java>
 </target>

 <target name="compile.client">
 <javac destdir="${build.dir}"
 debug="true"
 failonerror="true">
 <src path="${src.dir}"/>
 <classpath refid="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath"/>
 </javac>
 <jar destfile="${dist.dir}/lib/mysample-exacttarget-client-1.0.jar"
 basedir="${build.dir}/">
 </jar>
 </target>

 <target name="generate.compile.client" depends="generate.client,compile.client"/>

 <target name="clean">
 <delete dir="${build.dir}"/>
 </target>
</project>

iii) Run ant generate.client to generate the client classes. This target uses wsdl2java to generate java code from wsdl. After
this target is successfully run you should see java classes under com.exacttarget.wsdl.partnerapi package

iii) Now you should try to test the generated client. We will make use of ClientTest.java for the same. Here is a part of ClientTest.java
I have. Again the basic templated was given by ET itself

package com.exacttarget.samples.Axisv14.client;

import java.io.FileInputStream;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.xml.rpc.ServiceException;

import org.apache.axis.EngineConfiguration;
import org.apache.axis.configuration.FileProvider;

import com.exacttarget.wsdl.partnerapi.APIObject;
import com.exacttarget.wsdl.partnerapi.Attribute;
import com.exacttarget.wsdl.partnerapi.CreateOptions;
import com.exacttarget.wsdl.partnerapi.CreateRequest;
import com.exacttarget.wsdl.partnerapi.CreateResponse;
import com.exacttarget.wsdl.partnerapi.CreateResult;
import com.exacttarget.wsdl.partnerapi.DefinitionRequestMsg;
import com.exacttarget.wsdl.partnerapi.DefinitionResponseMsg;
import com.exacttarget.wsdl.partnerapi.Email;
import com.exacttarget.wsdl.partnerapi.List;
import com.exacttarget.wsdl.partnerapi.ListSubscriber;
import com.exacttarget.wsdl.partnerapi.ObjectDefinition;
import com.exacttarget.wsdl.partnerapi.ObjectDefinitionRequest;
import com.exacttarget.wsdl.partnerapi.Owner;
import com.exacttarget.wsdl.partnerapi.PartnerAPI;
import com.exacttarget.wsdl.partnerapi.PartnerAPILocator;
import com.exacttarget.wsdl.partnerapi.RetrieveRequest;
import com.exacttarget.wsdl.partnerapi.RetrieveRequestMsg;
import com.exacttarget.wsdl.partnerapi.RetrieveResponseMsg;
import com.exacttarget.wsdl.partnerapi.Send;
import com.exacttarget.wsdl.partnerapi.SimpleFilterPart;
import com.exacttarget.wsdl.partnerapi.SimpleOperators;
import com.exacttarget.wsdl.partnerapi.Soap;
import com.exacttarget.wsdl.partnerapi.Subscriber;
import com.exacttarget.wsdl.partnerapi.TriggeredSend;
import com.exacttarget.wsdl.partnerapi.TriggeredSendCreateResult;
import com.exacttarget.wsdl.partnerapi.TriggeredSendDefinition;

/**
 * Example to show Axis 1.4 usage pattern as a client to invoke services from
 * ExactTarget Integration Framework Web Service API endpoint.
 *
 * @author Erik Gfesser
 */
public class ClientTest {
 static String user = null;
 static String password = null;
 static String clientWSDD = null;
 static String customerKey = null;
 static String validEmailAddress = null;
 static String validSubscriberKey = null;
 static String validFromAddress = null;
 static String validFromName = null;
 static String invalidEmailAddress = null;
 static String invalidSubscriberKey = null;
 static String invalidFromAddress = null;
 static String invalidFromName = null;

 public static void main(String[] args) throws ServiceException,
 RemoteException {
 EngineConfiguration config = new FileProvider(clientWSDD);

 // Create PartnerAPI stub with ExactTarget Web Service API endpoint and
 // Axis configuration
 PartnerAPI service = new PartnerAPILocator(config);
 Soap stub = service.getSoap();

 testET( stub );

 } // end method main
}

In the testET method you can use any one of the ET API method to test the connectivity to the ET is working or not.

iv) If it works then you can generate the ET jar using compile.client ant target and you may use this jar as ET client in your target projects.

Grails EHCache Settings

11 Jun

We have configured Ehcache as second level hibernate cache for our project. This post is for Grails 1.1.1 projects. In the later version of grails, the configuration can be little different. Here are the steps. (It is quite some time when I did the actual configuration. Let me know if I missed something)

i)

First of all we have put ehcache.xml in grails-app/conf directory. Our config file looks like this.  You may modify the config based on your preferences. To learn more about this settings go to http://ehcache.org/documentation/configuration.html


<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="ehcache.xsd">
 <defaultCache
    maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="3600"
    timeToLiveSeconds="3600"
    overflowToDisk="false"
    diskPersistent="false"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU"
 />

 <cache name="org.hibernate.cache.UpdateTimestampsCache"
        maxElementsInMemory="10000"
        timeToIdleSeconds="300"
 />

 <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="10000"
        timeToIdleSeconds="300"
 />

</ehcache>

ii) Modify the cache provider class in your DataSource.groovy to org.hibernate.cache.EhCacheProvider like this

hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='org.hibernate.cache.EhCacheProvider'
}

iii) Now to fine-tune your cache setting, go to individual domain classes for which you want to enable ehcache and add the following mapping closure with cache true

class Employee {
    String name
    ........
    ........
    static constraints = {
        ....
    }

    static mapping = {
        cache true
    }
}

iv) If you want your query to be cached, you can configure it similarly with cache true clause

		def employeeList = Employee.createCriteria().list() {
			or {
				......
			}
			order(".....", "...")
			cache true
		}

For further reading to to http://ehcache.org/documentation/grails.html

Where to keep log4j.properties in a Maven project?

11 Jun

By default, maven will pull your resources from /src/main/resources folder and put it in web-app/WEB-INF/classes folder. So for web based project the default location of lo4j.properties is /src/main/resources folder.

How to switch to INNODB database in mysql

8 Jun

MySQL support many storage engines. If you run the following command you can see all the storage engines supported by your mysql version.


show engines;

For the performance reasons MyISAM is the default storage engine.  In some cases, you might want to change this to different engine, like  InnoDB for transaction support etc.

There are couple of ways of doing it. I know three of them

1. Change my.cnf file.

MySQL reads from my.cnf to read the default configuration settings. This file is generally found in /etc/my.cnf or $USERHOME/.my.cnf in *nix/mac  or c:\ or installdirectory or windows directory in window. In my.cnf file have this configuration


[mysqld]
.........

.........
default-storage-engine = InnoDB

Also, have the following  lines or uncomment them if already present. Make sure the innodb_data_home_dir etc points to a valid location

# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = /usr/local/mysql/data/
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /usr/local/mysql/data/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

2. SET storage_engine=INNODB

If you want your storage engine changed to something else for just the current session you can run the following command

SET storage_engine=InnoDB

3. Use engine=INNODB per table

You can change the engine per table like this

CREATE TABLE employee (id INT) ENGINE = InnoDB;

or if you have existing table and you want to change the engine

ALTER TABLE employee ENGINE = InnoDB;
Follow

Get every new post delivered to your Inbox.