Saturday, April 2, 2011

NSObject - description method

I believe that all Java Developers, using debugger from time to time, are appreciating toString method in Object class :) - probably the same feelings share all Objective-C Developers who know NSObject's description method.

In short, this method returns a string that represents the content of the receiving class, by default it is something like this:
<Card: 0x4b64c90>
Sounds mysterious for now, but when you override this method in your class (Card in this example), and make it look like this (face and value are properties of Card class):
- (NSString *) description {
    return [NSString stringWithFormat: @"face: %@, value: %d", self.face, self.value];
}
And then, in debugger, select Print / Description on the Card object:


You will see something like that:


The same method is used while you send the messages to the system log, using NSLog function:
NSLog(@"Card: %@", card);
Similar to the debugger Print / Description command, you'll see your object description in console when the NSLog will be reached in code.

Monday, March 21, 2011

Useless Flow Managed Persistence

Spring Webflow has some interesting feature called Flow Managed Persistence. In short: it allows you to change some persistent entity during the flow, and merge the state of entity into persistence context at the end of the flow.

Sounds interesting, and is worth trying for sure :) - but you have to be aware, that Spring Webflow guys have overlooked something very important. The JpaFlowExecutionListener, which is involved in the Flow Managed Persistence handling, binds an Entity Manager instance to the flow scope, when a flow execution starts.

So what? - you may say :) - hm, let's look at the Spring Webflow documentation: "any objects stored in flow scope need to be Serializable" - and now back to the Entity Manager interface - nope - it doesn't extend Serializable, so we have no guarantee that it will be.

Indeed when you use the EclipseLink as JPA provider you'll get beautiful "SnapshotCreationException: Could not serialize flow execution; make sure all objects stored in flow or flash scope are serializable".

I've reported this problem in Spring Webflow JIRA - see JpaFlowExecutionListener shouldn't assume that EntityManager is Serializable

You may also find this problem in Community Forum - EclipseLink, Toplink NotSerializableException - mentioned first on August 28th, 2008.

I'm waiting eagerly for the fix :)

Saturday, March 5, 2011

Spring @Autowired, JUnit and Mockito

Few days ago I've encountered interesting problem with autowiring Mockito based Spring Framework beans, let me share it with you :)

Everything started when I've made JUnit test for some business logic code.
...
import static junit.framework.Assert.assertNotNull;
...
@ContextConfiguration({ "classpath:.../business-logic.xml", "classpath:.../orm-jpa.xml",
"classpath:.../test/mockito.xml", ... })
public class MockitoTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private EmployeeManager employeeManager;

    @Test
    public void test01() {
        assertNotNull(employeeManager.get(Long.valueOf(1L)));
    }
}
Default EmployeeManager implementation used by me delegates the entity fetching to EmployeeDAO:
@Component("business-logic.EmployeeManager")
public class DefaultEmployeeManager implements EmployeeManager {

    @Autowired
    private EmployeeDAO employeeDAO;

    public Employee get(Long identifier) {
        return employeeDAO.get(identifier);
    }
}
EmployeeDAO in this example is a mock created using Mockito:
<bean id="persistence.EmployeeDAO" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="....dao.EmployeeDAO" />
</bean>
When I tried to run the test, it responded with beautiful exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'business-logic.EmployeeManager': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ... .dao.EmployeeDAO ... .logic.impl.DefaultEmployeeManager.employeeDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [... .dao.EmployeeDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ... .dao.EmployeeDAO ... .logic.impl.DefaultEmployeeManager.employeeDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [... .dao.EmployeeDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 
My first thoughts were - Why the heck it doesn't work?! There is a bean which can be used for autowiring! - but after few seconds I realized that I'm wrong :) - Here is the explanation why ;)

When Spring Framework creates the beans, and tries to autowire the EmployeeManager properties it seeks for the bean having class EmployeeDAO, but at this point our Mockito based bean is still a Factory, not concrete instance, therefore Spring Framework checks the mock method of our Factory, to determine the type of returned objects. As you may see below it has signature:
public static <T> T mock(Class<T> classToMock)
and thus the determined type is Object, which of course doesn't match the desired one (EmployeeDAO).

Let me read your mind at this point ;) - You think: What can we do with it? - Well, we have to assure that EmployeeDAO bean will be turned into real instance before it will be requested for autowiring.
In other words EmployeeDAO bean should be defined BEFORE the beans using it for autowiring.

We can do it in following ways:
  1. Change the @ContextConfiguration annotation to move the file defining this bean (mockito.xml) in front of all others (very naive solution, but sometimes sufficient ;) )
  2. Define for all beans referring EmployeeDAO that they depend on it
The last one can be achieved in following way:
@Component("business-logic.EmployeeManager")
@DependsOn("persistence.EmployeeDAO")
public class DefaultEmployeeManager implements EmployeeManager ...
when you define your beans using context scanning, or if you simple define them in XML, using depends-on attribute of the bean.

PS: Libraries/Frameworks used in the above example: Spring Framework - 3.0.4, Mockito - 1.8.5 and JUnit 4.8.1

Sunday, February 20, 2011

Test me to the end of code

Those who know me may think I'm Javaholic - well, maybe a little ;) - but I do like other programming languages too :) - really :) - below you may find results of my small experiment with XCode 4, Objective-C categories and Unit Tests.

I've started with the idea of extending NSArray class with method returning an array with shuffled elements, which can be achieved using Objective-C categories [1], in following way:

Define the Shuffling category (NSArray+Shuffling.h):
#import <Foundation/Foundation.h>

@interface NSArray (Shuffling)

- (NSArray *) shuffle;

@end
Implement the category using modern version of Fisher-Yates shuffle algorithm [2] (NSArray+Shuffling.m):
#import "NSArray+Shuffling.h"

@implementation NSArray (Shuffling)

- (NSArray *) shuffle 
{
    NSMutableArray *result = [self mutableCopy];
    int j = 0;
    for (int i = [result count]; i >= 1; i--) {
        j = arc4random() % i;
        [result exchangeObjectAtIndex:j withObjectAtIndex:i-1];
    } 
    return [[result copy] autorelease];
}

@end

We have the code, let's put it into some project where we could test it - static library will be enough for our needs, let's use it:


XCode 4 let you select if you will use Unit Tests for the project when you define its name:


After creating new project, we will add our source code to it:


It will be new Objective-C Category:


based on NSArray:


and bound to the primary project target:


Now we can put the source code described at the beginning of this post into newly created files.

Project created the above way with XCode 4 has automatically generated Unit Test, which can be run at this point to check if everything works correctly - before you do it, check if you selected the iPhone Simulator for running it - it cannot be done on physical device.

Let's run the XCode 4 generated Unit Test:


What we will see at this point will be:


It looks like everything is fine till now :) - let's create our own test instead of STFail macro:
- (void)testExample 
{
    NSArray *array = [NSArray arrayWithObjects: [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4], [NSNumber numberWithInt:5], [NSNumber numberWithInt:6], [NSNumber numberWithInt:7], [NSNumber numberWithInt:8], nil];
    NSArray *shuffledArray = [array shuffle];
    STAssertNotNil(shuffledArray, @"Shuffled array is nil");
    STAssertTrue([shuffledArray retainCount] == 1, @"Retain count: %i", [shuffledArray retainCount]);
    NSLog(@"Shuffled: %@", shuffledArray);
}

When you run it this time you'll get the exception:


because our static library was not used by the linker, and thus our NSArray extension is not visible, let's correct it by adding appropriate linker flag [3] (-all_load):


When you run the test now you should receive something like this:


As you see this time Unit Test is working correctly, and our shuffling code too :)

Few links for the dessert:
  1. Objective-C: Categories
  2. Fisher–Yates shuffle
  3. Objective-C Category Causing unrecognized selector
  4. Test Driving Your Code with OCUnit
  5. OCUnit: Integrated Unit Testing In Xcode

Sunday, January 30, 2011

STS - @RequestMappings View

Sometimes I wonder if I really know the tools lurking beneath the surface of my Eclipse IDE ;) - today I've discovered @RequestMappings View - part of SpringSource Tool Suite (STS). I know, you probably use it for centuries already ;) - but for me it was really nice surprise :) - The rest of this post is for all the developers having feeling that there should be something like that, but still looking for it ;)

Let's start from the beginning, and open this View:


At the bottom of the Eclipse window you should see something like this:


Let's populate it with some data now ;) - this is the hardest part, because your project should have a Spring Project Nature, my own didn't have it, therefore I had to correct its configuration - adding missing Nature first:


and defining which files contain Spring Beans:


Finally we can find the file defining our application's request handlers, and populate the View with defined mappings:


Which will look somehow like this now:


When you click twice on any of the lines in this view you'll be transfered to the appropriate handler method, like in this example:


I'm still learning this View, and hope that next STS versions (I'm using 2.5.2 currently) will bring more functionality in it.