Java

Getting the necessary libraries to run a HornetQ client

Yesterday, I stumbled upon what seems to be an ActiveMQ bug and I decided it was finally time to try another JMS broker. It’s been a while now that I want to try HornetQ, former JBoss Messaging 2.0.

The latest release is 2.2.1 and you can grab it over here.

I have this project where JMS access is configured with Spring and all I need is a ConnectionFactory and a DestinationResolver bean to get it working. The documentation of HornetQ is pretty complete as to which jars I need to add my classpath but since I am using Maven for my project of course I thought everything would have been resolved for me.

Well, no. The content of the hornetq-jms-client speaks for itself. Again, the documentation is clear so I was able to get it working quite easily actually. Here’s what I added in my pom to get it working


<dependency>
    <groupid>org.hornetq</groupid>
    <artifactid>hornetq-core-client</artifactid>
    <version>2.1.1.Final</version>
</dependency>
<dependency>
    <groupid>org.hornetq</groupid>
    <artifactid>hornetq-jms-client</artifactid>
    <version>2.1.1.Final</version>
</dependency>
<dependency>
    <groupid>org.hornetq</groupid>
    <artifactid>jnp-client</artifactid>
    <version>2.1.1.Final</version>
</dependency>
<dependency>
    <groupid>org.jboss.netty</groupid>
    <artifactid>netty</artifactid>
    <version>3.2.0.Final</version>
</dependency>

Of course you’ll also need the JMS API if these are not provided to you by the server you are using. The documentation recommends the jboss jms api jar but the one from geronimo will do as well


<dependency>
    <groupid>org.apache.geronimo.specs</groupid>
    <artifactid>geronimo-jms_1.1_spec</artifactid>
    <version>1.0.1</version>
</dependency>

Last but not least, I doubt the only Maven repository where I’ve found these is in your Maven proxy config so you’ll need to add this somewhere


<repository>
    <id>hornetq-repo</id>
    <url>http://repository.jboss.org/maven2-brew</url>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
</repository>

Too bad hornetq jars have no metadata and I’ll hope this will change in the future.

UPDATE: Have a look to HORNETQ-426.

Configuring separate Maven settings for Hudson

This may sounds very easy to do but it turned out to be much more complicated than I anticipated. At work, we have an HTTP proxy and SVN authentication using our domain user. As long as you are logged in with your user, it is working fine but if you need to setup background services or a shared user for whatever reason you all the sudden need a dummy user to perform the NTLM authentication for you.

We have a Hudson test instance using that dummy user of ours and I wanted to reuse it for our shared demo account (the demo purpose here of course is to avoid creating yet another stupid dummy user). Since the Tomcat service hosting Hudson was running as that user, all the Maven defaulting where used by hudson like enviromnent MAVEN_OPTS (the JVM options used by the Maven process) and the local settings.xml configuration.

Since Hudson is using the Maven embedder, using a separate Maven distribution with a hackish launch script won't do. Instead, you have to set the org.apache.maven.global-settings system property pointing to your customized local settings.xml file for Hudson. There you can specify the local repository location, proxy settings, profile, etc without affecting usage of Maven on the command line.

To do so go to Maven Hudson > Configure System and set something like the following in the Global MAVEN_OPTS option

CODE:
  1. -Dorg.apache.maven.global-settings=/var/lib/hudson/m2-env/settings.xml

Pay attention that using this option will ignore any settings set in the MAVEN_OPTS environment variable. You'll have to copy/paste them there as well for them to be taken into account.

Unit and Integration Tests made easy with Spring

A colleague at the Apache Software Foundation was asking me for info about the Spring Test Framework the other day and I thought I could just share the answer with everyone.

The first thing you would do of course is to read the online documentation here and here in particular if you're interested to bring transaction management in your tests. While the doc is pretty clear, a small example will probably allows you to get started more rapidly.

Those examples use Spring 2.5 and JUnit 4.4. Note that you need Junit 4.4 to use the annotations based helpers.


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/META-INF/myapp-test/foo-test-beans.xml"})
public class MyTest {

    @Resource
    private MyService myService;

    @Test
    public void simpleTest() {
        // Oh well test something with myService
    }

As you can see, two stupid annotations turned out your test class into a Spring-bean! The @Resource (or @Autowired) allows to automatically inject a reference to the service you want to test.

The first annotation, @RunWith, allows for Spring to get called when the test starts and to perform the necessary plumbing for us. The second one, @ContextConfiguration, defines basically what application context your test class will use. You can reduce even more the coding by placing a context file called MyTest-context.xml in the same package as the test. The nice thing about this annotation is that it will cache your application context so if multiple test classes are using the same context, the overall executions will be much faster. If you need advanced features, have a look to the documentation, especially if you want to override the application context of a test that subclasses another one! (have a look to the inheritLocations parameter).

Transaction management can be added easily. The framework will create the transaction for you and rollback everything by default, which means you don't have to worry about test objects that you would create in the database. Let's upgrade our simple test so that it can use a transaction.


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/META-INF/myapp-test/foo-test-beans.xml"})
@TransactionConfiguration(transactionManager = "transactionManager")
public class MyTest {

    @Resource
    private MyService myService;

    @Test
    @Transactional
    public void simpleTest() {
        // Oh well test something with myService
    }

That's it. Pretty neat, right?

What about exceptions? Checking for expected exceptions is a bit painful and add a whole bunch of code that does nothing. Besides, if the exception is related to the transaction, it's pretty hard to intercept it in a transactional test because the transaction will commit at the end of it. Hopefully, Spring provides an @ExpectedException that is really handy. Let's assume that my simpleTest now should throw a SomeException in some Hibernate interceptor. Previously, I would have to turn my test as non transactional and intercept the exception in a try/catch clause. Now I just have to do this


@Test
@Transactional
@ExpectedException(SomeException.class)
public void simpleTest() {
    // Oh well test something with myService that will fail as expected
}

There's other things that you would discover as you use it and it's definitely worth the effort integrating it in your test suites if you're using Spring already.

Spring 3.0 and Maven: an update

In a previous article, I was talking about the current naming issues in the first milestone of Maven 3.0. Hopefully, the first release candidate will have usual artifact Ids. See SPR-5385 for more details.

Good news!

Spring 3.0 M1 breaks Maven projects

I've been using Spring extensively for a couple of months now and I must say I really enjoy it. Since we have a RESTful web service at work, I wanted to test that latest REST integration in Spring 3.0 M1 as it was presented at Devoxx.

My first surprise was actually that it was quite hard to find this milestone release on any Maven repository so I had a look to the downloadable bundle (after all, I could use the big spring.jar file). No big spring.jar file but a bunch of jar files with weird names, like org.springframework.core.jar (wtf?).

The first entry in the 3.0 M1 changelog as announced here is

revised project layout and build system with module-based sources

Well, the new repository structure looks weird to me but it has a really nasty side effect: all artifactIds have changed (yes!). Have a look to the Maven repository view yourself.

I am a bit confused here. Either the SpringSource guys have decided to really break this in 3.0 because they wanted to harmonize it somehow (I still don't get what it brings if you are not in the process of using OSGi) or they have no idea how Maven works. I hope it is the second case and we will be able to let them know the chaos that users will experience with existing user projects if we keep this.

The obvious first problem is that all Maven poms should accommodate the names change which is annoying but not that much. However, the transitive dependencies mechanism of Maven will not detect a version conflict of the Spring framework anymore! Say that you have an old/stable module that relies on Spring 2.0. This module uses some stable Spring API at runtime and you are actually using it in a Spring 2.5 container in the final project. If you upgrade this project to 3.0 M1, you will end up with both Spring 2.0 and Spring 3.0 M1 in your classpath! Pretty scarry... You could obviously use the optional flag in the maven dependencies but since Maven does a good job of resolving the version conflict for us, most users have not chosen this approach.

All in all, cast your vote here please!

Discover candidate classes with Spring 2.5

I recently started using the Spring framework and discovered how it could help me writing better code. I just stumbled upon the following problem: I need to be able to provide the ability to 3rd party developers to define the implementation of an interface to plug custom behaviour in a server. Since those guys are writing their code in their own space, I don't want to force them to place the implementation at a given place in the classpath and I don't want them to force some kind of naming conventions for the implementation. Besides, the implementation is different based on a version flag so we also need to identify to which version the implementation refers to.

So basically, here's the easy stuff. I need an interface to define the contract of my custom behaviour and I can use an annotation to define the version to which the implementation refers to. All this boils down to


@MyAnnotation(version=2)
public class MyCustomImplementation implements ServerBehaviour {
  // bla bla bla
}

Now what? I can obviously scan the classpath by hand with all the mistakes I could make in my own custom code. That's were Spring comes into play. The ClassPathScanningCandidateComponentProvider has surely a long name but it proved to be very useful and very easy to use. Say that the developer provides a base package for his application (com.company.foo). Scanning the classpath (including sub packages!) is as easy as:


final ClassPathScanningCandidateComponentProvider provider =
    new ClassPathScanningCandidateComponentProvider(false);
// I want only classes that are flagged with my custom annotation
provider.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class));
// I want only classes that implements my CustomBehaviour interface
provider.addIncludeFilter(new AssignableTypeFilter(CustomBehaviour.class));

String basePackage = "com/company/foo";
final Set<beandefinition> components = provider.findCandidateComponents(basePackage);
System.out.println("Found["+components.size()+"] candidate(s)");
for (BeanDefinition component : components) {
  System.out.printf("Component: %sn", component.getBeanClassName());
}

Notice that the BeanDefinition class provides a lot of useful information about the discovered classes. The good news is that all this is available from plain stupid Java. You don't even need to start the spring container to use this.

Updated: the syntax highlighter that I am using puts the Set<BeanDefinition> in lower case for whatever reason. I keep trying to update it without any success. Just translate on-the-fly please.

Idea 8 released

Jetbrains just released Idea 8. The new release brings a bunch of new features but I am actually interested in two main areas that the previous versions of IDEA wasn't really addressing: Maven support and performance with projects with more than 4 modules and lots of classes. I must say that working with big codebase is quite a nightmare with IDEA.

Hopefully, the new release brings a nice update on the Maven support. So far, I've been able to use all my projects quite easily with it (I am using the EAP releases for a long time now). Regarding performance, there's still work to do. There's an must-have  configuration item that you need to configure if you are running Maven projects. Go to Settings and choose File Settings in the IDE options. In that screen there is a field called Ignore files and folders. Just add target; in front of the list of files. This will avoid IDEA to blow up the I/Os every time you're doing a complete rebuild for instance. This simple settings really boosted the performance and make IDEA enjoyable to use.

Singapore by Night

Allez hop, une petite photo de Singapour de nuit, 3 semaines en retard. Vous remarquerez chers lecteurs que je respecte les consignes que je donne à mes étudiants avec la taille des images. Une image légère avec une résolution relativement faible mais suffisante et éventuellement la possiblité de télécharger une image avec une résolution plus importante.

Singapore By Night

Singapore Days Two/Three

La majorité du week-end s'est déroulée aux quatre coins de la ville. Assez perturbant de se déplacer dans cette ville parce qu'ils roulent à gauche et ils appliquent ça aussi au sens classique des escalators et de la marche en général. On a même eu droit à une jeune fille qui brandissait une petite feuille A4 écrite à la main "Please Keep Left". J'étais persuadé que c'était une blague mais d'autres personnes arboraient des feuilles relativement similaires plus loin.

Samedi, on a vu l'hôtel le plus haut du monde et la fontaine la plus grande du monde. Malgré tout, Singapour reste vraiment une ville abordable (je n'irai pas à dire à échelle humaine). Emerald Hill est perpendiculaire à Orchard qui est de loin la rue la plus bruyante de la ville. A quelques mètres de là, une toute petite rue piétonne avec une poignée de bars et de jolies terasses toutes petites. Elle fut dur à trouver mais on l'a trouvé! Pour ceux que ça intéresse, il faut longer le restaurant Outdoors complètement et la rue est juste derrière. Un des bars a une trentaine de bières différentes et une face de la carte est consacrée exclusivement aux bières belges. A 12€ la Chimay bleue, ça calme évidemment. Le soir, on a mangé dans un resto japonais très sympa et typique (pas de chaussure, la table au niveau du sol avec un trou en dessous, etc, etc). Un peu déçu par mon choix mais le plat de Jean-Marc était très bon.

La ville est remplie de gens qui nettoient tout en permanence avec des balais pourraves. Dans un des escalators du metro, on vu un mec descendre avec deux lavettes près de la main courante pour bien tout nettoyer.

Dimanche, Chinatown et des arnaqueurs de haut-vol (on nous a fait payer nos serviettes!). Dans l'ensemble, très sûr et les gens sont très calmes.

Week-end à Savannah

Ce week-end, j'ai quitté l'horrible Atlanta vers la côté Est. Notre destination (Alain - mon boss - et Marc un collègue Australien): Savannah, à la frontière entre la Géorgie et la Caraline du nord. La météo présageait une température de 34° environ!

Le voyage fut assez long. Les autoroutes américaines sont particulièrement monotones: il y a tellement d'espace là bas que les 2 sens de circulations de l'autoroute sont parfois séparés d'une bonne trentaine de mètres ! A dire vrai, je n'ai pas eu vraiment beaucoup de temps pour préparer le voyage. On a réservé notre hotel le jour même, un espèce de Motel à l'américaine où on gare sa voiture devant sa chambre. Déjà vu no country for old men ? C'est un hotel dans ce genre là. La première chose qui me frappe, c'est l'eau qui sort d'un peu partout et qui tombe sur le sol. L'air-conditionné qui fontctionne dans toutes les chambres, peu importe si elle est occupée ou pas. Ma chambre est plutôt chouette, propre et fonctionnelle. Et il fait litérallement glacé dedans (beaucoup trop froid!).

On décide de prendre le taxi, histoire de ne pas devoir revenir avec un verre dans le nez. Savannah est un peu particulier: le centre historique est très sympa avec une promenade le long du canal (River St) et pas mal de boutiques à touriste. On a eu beaucoup de mal à trouver un resto en attendant l'activité du soir: the ghost tour. D'après les locaux, Savannah est hanté à pas mal d'endroits. En parlant de locaux, la nana qui nous accueille est très sympa et est passionnée par ce qu'elle fait. On a un petit groupe de 7 et elle nous montre tout un tas d'endroit intéressant: hotels, bed & breakfast, parcs, cimetières, ... Chaque endroit a sa petite histoire passionnante. Un peu bizarre au début mais amusant.

Après cette petite visite de la ville, direction un blues bar où un groupe très très bon joue ce soir là. Un chouette moment, Marc doit me donner le nom du groupe. La fête a été un peu gachée par une bande revenant d'un mariage complètement bourrés. C'était marrant 5 minutes mais ça a gaché un peu le spectacle.

Le lendemain on est allés à Tybee Island qui est ma première plage américaine: très beau, l'eau très très chaude et une super promenade. Sur un poton, une bande de locaux qui pêchent.

Savannah est un chouette coin mais il faut avoir les moyens de faire un voyage pareil pour uniquement quelques jours. Au delà, je pense que je me serai beaucoup ennuyé :)

Next »