Monday, April 27, 2009

Building Spring 3 working with Git

Until today, I've been keeping up on the Spring 3 development off the svn repository with svn. There is a great post by Chris Beams from SpringSource that provides adequate detail and is a great resource to read as a precursor to this post. In general, I'm moving all my development over to Git, and it was time to get Spring 3 inline. It was not without pain. For those who just want a quick reference, I will provide a quick step by step on how to achieve the end goal of setting up a git client to the spring 3 svn repository. Following that I will provide details for those who want a deeper understanding.

Quick Step-by-Step Spring 3 with Git
  1. In the directory you would like the spring project execute : "git svn clone --stdlayout https://src.springsource.org/svn/spring-framework"
  2. change directory to the newly created spring-framework directory
  3. copy forked script from github.com/kensipe named git-svn-clone-externals to the current directory; make executable and run.
  4. run "git svn show-ignore > .gitignore"
  5. run "git gc"
  6. from the current directory you'll need to create the following directories
  7. mkdir org.springframework.instrument/src/main/resources/
    mkdir org.springframework.instrument/src/main/resources/META-INF
    mkdir org.springframework.instrument.classloading/src/main/resources
    mkdir org.springframework.instrument.classloading/src/main/resources/META-INF
    mkdir org.springframework.asm/src
    mkdir org.springframework.asm/src/main
    mkdir org.springframework.asm/src/main/java
    mkdir org.springframework.core/src/main/resources
    mkdir org.springframework.core/src/main/resources/META-INF
    mkdir org.springframework.expression/src/main/resources
    mkdir org.springframework.expression/src/main/resources/META-INF
    mkdir org.springframework.web/src/main/resources
    mkdir org.springframework.web/src/main/resources/META-INF
    mkdir org.springframework.orm/src/main/resources
    mkdir org.springframework.orm/src/main/resources/META-INF
    mkdir org.springframework.context.support/src/main/resources
    mkdir org.springframework.context.support/src/main/resources/META-INF
    mkdir org.springframework.web.portlet/src/main/resources
    mkdir org.springframework.web.portlet/src/main/resources/META-INF
    mkdir org.springframework.test/src/main/resources
    mkdir org.springframework.test/src/main/resources/META-INF
    mkdir org.springframework.integration-tests/src/main
    mkdir org.springframework.integration-tests/src/main/java
    mkdir org.springframework.integration-tests/src/main/resources
    mkdir org.springframework.integration-tests/src/main/resources/META-INF
    mkdir org.springframework.instrument/src/test/java
    mkdir org.springframework.instrument.classloading/src/test/java
    mkdir org.springframework.asm/src/test
    mkdir org.springframework.asm/src/test/java
    mkdir org.springframework.aspects/src/test/java

  8. export ANT_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
  9. change directory to "build-spring-framework" directory
  10. run "ant"
  11. wait 20 minutes :)
The background and detail
The first line is standard git-svn to get the repository. If you are new to Git, this will take a few minutes long then a standard svn checkout. It is copying all the changes throughout history to your local .git repo. Fortunately spring 3 is still young from a history standpoint.

svn external - The first issue
The first thing to note is that part of the build process for spring 3 is a project which is added to this svn project as an external, which led me to this post on why svn externals are evil :) evil or not we have to deal with them. This led to a post by Alieniloquent which has some good explanations, followed by what I eventually settled on, a post by Andre Pang, which includes a script he created, which I forked off github. Kudos to Andre!! The script he created (which I can see using again the future), provides a one execution solution to what Alieniloquent blogged. It is beautifully simple. The script provides the following:
  1. pulls down all the svn externals (spring 3 only has one)
  2. creates a symlink (mocking what svn would have done)
  3. adds the symlink and the .git_externals directory to the excludes file
If you wanted to check your svn externals for other projects use the following command: "git svn propget svn:externals ." in the root of the project directory.

The next step is to get all the svn ignores into the .gitignores file.

version control directory management - the next issue
The explanation behind this issue is that svn allows for and manages empty directories... git does not. git only manages content. There are a number of empty directories which the spring build files expects to be present for the build to succeed. This is based on a standardize build system and a lack of error handling in the build system. If I get some time, I'll send a patch to the springsource guys to fix this. At this time you will have to create all the directories listed.

jvm out of memory issues - the last issue
ant will run out of memory without these changes.... first you will run out of perm space, followed by heap. You may be able to get by with less; I didn't spend much time here. The standard defaults will fail.

Also if you need to update your master branch with git... "git svn rebase" will do the job!

I need to say thanks to those bloggers already noted and to fellow NFJS speaker Matthew McCollough.

Thursday, February 26, 2009

Justification for Functional Programming

It appears that this subject has caught fire in recent years. The interest in St. Louis has resulting in the Lamdba Lounge started by Alex Miller. (Great name by the way). I have started reading (but not finished) Programming Clojure by Stuart Halloway and Programming Scala by Venkat Subramaniam. Additionally I just finshed writing a 10 page article on an introduction to functional programming, which includes 4-5 page on F#. The article is for NFJS who holds the exclusive rights at this time, but I plan to provide a link to it or post it here in its entirity after 90 days.

I should point out that I am no expert in this space, but I have been developing professional for 15+ years with a variety of languages (C, C++, Java, C#, a little Ruby, Perl, Groovy). In the last 6 months I've been "playing" with Scala, Clojure and F#.

The reason for this post is this: http://groovy.dzone.com/news/why-functional-programming. This article has been sent to me a couple of times and has been on twitter several. At this point I will make public comments I made in an email response regarding this subject. The first two subjects were points made via email, which make sense to maintain for this blog post.

The Argument to have UI and DB Support
I don't get the ui / db argument. This indicates an all or nothing mentality, which I would hope the industry could get over. A griffon front-end to a java hibernate db access and clojure rules engine make sense to me. Many of the functional languages provide the ability to produce a UI or interact with the DB, however that isn't really important to me as you will see below, but there are good solutions out there where this isn't really a concern.

Functional Notations and Code Beauty
I may be in the minority... but I could care less for "beauty" of code, I'm interested in less code that adds the same or more value. FP adds several notations that provide a conciseness to code, which is a huge value add. As I was writing up an article on F#... I became frustrated with my other programming languages... for instance: why is a switch in Java/Groovy so limiting. Groovy makes it better... but it is still limiting as you compare it to discriminated unions and pattern matching F#.

Getting Functional Programming
People don't get it yet (referring to the nah sayers)... they are in the battle pits and are lacking the big picture vision. This year quad core laptops are expected to be more common. That trend isn't going to stop. The last decade was all about die size and memory. This next decade is all about cores. The need for concurrency tools is a must. The language trend may be slightly ahead of its time.

I'll post more on this subject in the future... I just felt it necessary to provide some response to the value of functional programming. Frankly I've barely scratch the surface of the value.

Tuesday, February 24, 2009

Java 7 on Mac OS X

This blog post is worthy of Retweeting:) http://infernus.org/2009/02/building-java-7-on-mac-os-x/

In 2 weeks when I hope I have time... I will be on this!

BTrace Fix on the Mac

The last blog post showed a work around for getting BTrace to work on a Mac, however as explained it fails when trying to probe Grails. I've been working with the BTrace developers and now have a solution. It will likely be some time before the next release. So for those who don't want to build from source, I put a drop on drop.io of a build.

Side notes:
1) It appears that all the scripts and assumptions for Java do not take in account the Mac. Groovy, Grails and previously BTrace all have references to a tools.jar in a place which is not correct on a Mac.
2) drop.io is new to me... and it appears worth the look. I will likely use drop.io in the future. Mostly for presention code drops. I like github for source references, but sometimes it is just quick and easy to tar or zip up what you have and drop it.
3) There is an interesting situation with BTrace which can be frustrating if you are not aware of it. If you have a failed BTrace session... such as a connection refused on the BTrace side, then it is not possible to BTrace it again with a fixed version of BTrace. You have to restart the application to be probed.

Sunday, February 22, 2009

Fixing BTrace on the Mac

Well it is time to fix another Java issue on the Mac... again... Sorry for the sarcasm. I love Java and Groovy and I love my MBP, but as already documented (on fixing Java Memory Tools and Java is a 2nd Class Citizen), these two don't get along as often as I would like. I thought for some crazy reason that I was the only one fighting this issue until all the comments from the fixing the tools article appeared. Glad to know, first that this blog is helpful to others, second that there are number of great people all over the world (offer drinks no less) and third that we are not alone in this fight.

BTrace and the issue
First... if you don't know what btrace is... you have to check it out. In the evolution of debugging tools for the jvm, it is the next big thing! Active in this space is A. Sundararajan, he has a couple of my favorite blogs, one on scripting btrace and another on jmx and btrace. Another great tutorial blog is by Igor Minar.

This blog isn't as much about btrace, as it is about fixing it on the mac. BTrace is new enough though, that it may require just a quick introduction. BTrace is a debugging tool, which injects "probes" (my term) into a running Java process. It is an open source option that has a high possibility of replacing Wily's Introscope. To be fair, Introscope provides a lot of extras which BTrace doesn't at this time... but Introscope is tens of thousands of dollars and BTrace is a free open source tool. I would be shaking in my boots if I was on the Wily team.

We will need to start a Java process in order to illustrate how it works (or in the case of the Mac... doesn't work). For the Java process look in the demo directory, there is a Java2D.jar. On the Mac it is located: /Developer/Examples/Java/JFC/Java2D. At the comand-line type: java -jar Java2D.jar. This will start up a Java process. To get it's pid at another command-line type: jps
If this is the only Java process running on your box, the pid with the jar notation is the pid you are interested in. If you want to be 100% certain type: jps -l . You'll get something like:
7897 sun.tools.jps.Jps
7838 Java2D.jar

Now in the btrace bin directory (I'm assuming you followed one of the referenced tutorials), for our example type: ./btrace 7838 ../samples/ThreadCounter.java . To which you will get:
Connection refused

In the terminal of the running Java process for the jar you would likely see:
btrace DEBUG: adding to boot classpath failed!
btrace DEBUG: java.util.zip.ZipException: error in opening zip file
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.(ZipFile.java:114)
at java.util.jar.JarFile.(JarFile.java:133)
at java.util.jar.JarFile.(JarFile.java:97)
at com.sun.btrace.agent.Main.main(Main.java:108)
at com.sun.btrace.agent.Main.agentmain(Main.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)

Yea... epic fail! That is BTrace failing on the mac. If you want more details, go to the btrace script and edit -Dcom.sun.btrace.debug=false to be true. This will indicate the following stacktrace:
btrace DEBUG: debugMode is true
btrace DEBUG: dumpClasses is true
btrace DEBUG: dumpDir is .
btrace DEBUG: probe descriptor path is .
btrace DEBUG: parsed command line arguments
btrace DEBUG: System ClassPath: /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/tools.jar
btrace DEBUG: adding to boot classpath failed!
btrace DEBUG: java.util.zip.ZipException: error in opening zip file
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.(ZipFile.java:114)
at java.util.jar.JarFile.(JarFile.java:133)
at java.util.jar.JarFile.(JarFile.java:97)
at com.sun.btrace.agent.Main.main(Main.java:108)
at com.sun.btrace.agent.Main.agentmain(Main.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)

The line just above the fail point... hmmm.... it is looking for a tools.jar in the $JAVA_HOME/lib directory. As already noted, Apple likes to slice and dice the JDK... In trying to understand the issue, I uncovered an article released by Apple which says there is no tools.jar file... no tools.jar file!!! It is a classes.jar file and to make it fun it isn't in the $JAVA_HOME/lib directory... no, it isn't even under a subdirectory of $JAVA_HOME... I can't even write that without frothing at the mouth. I could start a rant here... but I'm assuming I'm writing to the choir so to speak.

Fixing the Issue
I didn't spend a significant amount of time on it... but I didn't get this working by changing the btrace scripts... something is in the code. I have another recommendation towards the end that the script change wouldn't work for as well. So we are left currently with the following work around.

Take the classes.jar and copy it to the lib directory as tools.jar (argghhh!!!) but it works. To be more specific... /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar to /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/tools.jar. It is important to note that you have to be sudo to make this change and you will have to do this with each Java version you want this to work with. Let's hope that the next version of BTrace will be Mac friendly!

After you get that working... checkout visualvm with the BTrace plugin. It is great stuff and another reason that the script change alone is not a total solution.

Other Issues
OMG... I'm frick'n shaving the yak again... just as I'm getting ready to post this... I was about to trace a grails app. The changes described above, break Groovy and Grails. So pick one :) You can be Groovy or you can BTrace but you can't have both yet. I guess I'll begin digging through code and send a patch tonight...

Thursday, February 19, 2009

Speaking on the NFJS Tour 2009

I will be speaking at a number of shows with NFJS this year. Already scheduled is Milwaukee, St. Louis, Minneapolis, Boston, Seattle. I will likely be at Omaha, Atlanta, Denver, Columbus, and Raliegh. That's just the first several months :).

It is always around this time of the year I like to revisit my goals. Commitment comes easy around January of a new year. Around mid to end of Feb, is a good time to check to see which goals you are seriously committed to. One commitment, I've maintained for several years is a commitment to learning and a commitment to excellence. This is easier when surrounded with like-minded and committed individuals who help to hold you accountable. It isn't always easy... just worth it. That is one of the reasons I love NFJS. The caliber of the speakers are top notch and world class.

For some the economy will be a an easy excuse to not attend. Or perhaps an employer will not pay for it this year. What is clear to me is those with the skills and the networks will find it easiest to find the next opportunity. This is the time to pick up new skills. As a local venue, no show makes it easier or less expensive than NFJS.

See you there !

Friday, February 13, 2009

Intellij 8.1 with Git Support

Finally... a good java editor with good git support. I've been waiting for a long time (in internet time) for git integration in the editor. Download Intellij 8.1 for Git support.

I have a number of project demos which are already in Git. I expected that Intellij would just pick up on this fact... and it did not. I then created a new project, did a Git init from Intellij and all was good.

To get IDEA to recognize a project already in Git, under the Version Control menu, select Enable Version Control Integration, then Git.

So far... the Git integration is fantastic!!! Love it! Well done JetBrains!
Happy Coding