Wednesday, July 18, 2018

Ignoring gitignore and unstaged files?


How to exclude files from git without committing changes to gitignore?

Run into the annoying problem of git complaining about unstaged changes that you just cannot commit for whatever reason. A quick way to get around this issue is add those files/folders to .gitignore But then you need to commit that file as well. That's so painful, huh?

Alternative is to add these files to .git/info/exclude that allows to ignore files from being staged. Yay! Problem solved.
Refer here for a detailed excerpt.

Thursday, May 21, 2015

Maven compilation fails with issues in gmaven-plugin

I ran into a weird exception when compiling my maven project. This failed even when the project had no code or dependencies. Searching our dear google gave ridiculous results. But finally I found the solution.

Error:


[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.521s
[INFO] Finished at: Thu May 21 16:59:13 PDT 2015
[INFO] Final Memory: 12M/491M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.gmaven:gmaven-plugin:1.3:execute (calculate-srcroot) on project bigsky-ui-tests: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method java.io.File#<init>.
[ERROR] Cannot resolve which method to invoke for [null, class java.lang.String] due to overlapping prototypes between:
[ERROR] [class java.lang.String, class java.lang.String]
[ERROR] [class java.io.File, class java.lang.String]

[ERROR] -> [Help 1]


The error is pretty misleading. The solution to this is to check the parent reference in pom.xml

I had missed the pom reference in the below -

<parent>
<groupId>com.vmware</groupId>
<artifactId>bigsky</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../src/pom.xml</relativePath>                      <!-- Had not provided this -->
</parent>


Monday, May 13, 2013

Removing Ctrl-M in Linux files

I do not know much about Linux. I have worked on it whenever I get a chance and have written a few shell scripts. But yet, this is relatively unfamiliar territory for me. Recently I came across this issue when running my shell scripts - "/bin/bash^M: bad interpreter: No such file or directory". This message is pretty obvious and means that some 'not-so-obvious' characters are introduced in the file, leading to these errors.

This issue occurs normally when one tries to edit files in Windows (using some of those fancy editors) and then copy into a Linux machine. At least that's what I had done. The first time I used dos2unix command to get rid of these unseen (^M) characters. The second time I tried the same, I found that dos2unix utility was not installed in my machine. This drove me into finding alternative solutions and here's what I found.

Open the file in question using vi and try typing the following (after pressing 'Esc'). Once done save the file using Esc, :wq.

Solution 1:
:%s/{Ctrl-v}{Ctrl-m}//g
where {Ctrl-v} refers to pressing 'Ctrl' and 'V' at the same time. Likewise for {Ctrl-m}

Solution 2:
 :set ff=unix
 Note: This is the one that worked for me.

Solution 3:
%s/{Ctrl-M}\+$//


Friday, May 4, 2012

Time for dates?

In Java, there often comes a scenario where we need to compute difference between two timestamps. Time difference, date, can it get any easier than that? Well, it is not that straight forward as it sounds as with real life. Added to that Java has a dozen different classes - Date, Time, Calendar, DateTime, Timestamp. Here is one easy way of computing time difference between 2 timestamps represented by the Date object - 



public static String getTimeDifference(Date date1, Date date2)
   {
      long difference = date1.getTime() - date2.getTime();
      AppUtil.print("Date1:" + date1);
      AppUtil.print("Date2:" + date2);
      String timeDifference = "";
      difference = Math.abs(difference);
      AppUtil.print("Diff:" + difference);
      if(difference==0) {
         timeDifference = "-";
      } else {
        long hours = difference/(1000 * 60 * 60);
        long minutes = (difference / (1000 * 60)) % 60;
        long seconds = (difference / 1000) % 60 ;
        if(hours>0) {
           timeDifference+= (hours + " hours ");
           AppUtil.print("hrs:" + hours);
        }
        if(minutes>0) {
           timeDifference+= (minutes + " min ");
        }
        if(seconds>0) {
           timeDifference+= (seconds + " sec ");
        }
      }
      AppUtil.print("time:" + timeDifference);
      return timeDifference;
   }


Also, as it is often with dates, they get pretty fussy. Sometimes, we need to format them the way we want them. Especially when you are passing Date or Timestamp objects from database obtained via JDBC. So here goes an example to format dates/times - 


Date timeReference = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS").parse(endTime);



Monday, January 23, 2012

Tomcat tuning

I was facing this issue with my test clients where HTTP status code 501 was thrown intermittently. It turned out to be an issue with the client. That's when my dear friend suggested this could be due to performance issues in Tomcat. Here are some things I found out.

Memory related changes:

Normally the JVM allocates an initial size for the Java heap and that's it, if you need more than this amount of memory you will not get it. For this, we need to set the minimum/maximum size of the Java heap. This can be altered using the -Xms/-Xmx parameters in the Java arguments. This can be set in the Java tab of the Tomcat Monitor.

-Xms1024m
-Xmx8192m

Connector alterations:

There are 2 default connectors configured in Tomcat server.xml viz.
  1. HTTP Connector - listens on port 8080 for incoming HTTP requests. Needed for stand-alone operation.
  2. AJP Connector- listens on port 8007 for incoming AJP requests. Needed for web-server integration (out-of-process servlet integration). 
 A good option is to use Thread Pools in Connectors. Tomcat is a multi-threaded servlet container. This means that each request needs to be executed by some thread. Prior to Tomcat 3.2, the default was to create a new thread to serve each request that arrives. This behavior is problematic for loaded sites because:
  • Starting and stopping a thread for every request puts a needless burden on the operating system and the JVM.
  • It is hard to limit the resource consumption. If 300 requests arrive concurrently Tomcat will open 300 threads to serve them and allocate all the resources needed to serve all the 300 requests at the same time. This causes Tomcat to allocate much more resources (CPU, Memory, Descriptors) than it should and it can lead to low performance and even crashes if resources are exhausted.
The solution for these problems is to use a thread pool, which is the default for Tomcat 3.2. Servlet containers that are using a thread pool relieve themselves from directly managing their threads. Instead of allocating new threads; whenever they need a thread they ask for it from the pool, and when they are done, the thread is returned to the pool.
Example configuration:
<Connector executor="tomcatThreadPool" maxThreads="1000"
               minSpareThreads="50"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
               executor="tomcatThreadPool" maxThreads="1000"
               minSpareThreads="50" />

Tuesday, November 1, 2011

Prepopulating form in Struts

I learned quite a few things when revisited Struts after a long time. Thought I could share some of these.

The simplest way to prepopulate a form is to have an Action whose sole purpose is to populate an ActionForm and forward to the servlet or JSP to render that form back to the client. A separate Action would then be use to process the submitted form fields, by declaring an instance of the same form bean name.

Let us take a look at the following example. Note the following definitions from the struts-config.xml file:

<action name="testCycleForm" path="/getlaunchdetails" scope="request" type="launch.action.GetLaunchDetailsAction" validate="false">
   ...
</action>
<action name="testCycleForm" path="/starttestcycle" scope="request" type="launch.StartTestCycleAction" input="page.starttestcycle">
  ...
</action> 


Note the following in this approach:

  • Both actions use the same form bean.
  • When the /starttestcycle action is entered, the framework will have pre-created an empty form bean instance, and passed it to the execute() method. The setup action is free to pre-configure the values that will be displayed when the form is rendered, simply by setting the corresponding form bean properties.
One aspect to be aware is how you type-cast the form in the execute method of GetLaunchDetailsAction. The correct way is

TestCycleForm cycleForm = (TestCycleForm) form;

Typecasting of the following type would not yield the desired result.

TestCycleForm cycleForm = new TestCycleForm();
// Populate values
form = cycleForm;

As far as the JSP is concerned, all is required is the property field appropriately pointing to the fields in the bean.

A couple of pointers in this regard - 
  • In JSP, do not give the name attribute in the Struts html tags unless you want to be hindered with the "Cannot find xxx in any scope" issue.
  • Populating  html:select tags can be a bit tricky. Consider the following example
       <html:select property="OS">
        <html:option value="select">-- Select --</html:option>
        <html:option value="linux">Linux</html:option>     
        <html:option value="windows">Windows</html:option>
        <html:option value="mac">Mac</html:option>
    </html:select>

       If you were to pre-populate the value for OS prior to form load, as before all you need to do  is set the form in your Action1 (GetLaunchDetailsAction). Just ensure that the value assigned matches the one inside the value field defined in the JSP. Here, setOS("mac") would be the correct approach and not setOS("Mac").