Thursday, July 23, 2009

Double in ActionScript, Java, and MS SQL

ActionScript 3

• There are three numeric data types in AS3: int, uint, and Number.
• They are not primitives because they can be instantiated using constructors.
• They are not "real" objects because they cannot be null, and they have default values:

myNumber:Number;
myNumber.toString(); // No NPE thrown

• Default value for type Number is NaN (not zero).

Java

• BlazeDS converts AS3 Number type to Java Double.
• NaN is idempotent of conversion:

NaN (Java) -> NaN (AS3) -> NaN (Java)

• null is not! Keep it in mind when you work with BlazeDS:

null (Java) -> 0 (AS3) -> 0.0 (Java)

If Java NaN doesn't have special meaning in your application, you can use it as a "replacement" for null in Java-Flex communication.

MS SQL

• Doesn't support NaN value for numeric columns.
• All NaN values should be replaced by null before saving entity in the database, otherwise you will get exception:

com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 24 (""): The supplied value is not a valid instance of data type real. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.

In my current project I'm using all three languages, and I have to convert NaN to null back and forth for every object:

NaN (AS3) <-> NaN (Java) <-> null (Java) <-> null (MS SQL)

So I created small utility class that replaces all JavaBean properties of particular type from one value to another:

ExtendedPropertyUtils.replacePropertyValue(myBean, Double.NaN, null);
ExtendedPropertyUtils.replacePropertyValue(myBean, null, Double.NaN);

Feel free to use it if you have the same problem.

Resources

• Feature request to Adobe to introduce nullable Number type.
• Other solutions for similar issues in BlazeDS.

Monday, July 20, 2009

Tom DeMarco on Software Engineering

Software development is inherently different from a natural science such as physics, and its metrics are accordingly much less precise in capturing the things they set out to describe.
...
Strict control is something that matters a lot on relatively useless projects and much less on useful projects. It suggests that the more you focus on control, the more likely you’re working on a project that’s striving to deliver something of relatively minor value.
To my mind, the question that’s much more important than how to control a software project is, why on earth are we doing so many projects that deliver such marginal value?
...
So, how do you manage a project without controlling it? Well, you manage the people and control the time and money. You say to your team leads, for example, “I have a finish date in mind, and I’m not even going to share it with you. When I come in one day and tell you the project will end in one week, you have to be ready to package up and deliver what you’ve got as the final product. Your job is to go about the project incrementally, adding pieces to the whole in the order of their relative value, and doing integration and documentation and acceptance testing incrementally as you go.”
...
For the past 40 years we’ve tortured ourselves over our inability to finish a software project on time and on budget. But this never should have been the supreme goal. The more important goal is transformation, creating software that changes the world or that transforms a company or how it does business.

read the whole article

Friday, July 17, 2009

Michael Feathers on Functional Programming

One of the things that seems like a rather pessimistic observation, but I think it's true to a degree, that the number of programmers who are able to or willing to think in a mathematically sophisticated way about code is relatively small, in comparison to the total population of programmers. I think that even though functional programming is becoming more popular, it is a bit of uphill battle for the industry and it may become just a very strong good niche tool for the people who are able to use it very well. I'm glad to see it's being brought up in prominence now, but I'm wondering if we'll ever see a day when everybody is doing work in functional programming. On the other hand, we got to the point where closures are becoming part of practically every programming language. It only took 30 years, so there is hope, I guess.

watch the interview

Thursday, July 16, 2009

Spring integration tests with mocked collaborators

Sometimes when you write integration tests that load Spring application context, you want to mock some collaborators just to verify that they've been called with correct data. This is a quite legitimate approach, but you have to keep in mind that Spring caches application contexts during the test execution. That means, after you replace a bean with a mock, all subsequent tests that share the same application context will use mocked instance instead of real one. That might cause tests to fail in very peculiar way. For example, test succeeds in Eclipse but fails in command line; you create new test and the old one starts failing, etc.

To fix the problem, you need to reload application context after every test that uses mocks. The best way to do this is to use @DirtiesContext annotation. In Spring 2.5 this was a method level annotation, but starting with Spring 3.0RC1 you can use it on the class level (thanks Spring!). So the rule of thumb is:

If you mock a bean in the Spring integration test, annotate the test class with @DirtiesContext

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:appclicationContext.xml"})
@DirtiesContext
public class IntegrationTest {

@Autowired
private Application application;

private Collaborator mockCollaborator;

@Before
public void setUp() {
mockCollaborator = mock(Collaborator.class);
application.setCollaborator(mockCollaborator);

}

@Test
public void collaborator_is_called_once() {
...
verify(mockCollaborator, times(1)).methodCall(...);
}
}

Resources

Source files for this post
• Spring annotations documentation
Class level @DirtiesContext annotation
• How to build Spring 3

Tuesday, July 07, 2009

Iteration Length

Iteration length in agile software development is the time between two consecutive customer feedbacks.

You can set up iteration length to 2 weeks in the JIRA, but if you meet your customer twice a year then your iteration length is 6 months. You can do iteration demo every 2 weeks, but if nobody except your manager sees the demo then your iteration length is not 2 weeks. You can even release some artifacts and change the version of your application every 2 weeks, but if your customer never tried to use your application then your iteration length is definitely not 2 weeks.

In general, without customer feedback there is no iteration. It's a cascade.

Monday, July 06, 2009

Tony Hoare: 50 Years with Legacy Code

Q: With your time in the computer science field, I'm guessing that you've seen some common trends, things that have remained consistent throughout time since 1960. What are those trends that have remained consistent and how do you think it will continue to the future?

A: I'm sorry to say it's the mistakes that remained consistent, not the virtues. The problems that afflicted us in the 1960s were the difficulty of predicting performance of large systems, the difficulty of discovering requirements, the difficulty of implementing code that was coherent across large-scale module boundaries. All of these things are still with us. I suppose I could say that even in 1960 living with legacy code was there. Dykstra once said that every day when he comes into work he thanks providence that he is not charged with the responsibility of living with legacy code - that's certainly still with us.

watch the interview

Friday, July 03, 2009

Collaborating Using git-svn

I like Git, and I'm using it everywhere. It gives you so much power that once you taste it, you won't want to come back to traditional source control systems. One of the Git benefits is collaboration friendliness. Git encourages collaboration, ideas exchange, and code review. If your team is using Git then you know how easy it is to share your code with your co-workers. But sometimes you are the only person in the team who uses Git, and everybody else is on Subversion. Don't worry, you still can share your ideas by means of git-svn tool, and here I want to show you how. The process is not as simple as native Git (via pull/push or patch/apply) but it's better than nothing.

Suppose you have an idea and you are eager to try it. You don't want to create a branch in Subversion because you don't know if your idea will work out, and committing all your crazy stuff in Subversion can easily pollute it. So you create a local Git branch and start working.

$ git checkout -b topic/great-idea

You code, test, git-add, git-commit, code, test, etc. At some point you see that your idea was great indeed and it's time to show the amazing results to your teammates. Now you need to "push" your Git branch to Subversion. To do this you have to create Subversion brunch first

$ svn copy http://svn.repo.path/project-name/trunk \
http://svn.repo.path/project-name/branches/great-idea \
-m "Created branch for my cool stuff"

Next step is to add this Subversion branch as a remote branch to Git configuration. Open .git/config file with a text editor. You should see something like this

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[svn-remote "svn"]
url = http://svn.repo.path
fetch = project-name/trunk:refs/remotes/trunk

If you built your Git repository by cloning Subversion repository (which you most likely did), you will have one or more svn-remote sections in this configuration file. You need to add another one for new Subversion branch.

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[svn-remote "svn"]
url = http://svn.repo.path
fetch = project-name/trunk:refs/remotes/trunk
[svn-remote "svn-great-idea"]
url = http://svn.repo.path
fetch = project-name/branches/great-idea:refs/remotes/great-idea

Next step is to fetch Subversion branch, but first you need to know revision number when this branch was created. Run this command

$ svn log --stop-on-copy http://svn.repo.path/project-name/branches/great-idea

You should get something like this:

------------------------------------------------------------------------
r2165 | andy | 2009-07-03 14:36:59 -0400 (Fri, 03 Jul 2009) | 1 line

Created branch for my cool stuff
------------------------------------------------------------------------

The first number of the output is what we are looking for:

$ git svn fetch svn-great-idea -r2165

Now you have the Subversion branch in you Git. If you run git branch -a command you will see "great-idea" branch in the list.

 master
* topic/great-idea
great-idea
trunk

You shouldn't work on remote branch, so let's create local one:

$ git branch svn-branch/great-idea remotes/great-idea

I put it in svn-branch namespace just to make it visually clear that this branch is in synch with Subversion. The next set of commands is a standard way to bring your work from one local branch to another. In our case: from initial topic/great-idea to svn-branch/great-idea

$ git rebase svn-branch/great-idea
$ git checkout svn-branch/great-idea
$ git rebase topic/great-idea

That's it. Now you are ready to commit your code to Subversion:

$ git svn dcommit

Done. As an option, you can delete initial branch because you have a Subversion backed copy of it:

$ git branch -D topic/great-idea

Resources

• Ian Boston's post explaining how to add Subversion branches to Git.