8 November 2013

Date type in H2 vs Oracle

I often use H2 to locally develop code that is supposed to work on Oracle. Yes, yes, I can hear all the 'Why don't you work on production-like environment?!'. Well, I do it because I'm lazy. When the development configuration has no dependency on external infrastructure then every new developer or tester can simply do: git clone ... && mvn test && mvn jetty:run and it just works. Immediately. Without bothering me with questions about the setup, configuration, passwords etc. CI server can build each new branch simultaneously. Local tests run quickly as there is no network communication. It's simply really convenient.

Of course, it has its price. Compatibility. Most applications are really simple and doesn't need any vendor-specific features. But sometimes...
create table my_table (my_column date);
insert into my_table values (timestamp '2013-01-23 13:23:34');
select my_column from my_table;
So what's the result of the select statement?
oracle: January, 23 2013 13:23:34+0000
H2:     2013-01-23
What happened with time? Let's see more details
select cast(my_column as timestamp) from my_table;
oracle: January, 23 2013 13:23:34+0000
H2:     2013-01-23 00:00:00.0
Yep, the time is silently truncated. Oracle Date stores time as opposed to H2, mysql, postgres and probably most others. And this will affect all frameworks you use: jdbc, dbunit, hibernate etc. So, if possible, use Timestamp type or design your application in a way it doesn't matter.

Tested databases (thanks to sqlfiddle.com):
  • Oracle 11g R2
  • H2 1.3.171
  • MySql 5.1.61
  • PostgreSQL 9.3.1

27 July 2013

404 error with spring mvc testing

We have a standard rest application built with spring mvc (v3.2.3). Let's add another controller (MyController) with one method that does some computations and returns an empty response with 200 OK. Test first:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.*;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

public class MyControllerTest {

 private MockMvc mockMvc;

 @Test
 public void test() throws Exception {
  mockMvc.perform(get("/my/test"))

   .andExpect(status().isOk())
   .andExpect(content().string(""));
 }

 @Before
 public void setUp() throws Exception {
  mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();
 }
}
Nothing new, everything just as in spring's tutorial. So now let's write the code:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MyController {

 @RequestMapping("/my/test")
 public void test() {
  System.out.println("test method executed"); //yes, yes, I know
 }
}
Test is green, that was easy. Let's see our code in action. Start jetty and check the address /my/test. Method is executed and we get... 404 not found. Wtf?!

Probably the quickest way to find the problem is to compare the method with other working controllers. Of course, I forgot about @ResponseBody. After adding it, jetty displays the page correctly and test still passes. But the purpose of writing tests is to have protection against such mistakes. So why the test was green?

For void methods without @ResponseBody spring forwards request processing to DispatcherServlet which, in this case, fails trying to resolve a view for the specified url. But for some reason mockMvc reports empty response and status 200. I reported it as a bug but it got status 'Works as Designed'. So how can we eliminate the false positive? We need to explicitly check if no forwarding is done. And there is an existing ResultMatcher for this:
forwardedUrl(null)
It can be added with another andExpect inside each test. But turning it on globally will save you from such mistakes in future:
@Before
public void setUp() throws Exception {
 mockMvc = MockMvcBuilders.standaloneSetup(new MyController())
                             .alwaysExpect(forwardedUrl(null))
                             .build();
}
After adding this matcher, the test without @ResponseBody fails:
java.lang.AssertionError: Forwarded URL expected:<null> but was:<my/test>

8 July 2013

Testing time-dependent code

Often people do something like that
public List<Notification> findNotificationsToSend() {

    List<Notification> notifications = repository.findDailyNotifications();
    int today = Calendar.getInstance().get(DAY_OF_WEEK);
    if (today == SUNDAY) 
        notifications.addAll(repository.findAllWeeklyNotifications());
    return notifications;
}
and then you can be sure they don't use TDD. Because there is absolutely no way you can create such a bad code when you have tests. But what can we do about the calendar? Same as always. Have you noticed that when there is a call to a database or other external system, people immediately say: 'extract and mock'? But when there is a call to jvm's infrastructure they have no idea what to do. And the answer is simple: 'extract and mock'. Does it mean people just repeat previously seen schemes without thinking?
We can start refactoring with:
public class TimeProvider {

    public int dayOfWeek() {
        return Calendar.getInstance().get(DAY_OF_WEEK);
    }
}
That's a good start. Now it's easy to test the findNotificationsToSend but TimeProvider can still contain some complicated time calculations which are not testable. And it will grow with calendar-dependent methods. How to clean it up?
  • Switch to joda time. It has much better api that protects TimeProvider from uncontrolled growing.
  • TimeProvider should contain only often used, calendar-like, parameterless methods dependent on current time. And nothing else. 'isSunday' and 'beginningOfQuarter' are fine but 'shouldIncludeWeeklyNotification' is not.
  • Completely separate jvm's infrastructure access from time calculations. In this case I usually choose inheritance over composition because TimeProvider won't ever grow in any additional dependencies. After all, even business guys don't change the definition of Sunday.
The following code usually works for me.
abstract class TimeProvider {

    protected abstract long currentMillis();

    public final DateTime now() {
        return new DateTime(currentMillis());
    }

    public final boolean isSunday() {...} //if often used

    // other common business methods. all final.
}

public final class RealTimeProvider extends TimeProvider {

    protected long currentMillis() {
        return System.currentTimeMillis();
    }
}

public class TestTimeProvider extends TimeProvider {

    private long currentMillis; 

    public TestTimeProvider() {
        this("2013-05-17"); // preset time; handy for tests
    }

    public TestTimeProvider(String currentTime) {
        setTime(currentTime);
    }

    public void setTime(String currentTime) {
        currentMillis = parseTime(currentTime);
    }

    protected long currentMillis() {
        return currentMillis;
    }

    private static long parseTime(String time) {...}
}
Of course, we use TestTimeProvider in unit and spring-context tests. Often it's more handy than mocks. If needed, add similar support for timezone.
Now we can test findNotificationsToSend, control time during integration tests and test isSunday method:
@RunWith(ZohhakRunner.class)
public class TimeProviderTest {

    TestTimeProvider timeProvider = new TestTimeProvider();

    @TestWith({
                 "2013-04-14,  true",
                 "2013-04-15,  false"
    })
    public void should_detect_sunday(String date, boolean shouldBeSunday) {
        timeProvider.setTime(date);

        boolean isSunday = timeProvider.isSunday();

        assertThat(isSunday).isEqualTo(shouldBeSunday);
    }
}
One place where time provider alone is not enough is integration testing, when we start the whole server to imitate production environment and connect to it over http. But that's a story for another post.

23 June 2013

Testing cron expression

Many people, using spring scheduling, write
@Scheduled("* * 3 * * ?")
public void myCronJob() {...
and then they wait a few days to check logs if the job is triggered correctly. And what about:
0 0/5 14,18,3-39,52 ? JAN,MAR,SEP MON-FRI 2002-2010
Fortunately, testing a cron expression is simple. But first we need a constant:
public static final String EVERYDAY_3_AM = "* * 3 * * ?"
And now, with spring's scheduling, we can use org.springframework.scheduling.support.CronSequenceGenerator
import static org.fest.assertions.api.Assertions.assertThat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.scheduling.support.CronSequenceGenerator;

import com.googlecode.zohhak.api.Coercion;
import com.googlecode.zohhak.api.TestWith;
import com.googlecode.zohhak.api.runners.ZohhakRunner;

@RunWith(ZohhakRunner.class)
public class CronTest {

  static CronSequenceGenerator everyday_3am;

  @TestWith({
    "2013-06-10 22:20,    2013-06-11 03:00",
    "2013-06-13 01:12,    2013-06-13 03:00"
  })
  public void should_trigger_at_the_nearest_3_AM(Date now, Date nearest_3am) {

    // when
    Date nextExecution = everyday_3am.next(now);
  
    //then
    assertThat(nextExecution).isEqualTo(nearest_3am);
  }

  @BeforeClass
  static public void parseExpression() {
    everyday_3am = new CronSequenceGenerator(Constants.EVERYDAY_3_AM);
  }

  @Coercion
  public Date coerce(String date) throws ParseException {
    return new SimpleDateFormat("yyyy-MM-dd hh:mm").parse(date);
  }
}
We use static variable just to avoid multiple parsing of the same expression, as for complex scenarios there might be many parameters.
The same can be achieved with quartz library. To do this just replace CronSequenceGenerator with org.quartz.CronExpression
Date nextExecution = everyday_3am.getNextValidTimeAfter(now);
everyday_3am = new CronExpression(Constants.EVERYDAY_3_AM);

9 June 2013

CodeGenerationException and proxies

Recently I saw one of tests failed with the message:
Exception of type java.lang.IllegalStateException expected but was not thrown. 
Instead an exception of type class org.mockito.cglib.core.CodeGenerationException 
with message 'java.lang.reflect.InvocationTargetException-->null' was thrown.
But let's start from the beginning. We have a spring web application that contains only 2 classes. First one is a standard session scoped component:
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MySessionComponent {
 
    public void doError() {
        throw new IllegalStateException(); 
    }

    public void doNothing() {}
}
Nothing new, right? Second component is a standard singleton:
@Component
public class MySingleton {
 
    @Autowired MySessionComponent mySessionComponent;

    public void sampleAction() {
        mySessionComponent.doNothing();
    }
}
That's the whole application. Now let's test it.
import org.junit.Test;
import static com.googlecode.catchexception.apis.CatchExceptionBdd.*;

public class MySessionComponentTest {

    @Test
    public void test() {
        when(new MySessionComponent()).doError();
        thenThrown(IllegalStateException.class);
    }
}
I use catch exception v1.0.4 and test passes. Now, let's do an integration test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class MySingletonTest {
 
    @Configuration @ComponentScan static class TestAppContext {} // just registers 2 components
 
    @Autowired MySingleton myController;
 
    @Test
    public void test() {
        myController.sampleAction();
    }
}
All tests pass. And now, let's suppose that we need, for whatever reason, to combine those tests:
@Test
public void test() {
    myController.sampleAction();

    when(new MySessionComponent()).doError();
    thenThrown(IllegalStateException.class);
}
And we get the exception. WTF? After some time spent with debugger I found InvocationTargetException thrown inside org.mockito.cglib.core.AbstractClassGenerator. The problem is there is no cause nor detailed message and therefore it's not propagated anywhere so you can't find the real reason in any logs. However this exception has target field and there we can find:
java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): 
attempted  duplicate class definition for name: "MySessionComponent$$FastClassByCGLIB$$441a78f3"
At first spring creates proxy for MySessionComponent in order to autowire beans with different scopes. Then catch-exception tries to create proxy for the same class. It seems that both frameworks generates the same name for the class and two classes with same name are not allowed within one classloader.

When we change the order of method invocations (the order of creating proxies)
@Test
public void deleteEbook() {
    when(new MySessionComponent()).doError();
    thenThrown(IllegalStateException.class);

    myController.sampleAction();
}
spring throws an exception but now you can see the real cause in the stacktrace:
org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
 at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
...
Caused by: java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "MySessionComponent$$FastClassByCGLIB$$441a78f3"
Btw, this behavior is strange because cglib claims it can detect name clashes. Maybe it's about repackaging cglib in almost every framework?

29 May 2013

Functional language for a java developer

Why should you learn it? IMHO, very important and underestimated argument is: it makes you a better programmer. What is more, you are probably already using it (javascript) and clojure and scala get more and more attention so it may be a good investment. But there is another, less obvious reason: it will help get a java job. A lot of interview questions are short algorithmic tasks. You can find one at almost every interview. Just pick the task, say that it would be easier to write it in a functional language and do it. Let's see a few examples. I asked google for 'programming interview questions' and I landed here. You can easily pick some tasks:

Create all permutations of a string. Here, haskell version is really impressive
permutation [] = [[]]
permutation xs = [x:ys | x <- nub (xs), ys <- permutation (delete x xs)]
In an array 1-100 numbers are stored, one number is missing how do you find it?
missing = succ . length . takeWhile id . zipWith (==) [1..] . sort
In an array 1-100 exactly one number is duplicate how do you find it?
duplicated = length . takeWhile id . zipWith (==) [1..] . sort
or after removing duplication:
increasingPrefixLength = length . takeWhile id . zipWith (==) [1..] . sort
missing = succ . increasingPrefixLength
duplicated = increasingPrefixLength
just for clarification, let's see how it works:
missing [1,3,2,5,6]
-- 4
duplicated [3,2,1,2,4]
-- 2
From other source: sum of digits of decimal expansion of 100!
(apply + (map #(Integer/parseInt (str %)) (str (apply *' (range 1 101)))))
number of zeros in decimal expansion of 100!
(count (filter #(= \0 %) (str (apply *' (range 1 101)))))
and the same in haskell (with currying and compact syntax for function composition)
sum . map digitToInt . show $ product [1..100]
length . filter (== '0') . show $ product [1..100]
Why functional style is useful? Often it's simpler because it has less edge cases (yes, you have to know the language and understand the FP). Of course above tasks aren't much more difficult in procedural approach and still, during the interview, you will probably have to solve them also in java. But I guarantee you: after such an answer you are a few points ahead of your competitors.

26 May 2013

Everything is a nail

How many times have you rejected someone's idea to use new tool in a (new) project? How many times have you done it without knowing the pros and cons of the tool? Just because you wasn't familiar with it? Why do you use the language / framework / library you use? Because it's best? Sufficient? If you really believe it, read the famous Beating the Averages (or at least the paragraph about The Blub Paradox).

Quiz


Before you expand code snippets, think for a while how would you solve the problem. Just try to estimate the complexity.

Question 1

What's the name of the following method? You know this method. If you don't, you should
public static boolean xxx(String str) {
    int strLen;
    if (str == null || (strLen = str.length()) == 0) {
      return true;
    }
    for (int i = 0; i < strLen; i++) {
      if ((Character.isWhitespace(str.charAt(i)) == false)) {
        return false;
      }
    }
    return true;
  }
How much time did you need to read and understand one of the most common functions?

Question 2

Can you do it better? Can you make this code more readable? Pick any tool you want.
isBlank = all isSpace

Question 3

Search all subdirectories and find all mp3 files greater than 9mb.
find -iname "*.mp3" -size +9M
Tiny academic examples? Maybe. Let's try something bigger and more complex.

Question 4

Write sudoku solver. The following solution is from Manuel Rotter's blog.
:- use_module(library(clpfd)). 

sudoku(Rows) :- 
  append(Rows, Vs), Vs ins 1..9,
  maplist(all_distinct, Rows),
  transpose(Rows, Columns),    
  maplist(all_distinct, Columns),    
  Rows = [A,B,C,D,E,F,G,H,I],    
  blocks(A, B, C), blocks(D, E, F), blocks(G, H, I),    
  maplist(label, Rows).     
 
blocks([], [], []).      
blocks([A,B,C|Bs1], [D,E,F|Bs2], [G,H,I|Bs3]) :-    
  all_distinct([A,B,C,D,E,F,G,H,I]),     
  blocks(Bs1, Bs2, Bs3)
Not a real life examples? No company would ever use such strange languages to make money? Well... they and they do.

Question 5

Something from corpo world. Typical security for web application. Only users with admin role (based on company's ldap) can access the application and only via https. Secondary log in of the same user should terminate his previous session. Each login should create new session id to prevent session fixation attack. Css files should not be protected because of performance.
<ldap-server url="ldap://mycompany.com:389/dc=mycompany,dc=com" />
<ldap-authentication-provider 
                         user-dn-pattern="uid={0},ou=people"
                         group-search-base="ou=groups" />

<http pattern="/css/**" security="none"/>
<http auto-config='true'>
    <form-login login-page='/login.jsp'/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" 
                                         requires-channel="https"/>
    <intercept-url pattern="/**" access="ROLE_ADMIN" requires-channel="https"/>

    <session-management>
        <concurrency-control max-sessions="1" />
   </session-management>
</http>
End of quiz. If you have other examples of a language/tool perfectly suited for a specific task, send them to me! Disclosure: prolog and spring examples haven't been tested.

Of course, you can't freely mix languages. Cost of integrating different languages, not designed for it, is rather high. Complicated build process, nonexchangeable data types, different runtimes, bad IDE support and so on. So, before each project, choose your language wisely. Will it cover most of requirements? Will it cover the most time-consuming ones? Then you won't add another language just to write isBlank but at some point it may be worth it. Will you recognize it when you reach that point? Cause when all you have is a hammer...