Posted by Joseph Nusairat
Thu, 20 Dec 2007 16:20:00 GMT
The long awaited news of Java 6 on Leopard has finally been announced, albeit with little fan fare.
Java 6 on Leopard
Apple has released the preview version; meaning a final version should be coming soon. While I find this to be great news for those of us who do Java development on the Mac, I find it intriguing by the fact that it makes special use of 64-bit architecture. However, it's that last part that worries me a bit. Apparently you HAVE to have a Core 2 Duo to use Java 6. So that means myself and two of my business partners Mac laptops will not be able to run Java 6. Now generally developers like to stay on the cutting edge at all times. But really, the Core duos are ONLY a year and a half old? That is NOT that old to have to upgrade.
I guess we shall have to see how desperate the Java developers who use the Mac are. There was a slight alternative right now as well. Someone has ported the unix JDK6 to the Mac with almost complete functionality. (the URL of the site escapes me right now but I will post it when I find it)
Posted in Java, Mac | no comments | no trackbacks
Posted by Joseph Nusairat
Mon, 10 Dec 2007 19:20:00 GMT
Every year brings with it new technologies, this year is of course is no different. One of the biggest changes I have seen this year (which did not really hit ‘till the end of the year) are some of the dynamic language features in Java, specifically Groovy.
Groovy has come a long way and with the 1.5 release over the weekend brings new meta-programming capabilities and better support for DSLs. All of this is supposed to help the Grails framework. And if you have used both you will really see the Ruby influence mixed with Java standards (there are of course many additions since this is a 1.5 release -from 1.0-.
The real power I see is with Groovy's being supported 100% in Grails (of course) and even in JBoss Seam. Besides Seam just being a good tool to bridge the gap between JSF and EJB3 it has quite a bit of support for ease of development when doing jBPM (JBoss' business process management system which can use Drools as part of its decision making process).
I think next year will be interesting to see if (now that the Java dynamic languages have reached good maturity) whether Groovy will really start to grow in the Java community. The NoFluffJustStuff tour has even branched off with a G2 (Groovy and Grails) tour as well.
At any rate, whether you are a Java, Ruby, or Python developer ... the exponential spread in popularity over the last 2 - 3 years of using dynamic languages via DSLs is great for the community. Let's see what 2008 brings.
Posted in Java, Seam, Groovy | no comments | no trackbacks
Posted by Brian Sam-Bodden
Fri, 07 Dec 2007 01:28:00 GMT

This installment was supposed to be about building the Dashboard page of the Tempo application. Instead, I'm addressing some bugs reported by readers.
Fixing Bugs TDD-style
An observant reader pointed out that one of the tests for the TimeEntry class broke when testing using a date range across a month boundary.
The offending code is shown below:
def split!
remaining_time_entries = []
if needs_splitting
original_end = self.end
self.end = self.start.change(:hour => 23, :min => 59, :sec => 59)
(self.start.day+1..original_end.day).each do |day|
time_entry = self.clone
time_entry.start = time_entry.start.change(:mday => day).beginning_of_day
if day == original_end.day
time_entry.end = original_end
else
time_entry.end = time_entry.start.change(:hour => 23, :min => 59, :sec => 59)
end
remaining_time_entries << time_entry
end
end
remaining_time_entries
end
Even though the code above was created in a TDD fashion and several of the tests created exercised the code, the tests failed to cover all of the possible cases.
The lesson here is that when dealing with date ranges, you should test across months and year boundaries. The code above only works when the two datetimes are in the same month and year which is a critical flaw. The code uses the day method to loop form the start day to the end day of the range. This will obviously break across months and of course across years.
One good thing about the test above was (as some might argue whether this is a good thing or not) is that I used a date range that started on the current date and time. In a continuous integration scenario this broken test would had revealed itself in the hourly build.
I've also made the same mistake (of using the day method) to check if a range of dates needed splitting, here's the original code:
def needs_splitting
self.start.day < self.end.day
end
First, let's prove that the code is indeed broken. To accomplish this I've written a test that crosses a month boundary:
it "should know how to split a time entry across multiple days over a month boundary" do
time_entry = create_time_entry
time_entry.start = Time.local(2007,"nov",30,23,0,0)
time_entry.end = 5.hours.since(time_entry.start)
entries = time_entry.split!
entries.should_not be_empty
total = 0.0
entries.inject(0) {|total, e| total += e.total_hours}
total += time_entry.total_hours
total.should eql(5.0)
time_entry.needs_splitting.should_not be_true
end
The above test fails with the existing code. Now we can refactor the code to pass the test.
def needs_splitting
(self.start.year != self.end.year) ||
(self.start.month != self.end.month) ||
(self.start.day != self.end.day)
end
def split!
remaining_time_entries = []
if needs_splitting
original_end = self.end
self.end = end_of_day(self.start)
days = ((original_end - self.start) / 86400).ceil.to_i
(1..days).each do |day|
time_entry = self.clone
time_entry.start = time_entry.start.advance(:days => day).beginning_of_day
time_entry.end = time_entry.end.advance(:days => day)
if same_day(time_entry.end, original_end)
time_entry.end = time_entry.end.change(:hour => original_end.hour, :min => original_end.min, :sec => original_end.sec)
else
time_entry.end = end_of_day(time_entry.start)
end
remaining_time_entries << time_entry
end
end
remaining_time_entries
end
The needs_splitting method now checks the year, month and day. The split! method now finds the total number of whole days (plus one) in the datetime range. It then creates new TimeEntry(s) for each of the whole days (24 hours each) and a partial one of the last day on the range. To advance each one of the days I use the advance method (see Rails extensions to the Time class).
Posted in Ruby, Rails | no comments | no trackbacks