Friday, 1 March 2013

Wednesday, 16 January 2013

MSN, skype & pidgin

If you have not heard, Microsoft are merging MSN & Skype and dropping the MSN IM tool in favour of skype.

After sometime in March you will have to stop using MSN and go to skype.

Part of this is merging your contacts from both apps. As a point of note you have to be logged in to to skype with your MSN account & then merge in the skype contacts & NOT the other way around.

Anyway that aside and back to the point of this post.
I have always hated the Microsoft front end to Messenger with all its adverts.
The skype GUI is OK but is not what I call clean. In the past I have used trillian or latterly pidgin. These great apps allow you to connect to all your different IM suppliers including MSN, Google Talk, Yahoo, AIM through one app. However until recently pidgin could not connect to skype.

Now it can. You do need skype installed & running as well as pidgin & you will always need skype running - a slight pain I know. You then need to install a skype plugin for pidgin .

I have not tried trillian & I am not sure what will happen after the March deadline but in the meantime I have my skype contacts through pidgin.

One note though there was a few interaction issues after installed the plugin with skype complaining about pidgin trying to connect but after a few stop/starts of pidgin & skype it is all good.

Wednesday, 21 November 2012

Tomcat 7.0.32, IE & javascript comments


UPDATE: this is fixed in 7.0.33


A funny one this & one that took a while to track down.
First off the bug does not show itself in firefox or chrome (proper browsers), just IE, but sadly we have to get them all to work.

My development system was running perfectly in all tested browsers but then my tester reported an issue where a page was just displaying a blank page.

We blamed the data, his version of IE, which was 8 & I am on IE 9.

Eventually we struck on the tomcat versions. I was running 7.0.29 & he was running what is currently the latest tomcat 7.0.32

So looking further I worked out that if I swapped over the jasper jars I could get 7.0.32 to work. The issue turns out to be the javascript comments. If there is an uneven number of dashes next to the percent then the page will fail.

 So this is good.
 <%-- a good javascript comment --%>;  

& this will fail
 <%--- a dodgy javascript copmment in tomcat 7.0.32 --%>  

clock changing - Is this a Long, Short or a Normal day

Time is always a thorn in the side of developers.

In my latest project I needed to know the number of hours in a day and I could find no easy method on existing classes to determine if the day was a clock change day. I thought the great Joda date time classes would have helped but I could not find the one I needed so I wrote this.

 public enum ClockChangeInfo {  
  LONG_DAY(90000000, 25), SHORT_DAY(82800000, 23), NORMAL_DAY(86400000, 24), INDETERMINATE(0, 0);  
  private int mMsecs;  
  private int mHrs;  
  private static final Map<Integer, ClockChangeInfo> MSEC = new HashMap<Integer, ClockChangeInfo>();  
  static {  
   for (ClockChangeInfo cci : values()) {  
    MSEC.put(new Integer(cci.mMsecs), cci);  
   }  
  }  
  ClockChangeInfo(int aMsecs, int aHrs) {  
   mMsecs = aMsecs;  
   mHrs = aHrs;  
  }  
  public int getHrs(ClockChangeInfo aCci) {  
   return aCci.mHrs;  
  }  
  public static ClockChangeInfo getDayType(DateMidnight dateToCheck) {  
   DateMidnight nextDay = dateToCheck.plusDays(1);  
   //this is a safe convert as it is only for day(n) - day(n-1)  
   Integer millis = (int)(nextDay.getMillis() - dateToCheck.getMillis());  
   ClockChangeInfo cci = MSEC.get(millis);  
   if (cci == null) {  
    return INDETERMINATE;  
   }  
   return cci;  
  }  
 }  

 public class ClockChangeUtil {  
  public static ClockChangeInfo getDayType(DateMidnight dateToCheck) {  
   return ClockChangeInfo.getDayType((dateToCheck));  
  }  
  public static int getNumHoursInDay(DateMidnight dateToCheck) {  
   ClockChangeInfo dayType = ClockChangeUtil.getDayType(dateToCheck);  
   return dayType.getHrs(dayType);  
  }  
  public static int getNumHalfHoursINMonthSoFar(DateMidnight dateToCheck) {  
   int numHours = 0;  
   int day = dateToCheck.getDayOfMonth();  
   if (day == 1) {  
    return 0;  
   }  
   DateMidnight dm = dateToCheck.minusDays(1);  
   do {  
    numHours += getNumHoursInDay(dm);  
    dm = dm.minusDays(1);  
    day--;  
   } while (day > 1);  
   return numHours * 2;  
  }  
 }  


and some test methods for it. NB these are UK based.


 public class ClockChangeUtilUnitTest  
 {  
  @Test  
  public void test_isLongDay() throws Exception  
  {  
   DateMidnight dm28 = new DateMidnight(2011, 10, 28);  
   DateMidnight dm29 = new DateMidnight(2011, 10, 29);  
   DateMidnight dm30 = new DateMidnight(2011, 10, 30);  
   DateMidnight dm31 = new DateMidnight(2011, 10, 31);   
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm28));  
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm29));  
   assertEquals(ClockChangeInfo.LONG_DAY, ClockChangeUtil.getDayType(dm30));  
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm31));  
  }  
  @Test  
  public void test_isShortDay() throws Exception  
  {  
   DateMidnight dm26 = new DateMidnight(2011, 3, 26);  
   DateMidnight dm27 = new DateMidnight(2011, 3, 27);  
   DateMidnight dm28 = new DateMidnight(2011, 3, 28);  
   DateMidnight dm29 = new DateMidnight(2011, 3, 29);  
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm26));  
   assertEquals(ClockChangeInfo.SHORT_DAY, ClockChangeUtil.getDayType(dm27));  
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm28));  
   assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm29));  
  }  
  @Test  
  public void testClockChange() throws Exception  
  {  
   long millisInANormalDay = 24 * 60 * 60 * 1000;  
   long millisInALongDay = 25 * 60 * 60 * 1000;  
   DateMidnight dm28 = new DateMidnight(2011, 10, 28);  
   DateMidnight dm29 = new DateMidnight(2011, 10, 29);  
   DateMidnight dm30 = new DateMidnight(2011, 10, 30);  
   DateMidnight dm31 = new DateMidnight(2011, 10, 31);  
   assertEquals(millisInANormalDay, dm29.getMillis() - dm28.getMillis());  
   assertEquals(millisInANormalDay, dm30.getMillis() - dm29.getMillis());  
   assertEquals(millisInALongDay, dm31.getMillis() - dm30.getMillis());  
   DateTime dt28 = new DateTime(dm28);  
   DateTime dt29 = new DateTime(dm29);  
   DateTime dt30 = new DateTime(dm30);  
   DateTime dt31 = new DateTime(dm31);  
   assertEquals(millisInANormalDay, dt29.getMillis() - dt28.getMillis());  
   assertEquals(millisInANormalDay, dt30.getMillis() - dt29.getMillis());  
   assertEquals(millisInALongDay, dt31.getMillis() - dt30.getMillis());  
   assertTrue(dt28.getZone().equals(dt29.getZone()));  
   assertTrue(dt28.getZone().equals(dt30.getZone()));  
   assertTrue(dt28.getZone().equals(dt31.getZone()));  
  }  
  @Test  
  public void test_getNumHoursInDay() throws Exception  
  {  
   DateMidnight dm26 = new DateMidnight(2011, 3, 26);  
   DateMidnight dm27 = new DateMidnight(2011, 3, 27);  
   DateMidnight dm28 = new DateMidnight(2011, 3, 28);  
   DateMidnight dm29 = new DateMidnight(2011, 3, 29);  
   assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm26));  
   assertEquals(23, ClockChangeUtil.getNumHoursInDay(dm27));  
   assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm28));  
   assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm29));  
  }  
 }  





Wednesday, 31 October 2012

sqlserver - conversion of a varchar data type to a datetime data type resulted in an out-of-range value

I have an app connecting to a microsoft sqlserver DB.

When I ran the app all was fine & when the tester ran the app it failed with the following Exception:


Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4853)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1781)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1034)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
at org.hibernate.loader.Loader.doQuery(Loader.java:825)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2542)
... 41 more


It took me ages to work out what the issue was until I noticed that I was connecting to the database as 'sa' & he was using the schema name.

There is a lot of info on the web about this issue concerning changing the systems Regional settings but that was not my issue. In this case the sqlserver user 'sa' had a Default language of 'English' and the schema user had a language of 'British English'. Changing the Default Language to 'English' solved the problem.



Friday, 22 June 2012

hibernate ClassCastException and Transcient methods

This is an interesting little problem I had.

I have a domain object that has a char(1) column in the database but this is not a boolean. It contains one of two characters 'N' or 'H'.

I mapped this as follows with a handy @Transcient method:

 @Column(name="NHH_HH_IND", nullable=false)
 @Length( max = 1 )
 @NotNull
 @Type(type="java.lang.String")
  public String getHalfHourlyIndicator()
  {
    return mHalfHourlyIndicator;
  }

  public void setHalfHourlyIndicator(String aHalfHourlyIndicator)
  {
    //Integer y = new Integer((String)aHalfHourlyIndicator);
    this.mHalfHourlyIndicator = aHalfHourlyIndicator;
  }
  @Transient
  public boolean isHalfHourlyIndicator()
  {
    if (getHalfHourlyIndicator().equals("H")) {
      return true;
    } else {
      return false;
    }
  }


However when trying to persist this I got a ClassCastException:


java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
at org.hibernate.type.descriptor.java.StringTypeDescriptor.unwrap(StringTypeDescriptor.java:40) at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:52)

But I had no Boolean objects that were not transcient.

The problem appears to be because the Transcient method has the same body IE 'HalfHourlyIndicator'


Changing this method name to something else solved the problem. This is what I ended up with.

 @Column(name="NHH_HH_IND", nullable=false)
 @Length( max = 1 )
 @NotNull
 @Type(type="java.lang.String")
  public String getHalfHourlyIndicator()
  {
    return mHalfHourlyIndicator;
  }

  public void setHalfHourlyIndicator(String aHalfHourlyIndicator)
  {
    //Integer y = new Integer((String)aHalfHourlyIndicator);
    this.mHalfHourlyIndicator = aHalfHourlyIndicator;
  }
  @Transient
  public boolean isHalfHourlyIndicatorAsBoolean()
  {
    if (getHalfHourlyIndicator().equals("H")) {
      return true;
    } else {
      return false;
    }
  }

Tuesday, 12 June 2012

Copying files in eclipse was failing & creating a Snippet.java

When trying to copy a file from one project to another instead of copying the file it creates a file Snippet.java with the file name inside a main method.

WTF?

I did not suss out when this started & I have struggled to solve the issue.
Today I sussed it with some help from the wonderful stackoverflow.

Bizarrely the cause was the Skype 'Click to Call' extension in Chrome.
The stackoverflow solution suggests an upgrade to the extension might fix it but as I do not use skype from my work PC I simply deleted the extension