Wednesday, October 27, 2010

Continuous integration server with Hudson for Java, .NET and beyond.


Continuous Integration and Automated Build Environment...

We all know it's super awesome and we need to have this practice. The point of this post is simple. How to get hudson (very simple continuous integration server) up and running to checkout (from svn, git, etc) and build your java (maven, ant) or .net (nant) projects at light speed.

First download the hudson.war from http://hudson-ci.org/. You will need jre 1.5+ and ........that's it! No DB no configuration no nothing!!!! Hudson stores your setup under ~/.hudson in xml files but for all practical intents and purposes you don't need to worry about it.

start the embedded jetty by typing the following in your terminal:

java -jar hudson.war

This will start jetty at http://localhost:8080

Go to that URL in your browser. You should see something like this



Now if your using git you need to install the git plugin. Go to the nav bar on the left and then to manage hudson->manage plugins. Here you can install the git plugin (as well as the nant plugin if your working in .net).

Lastly, you create a new job. When you create a new job you can go to configure and fill out the easy to follow GUI form.

That's it!

Thursday, October 21, 2010

Goodbye MS Visual Studio & .NET, Hello Mono Stack + Lucid Lynx!

I'm originally from the MS world. Don't fault me it was the time that I grew up. My generation had pretty much grown up eating up MS products without any knowledge of anything else. So naturally while doing a CS undergrad I learned classic ASP and out of school started with .NET 1.1.

The last two or so years I've had the pleasure of working at a company that is solely open source. At first I hated it. Everything seemed soooo much harder. You had to configure this and configure that and I absolutely hated the linux command terminal. Little did I know it was my ignorance that made me hateful. Not before long, I fell in love with the terminal. Then I fell in love with Java and JEE. Open source simply fits the personalities of true developers better. I would of told present day me off 2 years ago, but it's true. MS creates inferior developers.

Anyway, recently I got a project that was .NET. I had heard of Mono before but I actually got a chance to work with it. Let me tell you that it's awesome!!! Sure it doesn't have all the bloat that VS has but that bloat is unnecessary anyway for most things I work on. It's faster than VS2008. NUnit hooks in beatifully, unlike the MS Test project that is super bloated and slow. It has all types of engineering goodies like LOC, Cyclomatic Complexity, etc.

Anyway for the full stack you gotta get:

1. Mono - Runtime
2. MonoDevelop - IDE
3. MonoDevelop-Nunit - NUnit integration for IDE
4. Nunit - Command line NUnit
5. NAnt - Build tool
6. XSP2 - Mini Web/App server for asp.net

If your on Ubuntu 10.04 follow these steps:

1. Add deb
http://badgerports.org lucid main
to
/etc/apt/sources.list
2. Run following commands

gpg --keyserver http://badgerports.org/directhex.ppa.asc --recv-keys 0E1FAD0C
gpg --export --armor 0E1FAD0C | sudo apt-key add -
sudo aptitude update
sudo aptitude install monodevelop
sudo aptitude install monodevelop-nunit
sudo aptitude install nunit
sudo aptitude install nant
sudo aptitude install mono-xsp2

That's it. I guarantee it'll be installed before you get through the first 5-10 minutes of VS2008 if you have good bandwidth.

Wednesday, September 15, 2010

Global Economy...Good or Evil?

Everyone's talked about it for a long time. Programmers have been scared that their jobs will soon be gone. Executives have been salivating at the thought of getting a super smart programmer for less than the US minimum wage. The globalization of software development. I had an interesting conversation about this with a colleague and friend yesterday and some interesting points came up. Free trade.

Generally speaking I believe most people think that free trade is a good thing. It promotes competition and as a result the quality of products. My friend, who shall remain unnamed =), believed that only good could come out of outsourcing. He looked at it from the perspective of pure scientific benefit. The more the competition is for skilled software professionals, the more skilled the profession of software development would naturally become. I can't say that I disagree with this in the slightest. However, this is looking at the issue from a simple, and in my opinion rather naive perspective...

It assumes that all things are equal. That all other aspects do not factor in. In my opinion nothing can be further than the truth. First, the concept of quality. Quality is hard to measure in software. Bugs are of course not related to quality but rather unintended behavior from a functional perspective. Quality, in software engineering, is more associated with non-functional requirements or quality attributes. These are the 'illities.' For example, scalability and modifiability are very highly dependent on the micro-architecture and detailed design of a system. The structure design. This, of course, disappears when a system is compiled. The outside world cannot tell the difference between a well architected system and a poorly architected system. This means that executives cannot tell the difference. They can 'feel' the difference in an indirect, ambiguous way somewhere down the line. What results from that 'feeling' is a rabbit hole in of itself! Either way the only people who understand this quality are technical people and what executive is going to listen to them! After all they could be just lying to save their jobs!

Another aspect is pay scale. Software professionals are highly skilled people. I would go as far as saying their among the elite of the skilled professions. They usually have BS and MS degrees from rigorous academic programs. As a result, they are usually well paid. In a global economy this gets skewed. 15-20K a year job in the states is typically a dead end job requiring no skills or education. However, this amount in a third world country is great!

Some would argue that this is the same as the outsourcing of traditional manufacturing that happened in the late 70's and 80's. I would argue that in spite of the superficial similarities of labor and reducing costs of labor this is very different. Engineering and Computer Science are disciplines and are critical to the growth of society. The US way of life is what has inspired such growth in these fields. When our way of life changes, and it inevitably will as a global economy means a global way of life, so will the growth in the fields.

So is global economy good or evil? I guess we will just have to wait and see...

Tuesday, September 14, 2010

Creating a "Fat Jar" using Maven

UPDATED 11/28/11 to use latest assembly plugin!

A while ago, before I really started playing with maven, I wanted to create a jar that would package up all the libraries it used and be a single entity that I could invoke. So some searches yielded the eclipse plugin "Fat Jar." This was all nice and great but how could one do this without eclipse? Well maven let's you do this rather easily. Check out the pom.xml file below


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.orphanware.mv</groupId>
    <artifactId>mv-session-mgr</artifactId>
    <packaging>jar</packaging>
    <version>1.1</version>
    <name>mv-session-mgr</name>
    <url>http://maven.apache.org</url>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <fork>true</fork>
                    <executable>/usr/lib/jvm/java-7-openjdk-amd64/bin/javac</executable>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                  
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>            
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.tiger</groupId>
            <artifactId>mvapi</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>

    </dependencies>
    
    
</project>



Of course the code above is for a project I was working on so don't pay too much attention to the specifics. The part we care about is the:

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                  
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


That is how it will package it into a jar with what you named the artifact and it will append the descriptorRef to it.

Now you can build it with

mvn package

Thats it!

Wednesday, August 25, 2010

Flex to Java to PDF with iText and Linear Algebra

So I had a project that required some graphics programing in Adobe Flex and for those graphics to be exported to a PDF and of course a much higher resolution to be used in print. To do this I used the iText library for Java! It truly is a great piece of software and it's free! I won't spend time here explaining how to program in ActionScript or Java or how to transfer data between the two. This also isn't a beginners tutorial on iText. There is a great book on iText. It's called iText in Action. What I'll spend time doing here is explain a bit about how matrices are handled in Flash, in Java and how we can use them to transfer graphics data from the flash player to a PDF.

First off, it would be a good idea to review transform matrices. Wikipedia has a great page on them http://en.wikipedia.org/wiki/Transformation_matrix

Next let's understand how ActionScript and Java treat matrices differently. Flash treats matrices like so:

| a c tx |
| b d ty |

Java on the other hand treats them like so:

| a b tx |
| c d ty |

Notice that the b and the c are swapped, which can pretty much drive you crazy if you don't know or don't catch it.....trust me...I know! So when you send your matrices from ActionScript to Java make sure to flip those two elements!

Now on to the fun part. Dealing with the different coordinate systems between Flash and PDF. Flash, like most graphics platforms, uses a top left Cartesian coordinate system. PDF, like most printing platforms, uses a bottom left Cartesian coordinate system. We need to apply some matrix magic to get our desired results. Let's say that we have converted the matrix from flash to be in the same order as the matrix in Java. One matrix will be sent from Flash representing translation, rotation, scale and skew. Skew, I didn't have to deal with in my project so it will not be covered in this post. If there is a demand for it however let me know and I'll look into it.

First thing we need to do to achieve our final AffineMatrix in Java is to factor out scale. We do that by using the following Trig Identity:

sin^2(theta) + cos^2(theta) = 1^2

If the scale is 1 (100%) then doing the math and taking the square root of the left side of this equation should give us 1. Likewise, if the scale is .8 then it will give us .8. We do this in our context by the following:

float xscale = (float) Math.sqrt(a*a + c*c) ;
float yscale = (float) Math.sqrt(b*b + d*d) ;


Then we find theta:

float theta = (float)Math.acos(a/xscale);
if( b < 0)
theta = 2f * (float) Math.PI - theta;
tx and ty do not have to be factor out, but they do need to be converted to points. For a 300 DPI resolution you could use the following method:
public static  float convertToPoints(float pixels)
{
float points = pixels/(300f/ 72f);
points = points*10;
points = Math.round(points);
points = (points/10);
return points;
}
So to get the tx and ty in points you do the following:
tx = convertToPoints( (float) tx   );
ty = convertToPoints((float) ty  );
Now for the creating creating and multiplying the matrices. In matrices the order of multiplication matters so first we are going to scale the object with the following:
AffineTransform stm = new AffineTransform();
stm.setToIdentity();
stm.scale(xscale, yscale);
Then we are going to translate the object to the top left so that are relative to the tx ty values and multiply it by the scale matrix that we created in the step before. Note that we find the y by subtracting the scaled object height from the total height of the PDF:
AffineTransform ztm = new AffineTransform();
ztm.setToIdentity();
ztm.translate(0, pdfHeight-(imageHeight*yscale);
ztm.concatenate(stm);
Next we create a matrix to translate the object to it's desination and multiply it by the matrix from the above step. Note that we translate with a negative ty since in a top left coordinate system positive goes down and in the bottom left coordinate system positive goes up!
AffineTransform ttm = new AffineTransform();
ttm.translate(tx, -ty);
ttm.concatenate(ztm);
Lastly we create a rotation transform and multiply it by the matrix in the previous step. Note that we use a specific AffineTransform method for rotating theta across an anchor point and that anchor point being the tx, ty that was applied to the last matrix:
AffineTransform rtm = new AffineTransform();
rtm.setToIdentity();
rtm.rotate(theta, ttm.getTranslateX(), ttm.getTranslateY()+(imageHeight*yscale));
rtm.concatenate(ttm);
That's it! Now call transform on your PdfContentByte instance and pass the last matrix above (rtm) to the method call before adding the object. Don't forget to wrap all the matrix multiplication in between the following:
PdfContentByteInstance.saveState();

...matrix stuff

PdfContentByteInstance.restoreState();


Drop me a line if there are any questions.

Saturday, July 31, 2010

Resurrection

So I revamped this blog. It's going to be catered more towards technology now. First post is goingto be about a command pattern framework for java that I co-authored. It's iskandar. Going to be working on the wiki for it. It's super light weight and it can be easily integrated with a DI framework such as spring and guice. More to come on that soon.