Friday, February 27, 2009

Get Yesterday's Date [Scripting]

Here is a useful snippet that you can include in your shell scripts if you need to find out what the previous day's date was.

Perl code:

$secsInADay=86400;
@yest=localtime(time-86400);
$year=$yest[5]+1900;
$month=$yest[4]+1;
$day=$yest[3];
print "$year$month$day";
One-liner for Shell Scripts
YEST=`perl -w -e '@yest=localtime(time-86400);printf "%d%.2d%.2d",$yest[5]+1900,$yest[4]+1,$yest[3];'`
echo $YEST
To get Tomorrow's Date
TOM=`perl -w -e '@tom=localtime(time+86400);printf "%d%.2d%.2d",$tom[5]+1900,$tom[4]+1,$tom[3];'`
echo $TOM

Wednesday, February 25, 2009

Quick Maven Commands

Creating a Maven project
In order to create a new maven project called MyProject run the following command:
mvn archetype:create -DgroupId=fs.work -DartifactId=MyProject
This will create a new directory called MyProject with a pom.xml and the following tree structure:
MyProject
 |-->pom.xml
 |-->src
 |  |-->main
 |  |  |-->java
 |  |  |  |-->fs
 |  |  |  |  |-->work
 |  |  |  |  |  |-->App.java
 |  |-->test
 |  |  |-->java
 |  |  |  |-->fs
 |  |  |  |  |-->work
 |  |  |  |  |  |-->AppTest.java
The pom file looks like this:

  4.0.0
  fs.work
  MyProject
  jar
  1.0-SNAPSHOT
  MyProject
  http://maven.apache.org
  
    
      junit
      junit
      3.8.1
      test
    
  

Creating sub-modules
If you need to create sub-modules within your project, you need to change the packaging in the pom file (i.e. the "super" pom), to pom. Then, from within the MyProject directory issue the following commands to create sub-modules:
mvn archetype:create -DgroupId=fs.work -DartifactId=MyProjectWeb -Dpackaging=war
mvn archetype:create -DgroupId=fs.work -DartifactId=MyProjectModule1 -Dpackaging=jar
This creates the sub-modules and the directory tree now looks like this:
MyProject
 |-->pom.xml
 |-->src
 |  |-->main
 |  |  |-->java
 |  |  |  |-->fs
 |  |  |  |  |-->work
 |  |  |  |  |  |-->App.java
 |  |-->test
 |  |  |-->java
 |  |  |  |-->fs
 |  |  |  |  |-->work
 |  |  |  |  |  |-->AppTest.java
 |-->MyProjectModule1
 |  |-->pom.xml
 |  |-->src
 |  |  |-->main
 |  |  |  |-->java
 |  |  |  |  |-->fs
 |  |  |  |  |  |-->work
 |  |  |  |  |  |  |-->App.java
 |  |  |-->test
 |  |  |  |-->java
 |  |  |  |  |-->fs
 |  |  |  |  |  |-->work
 |  |  |  |  |  |  |-->AppTest.java
 |-->MyProjectWeb
 |  |-->pom.xml
 |  |-->src
 |  |  |-->main
 |  |  |  |-->java
 |  |  |  |  |-->fs
 |  |  |  |  |  |-->work
 |  |  |  |  |  |  |-->App.java
 |  |  |-->test
 |  |  |  |-->java
 |  |  |  |  |-->fs
 |  |  |  |  |  |-->work
 |  |  |  |  |  |  |-->AppTest.java
The pom file for MyProjectModule1 contains a reference to the parent and looks like this:

  
    MyProject
    fs.work
    1.0-SNAPSHOT
  
  4.0.0
  fs.work
  MyProjectModule1
  MyProjectModule1
  1.0-SNAPSHOT
  http://maven.apache.org
  
    
      junit
      junit
      3.8.1
      test
    
  

Deploying a jar to the repository
If you have a jar file called myarchive.jar which you want to upload to your maven repository, use the following command:
mvn deploy:deploy-file -Durl=scp://hostname/dir/to/maven -DrepositoryId=fs.repo -Dfile=myarchive.jar -DgroupId=fs.work -DartifactId=myarchive -Dversion=1.0 -Dpackaging=jar
This will create dir/to/maven/fs/work/myarchive/1.0/myarchive-1.0.jar in the maven repository.

Creating a dependency
To create a dependency on myarchive.jar, add the following dependency to your pom:


  fs.work
  myarchive
  1.0

Generating Eclipse .project and .classpath files
Use the following command:
mvn eclipse:eclipse
Skipping tests
To skip tests use the property maven.test.skip=true.
mvn -Dmaven.test.skip=true install
Release a project
Two commands must be invoked, in the following order:
mvn release:prepare
mvn release:perform
Other commands
mvn install
mvn clean
mvn compile
mvn jar:jar

Tuesday, February 24, 2009

Sending Date Objects Over RMI

Had a funny issue with java Dates today which had me tearing my hair out: I was sending a java.sql.Date from one machine to another, via RMI and then storing it into the database, but the date being stored was incorrect!

The flow of the system can be described as follows:

  • CalcServer running on host A gets a "date-string" e.g. 20090220 and converts it to a java.sql.Date object using a SimpleDateFormat("yyyyMMdd")
  • CalcServer then sends the java.sql.Date object to the ResultServer, running on host B, via RMI.
  • ResultServer stores the java.sql.Date object to a java.sql.Types.DATE column in my Oracle database.

BUT, when I query my database I see 19-FEB-2009, instead of 20-FEB-2009! What is going on?

After a lot of investigation I found out that host A and host B were in different regions; one in Frankfurt and the other in London. The CalcServer in Frankfurt converts "20090220" into a date of "Fri Feb 20 00:00:00 CET 2009". When the ResultServer in London, deserialises the date it gets "Thu Feb 19 23:00:00 GMT 2009" and hence 19-FEB-2009 is stored in the database.

I have now fixed this by sending the date-string (not the java.sql.Date object) to the ResultServer, which will then parse it into a java.sql.Date object for storage.

Here is sample code which can be used to serialise a date on one host and deserialise it on another.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class SerializationTest {

  public static void main(String[] args) throws Exception {

    final String yyyyMMdd = "20090220";
    final Date date = new SimpleDateFormat("yyyyMMdd").parse(yyyyMMdd);

    if (args.length != 1) {
      System.out.println("Usage SerializationTest S|D");
    }

    boolean serialise = false;
    if (args[0].equals("S")) {
      serialise = true;
    }
    else if (args[0].equals("D")) {
      serialise = false;
    }

    String filename = "date.ser";
    if (serialise) {
      // write the object to file
      FileOutputStream fos = new FileOutputStream(filename);
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      ObjectOutputStream outputStream = new ObjectOutputStream(bos);
      outputStream.writeObject(date);
      outputStream.flush();
      outputStream.close();

      System.out.println("Serialised: " + date);
    }
    else {
      FileInputStream fis = new FileInputStream(filename);
      BufferedInputStream bis = new BufferedInputStream(fis);
      ObjectInputStream inputStream = new ObjectInputStream(bis);
      Date outDate = (Date) inputStream.readObject();
      inputStream.close();

      // print the object
      System.out.println(outDate);
    }
  }
}
Link to Stack Overflow Question

Friday, February 20, 2009

Java Serialization Snippets

Object serialisation is the process of saving an object's state to a sequence of bytes. De-serialisation is the process of rebuilding the object from those bytes later.

The object to be serialised must implement the Serializable interface or inherit it. If you don't want fields in the object serialised mark them as transient.

Serializing an Object

//the object to serialize
Date date=new Date() ;

//the file to serialize to
String filename="date.ser";

//write the object to file
FileOutputStream fos=new FileOutputStream(filename);
BufferedOutputStream bos=new BufferedOutputStream(fos);
ObjectOutputStream outputStream=new ObjectOutputStream(bos);
outputStream.writeObject(date);
outputStream.flush();
outputStream.close();
De-Serializing an Object

//the file containing the serialized object
String filename="date.ser";

//read the object from the file
FileInputStream fis=new FileInputStream(filename);
BufferedInputStream bis=new BufferedInputStream(fis);
ObjectInputStream inputStream=new ObjectInputStream(bis);
Date date=(Date)inputStream.readObject();
inputStream.close();

//print the object
System.out.println(date);
Determining the Size of an Object
//the object to measure
Date date=new Date() ;

//write it out to a byte array
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(date);
oos.close();
byte[] ba=baos.toByteArray();
baos.close();

//print size
System.out.println(ba.length);
or you can serialize the object to a file and measure the size of the file.

Friday, February 13, 2009

Happy 1234567890!

The epoch timestamp just passed 1234567890 and I saw it change!

Epoch Time

The time has come.

Tonight, at exactly 23:31:30 UTC, Epoch Time will reach 1234567890! You can watch the countdown here: http://coolepochcountdown.com/

Epoch Time (or Unix Time) can be defined as the number of seconds elapsed since 1 January 1970 00:00:00, not counting leap seconds. It is widely used on many computing systems.

We had an interesting time at work today, coming up with programs in different languages to watch Epoch Time tick by. Here are some of them:

Shell

 while true; do date +%s; sleep 1; done
Perl
 perl -le 'while(true){print time();sleep 1;}'
Haskell
import System.Time
import System.Posix

main :: IO ()
main = do { TOD epoch _ <- getClockTime
       ; putStrLn $ show epoch
       ; threadDelay 1000000
       ; main }
Groovy
groovy -e "while(true){println(new Date().time);sleep(1000)}"
Python
python -c \
  "while True: import time;print time.time();time.sleep(1)"
Java
import java.util.Date;

public class EpochTime {
  public static void main(String[] args) {
    while (true) {
      System.out.println(new Date().getTime() / 1000);
      try {
        Thread.sleep(1000);
      }
      catch (InterruptedException ignore) {
      }
    }
  }
}
HTML
<HTML><body>
<script language="javascript">
if(document.all){
  setInterval(function(){
  time=parseInt(new Date().getTime()/1000);
  document.body.innerText=time;
  },1000);
} else{
  setInterval(function(){
  time=parseInt(new Date().getTime()/1000);
  document.body.textContent=time;
  },1000);
}
</script></body></HTML>

Can you think of any more?

Happy 1234567890 day!