Abhishek Tejpaul « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

Abhishek Tejpaul

http://www.IntelliGrape.com

An open-source and Agile enthusiast.

Posts by Abhishek Tejpaul:

  • Using git diff feature on Github

    07 Jun 2011 in System

    Hi Folks,

    Recently I came across a cool way to compare differences between two branches, two tags, or between two commits on Github. Many a times in our project we have to thoroughly see what has been a specific change in the code base before we push it on our production branch.

    Here is how you can view the differences in commits:

    On the Github, go to the Source view of your project. You will see a link named ‘Branch List’. Once the page opens you can see a list of all the remote branches. Hit on the Compare button in front of any of the available branches to see the difference between two branches.

    Now note the URL in the address bar. It should end with something like ‘…/compare/<x>…<y>’ where x and y are separated by three dots(…) and their values could be project’s branch names

    Isn’t it good?

    Well, Git’s (read about git diff) and Github’s goodness does not stop just here. Instead of branch names as the values of x and y, you can also put two different commit hashes or tag names to view the differences in the code-base. More so, the commit hashes do not have to belong to the same branch. So you can pretty much compare your code’s current snap-shot with any of its past snap-shot irrespective of branch or a tag or a commit hash.

    Hope this helps someone.

    Abhishek Tejpaul
    abhishek@intelligrape.com
    [IntelliGrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Fetching an old deleted file of a project using Git

    15 Nov 2010 in System

    Recently in one of my projects, I had to bring the content of old-forgotten-deleted file back to the application code base using Git. The problem took a ‘fancy’ turn as the path to the file was no more a valid path in Git as there had been a major refactorings in our project esp. renaming of the packages as well as the folder structure since the file in question was deleted.

    This is how I could see the deleted file (& its content) using the Git commands:

    1. First of all, we will try to get the revision number of the git commit which committed our deleted file.
    Type in, git log
    on your console at the location where you have cloned/forked your Git project. This command will show a all the commits that has been done since the start of the project.
    If you know at what period of time the deleted file was committed, you can use another flavor of git log command i.e.
    git log –before=”Oct 01 2010″, or,
    git log –after=”Oct 01 2010″
    If you have an idea about who all could have or have committed the deleted file, then you can also use another option provided by git log command i.e
    git log –author=”Author Name” or
    git log –author=authorId
    The commands above are self-explanatory.

    NOTE: The step above would be helpful only if your team has followed good practices such as putting appropriate and self-explanatory comments while committing. So like if you have deleted a file & the comment while committing specifies that in some way or other it would be really easy for you to find out the probable revision number of that old commit by seeing the logs.

    2. Now once we have the revision number, we can try using the

    git show 

    command to make sure that the deleted file was actually present in the commit. Type the following:

    git show --name-only <revisionNumber> 

    Once you see your sought-after file there, then you can see the contents of your file by typing

      git show <revisionNumber> 

    This command will show you the change-set and the content of the file. Now you can fetch or copy the code out of the deleted file and place it in your new code or create an entirely new file out of it.

    Hope this helps !!!

    Reference: http://cheat.errtheblog.com/s/git

    – Abhishek Tejpaul
    abhishek@intelligrape.com
    [IntelliGrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Passing parameters to sub-reports in Jasper

    15 Sep 2010 in Java tools

    In one of our recent project, we made quite a good use of Grails Jasper plugin (v-0.9.7) to generate reports in the form of PDFs and Excel sheets. The reports contain sub-reports, which in many cases, contain sub-reports again. The way to pass parameters to sub-reports at the deeper level is to use the following tag in the .jrxml file: <subreportParameter>

    In the Grails Jasper plugin, the Jasper controller searches for the “SUBREPORT_DIR” in the params when the request is forwarded to it. If it does not find any key named “SUBREPORT_DIR” in the params map, it initializes the variable SUBREPORT_DIR with the value of “jasperFilePath” i.e. the location where the Jasper’s .jasper and .jrxml files can be found. Now suppose you want to give seperate file location for your sub-reports, you can easily do this using the following code in the .jrxml file inside the tag:

    
       ...
    
      ...
    

    Note the value of “![CDATA[$P{SUBREPORT_DIR}]]” parameter can be passed as a parameter from the controller to the master report but afterwards you can make use of the tag to pass on the information to the subsequent sub-reports to any level.

    For more information on the jasper .jrxml tags, please visit the following link here: http://jasperforge.org/uploads/publish/jasperreportswebsite/trunk/schema.reference.html

    Hope this helps !!

    - Abhishek Tejpaul
    abhishek@intelligrape.com
    [IntelliGrape Software Pvt. Ltd]

    • Share/Bookmark
  • Grails Transactions using @Transactional annotations and Propagation.REQUIRES_NEW

    30 Jul 2010 in Database& Grails& Groovy

    Hi All,

    Here is how you can implement a new transaction in an already executing transaction in Grails which uses nothing but Spring framework’s Transaction mechanism as an underlying implementation. Spring provides @Transactional annotations to provide declarative transactions. We can use the same in our Grails project to achieve the transactional behavior.

    Here is the scenario: You have two domain classes named SecuredAccount and AccountCreationAttempt. You try to transactionally save the SecuredAccount object which in turn creates a AccountCreationAttempt object which writes to the database stating: “There is an attempt to create a new SecuredAccount at this time: <current date and time>”. Point to note here is that even if the creation of the new SecuredAccount object fails, the record must still be written to the database so that the Administrator can validate whether the attempt at the specific time was by a legitimate user or an attacker.

    Here is the code:

    import org.springframework.transaction.annotation.*
    Class MyService {
     
    static transactional = false
    def anotherService
     
    @Transactional
    def createSecuredAccount() {
    def securedAccount = new SecuredAccount(userId:"John")
    securedAccount.save(flush:true)
    anotherService.createAccountCreationAttempt()
    throw new RuntimeException("Error thrown in createSecuredAccount()")
    }
    }
    import org.springframework.transaction.annotation.*
    class AnotherService {
     
    static transactional = false
     
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    def createAccountCreationAttempt() {
    def accountCreationAttempt = new AccountCreationAttempt(logRemarks: "There is an attempt to create a new SecuredAccount at this time: {new Date()}")
    accountCreationAttempt.save(flush:true)
    }
    }

    Now in this scenario, AccountCreationAttempt object always gets persisted whether or not the transaction for creating SecuredAccount object fails.

    Here are few gotchas regarding the above transactions:

    1.) First of all, for Propagation.REQUIRES_NEW to work as intended, it has to be inside a new object i.e. a new service in our example. If we had put the createAccountCreationAttempt() method in the MyService there would be no new transaction spawned and even no log entry would be made. This is Spring’s proxy object implementation of transactions and you can read more about it here:

    http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations.

    Please pay special attention to the “NOTE” sub-section.This is what it states:

    “In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.”

    2.) Secondly, all the @Transactional methods should have a public visibility i.e. createSecuredAccount() and createAccountCreationAttempt() methods should be public methods, and not private or protected. This again is Spring’s @Transactional annotations implementation and you can read about it at the same link as provided above. Note the right side-bar titled “Method visibility and @Transactional“.

    Well, once you keep note of these gotchas I guess you are all set to make good use of @Transactional annotations and its full power.

    Cheers !!!

    - Abhishek Tejpaul
    abhishek@intelligrape.com
    [IntelliGrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Tomcat 6 in-memory session replication

    22 Jul 2010 in System

    Hi All,

    Here are the few basic steps that you need to follow in order to achieve the in-memory session replication between two or more Tomcat 6 instances.

    This blog refers the Apache Tomcat documentation as found here: http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html.
    The Tomcat documentation provides more detailed explanation of the Clustering concepts as well as the definition of tags, attributes etc. used in server.xml file.

    Step 1: Include the <distributable> tag in web.xml file i.e. you can simple write the following line in your deployment descriptor(i.e. web.xml):

     <distributable />

    Please read the following link to know more about this tag: http://wiki.metawerx.net/wiki/Web.xml.Distributable

    Step 2: Add the following lines of XML in the server.xml file inside the <Engine> element/tag:

    <Engine name="Catalina" defaultHost="localhost">
          <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                channelSendOptions="8">
                         <Manager className="org.apache.catalina.ha.session.DeltaManager"
                          expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>
                         <Channel className="org.apache.catalina.tribes.group.GroupChannel"> 
                                   <Membership className="org.apache.catalina.tribes.membership.McastService" 
                                   address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> 
                                  <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" 
                                     address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/>
                                   <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> 
                                                 <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> 
                                    </Sender>
                          <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                          <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
                      </Channel>
               <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> 
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> 
              <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" 
                       tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/"
                       watchEnabled="false"/> 
                       <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
                      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
         </Cluster>
     .
     .
     .
     .
     </Engine>

    Please note that there might be some other elements such as <Host>, <Realm> etc. inside the <Engine> element. Also, for each tomcat instance the value defined for the ‘port’ attribute of the <Receiver> tag must be unique.

    And, that’s all. You now have a basic session-replication in place. Your sessions are replicated amongst all the tomcat instances which are part of your cluster.

    NOTE: Please make sure if you make any changes to the “context.xml” file, you have to delete the following xml file located in the <TOMCAT_HOME>/conf/Catalina/localhost/{yourAppName}.xml. If you don’t delete this file, then your changes will be ignored and the settings defined in this file will take effect.

    Cheers!!!

    Abhishek Tejpaul
    abhishek@intelligrape.com
    [Intelligrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Tomcat 6 Session Persistence through JDBCStore

    21 Jul 2010 in Database& System

    In one of our recent projects, we needed to save the HTTP session in the database.
    This blog refers the Apache documentation as found here: http://tomcat.apache.org/tomcat-6.0-doc/config/manager.html

    These are the following steps that need to be followed:

    Step 1: Create a database named tomcat (as shown in our example in Step 3 below) or any other name as specified in the ‘connectionURL’ attribute of the <Store> element.

    Step 2: Create the following table in the newly created database:

    create table sessions (
    session_id     varchar(100) not null primary key,
    valid_session  char(1) not null,
    max_inactive   int not null,
    last_access    bigint not null,
    app_name       varchar(255),
    session_data   mediumblob,
    KEY kapp_name(app_name)
    );
    

    Step 3: Copy the context.xml file available at the global level at this location: <TOMCAT_HOME>/conf to your application’s META-INF folder and replace the <Manager> element with the following:

    <Manager className='org.apache.catalina.session.PersistentManager'
     saveOnRestart='false' minIdelSwap='0' maxIdleSwap='0'  maxIdleBackup='1'> 
    <Store className="org.apache.catalina.session.JDBCStore" 
    driverName="com.mysql.jdbc.Driver"
    connectionURL="jdbc:mysql://localhost/tomcat?user=username&amp;password=password" 
    sessionTable="sessions" 
    sessionIdCol="session_id"
    sessionDataCol="session_data"
    sessionValidCol="valid_session" 
    sessionMaxInactiveCol="max_inactive"
    sessionLastAccessedCol="last_access"
    sessionAppCol='app_name' />
     </Manager>

    If these settings are placed in the ‘<TOMCAT_HOME>/conf/context.xml‘, it will have a global effect on all the applications running on the server. For an application specific setting, you can place a newly created “context.xml” file in the <APP_HOME>/META-INF sub-folder inside the webapps folder.
    Please note that attributes used in the <Store> element make use of the table columns as created in the database in Step 2.

    Step 4: Set the following system properties named – ‘org.apache.catalina.session.StandardSession.ACTIVITY_CHECK‘ to ‘true‘.
    For further information on this, read the ‘Persistent Manager Implementation’ section at this link : http://tomcat.apache.org/tomcat-6.0-doc/config/manager.html

    Step 5: Make sure you have placed the MySql jar in the <TOMCAT_HOME>/lib folder.

    Now you can try to hit the application’s URL and check the database table to see the newly persisted session. Please note that it takes around 60 seconds to see the stored session in the database so you might have to wait a bit. You can have multiple instances of tomcat running your application pointing to the same database and can share this persisted session in case any of the tomcat instance crashes.

    Cheers!!!

    Abhishek & Imran

    abhishek@intelligrape.com | imran@intelligrape.com

    [Intelligrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Finding User’s Session Locale in GSP

    14 Jul 2010 in Grails& HTML-UI-CSS

    There are situations where you might want to know the Locale of the user as set in the session in your GSP so that you can show text in a particular language/manner. Here the Spring framework’s SessionLocaleResolver can come to the rescue. In one of our recent Grails projects, we did the following in one of our GSPs to display the content accordingly.

    Please note that our use-case was like that in which we have fields for different languages in our domain classes. For example:

    class MyDomain {
    String greetingEnglish
    String greetingFrench
    }

    And now you have to conditionally display the object’s fields based on the user’s locale. If this were a static text, then the Grails in-built i18n support in the form of message bundles would be the ideal solution. But this is a different scenario.

    So let’s start by writing the following in your GSP :

    <g:set var="lang" value="${session.'org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'}"/>

    The above statement returns the ISO Language Code from the session object which is a map. In Grails, the map values can be retrieved by the ‘.’ operator too by passing the keys. These codes are the lower-case, two-letter codes as defined by ISO-639. For example: ‘en’ for English, ‘fr’ for French and so on.

    Once you know the locale, you can show the conditional content on your page. It could be something like this:

    <g:if test="${lang.startsWith('en')}">
    <h1> ${myDomainobject.greetingEnglish} </h1>
    </g:if>
    <g:elseif test="${lang.startsWith('fr')}">
    <h1> ${myDomainobject.greetingFrench}</h1>
    </g:elseif>
    <g:else>
    <h1> Default Greeting </h1>
    </g:else>

    Hope this will help !!!

    - Abhishek Tejpaul

    [Intelligrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Configuring multiple senders in Grails Mail plugin

    14 Jun 2010 in Grails& Java tools& Plugin

    In one of the recent projects, we had to set up a system where emails for different purposes (i.e registration, error reporting etc.) were to be sent out from different email accounts. We were using the Grails Mail plugin which does not provide a clear way to set-up or configure multiple email addresses. With the help of my colleague, Chandan Luthra, I tried to dig into the workings of plugin and found out that Mail plugin injects the properties such as username, password etc. through a bean named mailSender. So we just did the following to customize/configure these properties on the fly from the controller or a service:

    CH.config.grails.mail.default.from = "username@domain.com" // Mail plugin uses this to connect to the account in e-mail provider's server. So it should be set.
    mailSender.username = "username@domain.com"
    mailSender.password = "sample123!"

    And yes, once you are done with your email sending functionality you can set mailSender properties back to the default settings set originally in Config.groovy. Your service/controller code could look something like this:

    // Store the default mail settings in variables
    def defaultFrom = CH.config.grails.mail.default.from
    String oldUsername = mailSender.username
    String oldPassword = mailSender.password
    
    // Change the properties here; send the email
    try {
    CH.config.grails.mail.default.from = "username@domain.com"
    mailSender.username = "username@domain.com"
    mailSender.password = "sample123!"
    mailService.sendMail {
    to(['exampple1@domain1.com', 'example2@domain2.com'].toArray())
    subject("Example Subject")
    body("Sample body")
    }
    }
    catch (Exception e) {
    // catch block code
    }
    // Set the original settings back
    finally {
    CH.config.grails.mail.default.from = defaultFrom
    mailSender.username = oldUsername
    mailSender.password = oldPassword
    }

    I guess this scenario can be quite prevalent in many projects. Hope you find the blog useful.

    - Abhishek Tejpaul

    Intelligrape Software Pvt. Ltd.

    [www.intelligrape.com]

    • Share/Bookmark
  • Vi Editor

    14 May 2010 in Linux

    I will try my best to give you some tips to make Vi look more interesting and easy to use for all you guys. I have read few articles and tutorials about Vi and will try to summarize some key points here.

    First things, first : WHAT IS Vi?

    Vi is NOT just an editor. It has evolved to be something more than just a plain text-editor with cool features. It can easily be an IDE for programmers (but only after you become an expert in Vi). But before going into how Vi can help you in technical terms, I would like to emphasize about how to ‘let go’ of the fear of using a Vi editor.

    Vi is your friend. An interesting friend. Only you have to know its language (read commands). The good thing about Vi is that it lets you perform create, edit, delete, save, find, count, select, copy/paste and so many other operations without forcing you to move your hands away from the home keys/home row (and yes, I am talking about the home keys of ‘Touch Typing’ fame). Just with a single keystroke or a combination of few keystrokes you can literally achieve anything you want to do while text-editing your documents or coding a super-cool program and that too all in a comfort of your keyboard and nice placement of your hands.

    The learning curve is steep, I agree but the ROI is steeper. It is more about how you see Vi. A capable editor or a demanding one. I read few articles; used it a little bit and am convinced that it is a capable editor.

    Let’s start with the basics now:

    Let’s DO away with mouse. I WANNA move around through the keyboard.

    The home keys, again !!! Hit h,j,k,l – to move left, down, up, and right respectively.
    A nice tip to remember the movement keys :

    h is on the left – so left it goes,

    l is on the right – so right it goes,

    j looks like a down arrow key – so down it goes,

    k  (well the only way to go now is UP) – so up it goes.

    If you have a photographic memory, this picture might help you. This is an ADM3A terminal, the type of machine used originally by Bill Joy (the creator of Vi) to code the C shell on which Vi runs. This could be the reason why h,j,k,l are movement keys.

    The modes in Vi : Command mode and Insert mode.

    The name says it all. In the Command mode, Vi waits for your commands i.e. the keystrokes to let you copy, move, replace, delete, change, go to a particular line/word etc. The good thing about Vi is it gives you different ways to achieve the same thing. You want to go end of current line: you can achieve that in different ways

    Way 1 – Pressing l (the small L) again and again till you reach end of line.

    Way 2 – Press e (command to go to end of the word) again and again till you reach your destination.

    Way 3 -  Press f (command to find a character) followed by the character (which is the last character of your line) again and again to reach the end of line.

    Example: “This is a sample line.”

    Now, to reach the end of this line(assuming your cursor is somewhere on the line) all you have to do is press ‘f’ followed by ‘.’  since ‘.’ – period is the last character of your line.

    Way 4 – Just hit the dollar sign i.e. ‘$’.

    And this list is still not exhaustive, I believe. The more familiar you will become with Vi the more ways you will have to achieve the things. Some smarter ways, some dumber ways. But they all will get the job done.

    The second mode is the Insert mode. In this mode, the Vi takes a back seat (to say so) and lets you  modify the contents of your document the way you want to. It is the normal text edit mode that we work on while using Notepad, Wordpad, MS Word, gedit and so on.

    Well, the good place to start learning Vi is vimtutor. Open the shell(terminal) for Linux, type in ‘vimtutor’ and ‘get going’ !! It is an interactive tutorial which lets you practice while you learn.

    On the ending note, I wish you all good time with Vi and will try to continue writing more about Vi editor in the future blogs.

    - Abhishek

    [Intelligrape Software Pvt. Ltd.]

    • Share/Bookmark
  • Creating image thumbnails through Grails ImageTools plugin

    23 Mar 2010 in Grails& Java tools

    In one of the projects recently, we had to generate the thumbnails dynamically from the client-provided images. We decided to use the Grails plugin named: ImageTools. This is a very basic plugin but provided very quick and stable solution to our use-case. You can read more about the plugin and how to install it here .

    We decided to implement the solution in the form of a tag which gave us the ease to use it directly in a .gsp file. Here is how the code looked like in a taglib:

    import org.grails.plugins.imagetools.ImageTool  // Import the ImageTool class in your taglib.
    
    def thumbnail = { attrs ->;
    def imgSrc = attrs['imgSrc']  // as the name suggests - the image source
    def dimension = attrs['dimension'].toInteger()  //size of the image - giving 200 as a dimension gives you the thumbnail of around 200*200 in size.
    def imageTool = new ImageTool()
    imageTool.load(imgSrc)
    imageTool.square()
    imageTool.thumbnail(dimension)
    imageTool.writeResult(thumbnailLocation,"JPEG")  //thumbnailLocation - provides the path to where you want to store the thumbnail image.
    out << thumbnailLocation
    }
    

    This is all you need to create the thumbnail programatically through ImageTools plugin. The code above always creates the new thumbnail; we tried to improvise the above solution by saving the thumbnail in a folder and checking for the existence of the thumbnail before actually creating the thumbnail. This is how we achieved it:

    def thumbnail = {attrs ->;
    def imgSrc = attrs['imgSrc']
    def dimension = attrs['dimension'].toInteger()
    def thumbLocation = "/path/to/store/thumbnails"  + imgSrc
    def file
    
    // if thumbnail already exists, return the path to the image
    if((file =  new File(thumbLocation)).exists()){
    out << thumbLocation
    }
    else{
    // the code to generate the thumbnail comes here.
    }
    }
    

    Hope this helps.

    – Abhishek

    Intelligrape Software

    • Share/Bookmark