Application-wide configuration of Lambdaj FinalClassArgumentCreators. Where and how to do it?
Asked Answered
S

2

11

We have a problem with configuring lambdaj to work with Joda Time. Since LocalDate is a final class, Lambdaj needs to be initialized like following: (see bug 70)

public class LocalDateArgumentCreator implements FinalClassArgumentCreator<LocalDate> {
    private final long MSECS_IN_DAY = 1000L * 60L * 60L * 24L;
    public LocalDate createArgumentPlaceHolder(int seed) {
        return new LocalDate((long)seed * MSECS_IN_DAY);
    }
}
ArgumentsFactory.registerFinalClassArgumentCreator(LocalDate.class, new LocalDateArgumentCreator());

Since we need this configuration to be applied virtually everywhere, we are short of options on how to implement this. Our application is a web application based on Spring and Wicket.

I have come up with three different options:

1. Static initialization block in the core maven module

Since the core module is included in every other module, all modules would include the class. The remaining question is that do static blocks always get initialized even if there are no references to the target class?

Example

public final class LambdajInitializer {
    static {
        // initialize like above
    }
}

2. An initializing bean in applicationContext.xml

Downside: never gets initialized for non-Spring tests

Example: In applicationContext-core.xml (included in every module)

<bean class="...LambdajInitializer" />

public class LambdajInitializer {
    @PostConstruct
    public void init() {
        // Lambdaj initialization
    }
}

3. A call to a initializing method in the Wicket application class

Downside: never gets initialized outside the web module

public class MyApplication extends WebApplication {
    @Override
    public void init() {
        ...
        // Lambdaj initialization
        ...
    }
}

My question is: which is the preferable way to achieve this?

Scare answered 11/12, 2012 at 13:23 Comment(2)
You're missing the question...Quincuncial
Yeah, accidentally posted it too early.Scare
S
0

We came to the following conclusion:

  1. For the runtime of the application, we initialize the Lambdaj's FinalClassArgumentCreators in the Wicket Application class's init() method. This way, they are almost certainly being initialized before any Lambdaj usage.
  2. For testing of Wicket components and pages, we created our own TestApplication class, which uses the same initialization code as the production application.
  3. For out standalone batch jobs, we decided not to use Lambdaj. If we later on decide to use it, we will probably extract the initialization to a class that Spring would instantiate.
Scare answered 27/12, 2012 at 6:57 Comment(0)
S
2
  1. I would avoid static initialization as you may have (how unlikely is your call) modules in future which won't need this kind of initialization. I do not fancy static inits.
  2. It is a reasonable approach, you can place this initialization in a @Before section of your non-spring unit tests
  3. Like for 2., you can initialize the code in your @Before sections.

Option 4. you could create a test-only Spring configuration class/file and pass it on to your tests using @ContextConfiguration

Schou answered 18/12, 2012 at 7:34 Comment(1)
I'm not so worried about the tests than the production code. If the initialization has not been done in tests, they will just fail, which when using Lambdaj operations on LocalDates in this case. The problem is, that the problem might not be spotted by unit tests since it somehow depends on the execution order (in out production environment cluster the other server failed whereas the other did not).Scare
S
0

We came to the following conclusion:

  1. For the runtime of the application, we initialize the Lambdaj's FinalClassArgumentCreators in the Wicket Application class's init() method. This way, they are almost certainly being initialized before any Lambdaj usage.
  2. For testing of Wicket components and pages, we created our own TestApplication class, which uses the same initialization code as the production application.
  3. For out standalone batch jobs, we decided not to use Lambdaj. If we later on decide to use it, we will probably extract the initialization to a class that Spring would instantiate.
Scare answered 27/12, 2012 at 6:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.