So far I’ve been using a simple static variable as a fake storage to hold article metadata. That was enough to move forward, to explore the API for the service and how to use it from a client.
This blog post is part of a series about the development of ALE News using an approach to software development called Acceptance Test-Driven Development. For an overview please see the introductory article.
Another thing that was also in the back of my head is versioning. Sometime in the future the API of the service will evolve and I might have to distinguish different versions of it.
For now I just wanted to improve the storage a bit and changed this to an ArrayList. That change is now breaking my scenario tests, because I get a NullPointerException when my code is trying to use the list to find article metadata.
Initially I was using
// todo: fake
private static Map<String, ArticleMetadata> fakeArticles = new HashMap<String, ArticleMetadata>();
and then got the NullPointerException when trying to access fakeArticles
. I then changed this to
// todo: fake
private static Map<String, ArticleMetadata> fakeArticles ;
public ArticleResource() {
fakeArticles = new HashMap<String, ArticleMetadata>();
}
and now it is clear what is causing the problem: re-instantiating the class.
So I need to create a slightly more elaborate storage facility. I’m still not ready to invest into using a real database, as that would require me to do all kinds of additional work unrelated to working on what ALE News should do.
When I was browsing the documentation for Jersey I saw that it can be used together with Java CDI (Context Dependency Injection). I could have an instance of a class holding the ArrayList and have that injected into the @Resource to serve RESTful service requests.
That seemed like a nice way to continue going without committing on too much just yet.
However, it appears that for using CDI one needs to also use an Application Server. I looked around and found Glassfish, JBoss and even the real big ones like Websphere. That’s not what I want to use at the point. Supposedly Jetty can also be configured to manage beans and support CDI. But somehow all that is a bit too much dependency for my taste. I consider choosing an application server or any slightly bit more elaborate runtime environment as a dependency an early commitment and I don’t want to do that at the moment. I want to keep my options open and focus on fleshing out the what of ALE News. I might change a lot of things very soon and any early commitment would just make that change harder.
Then I remembered an old friend: Spring Framework. Several years ago that was what a Java programmer would usually use for Dependency Injection. So I looked it up and saw that Pivotal Labs is now maintaining it. I don’t know the details and I don’t intent to research it but I thought “Oh! A Ruby shop has taken over a popular Java framework”. The current spring.io website looks very good and there I also found that all I want to do at the moment I can do with Spring. That includes RESTful web services. I might want to continue with Spring instead of Jersey.
The good part about Spring has always been that one really owns the code. The framework itself is open source, which means that one can have a copy of it and it is not very likely to disappear. The other good part is that nothing really requires an application server. Everything can just as well be run as a standalone Java executable. So running something in a server becomes an option not a requirement.
Although it is not much right now I have a RESTful service implemented using Jersey. Jersey can integrate with Spring and so I decided to some minimal invasive changes to my code by adding a dependency:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.12</version>
</dependency>
I also had to add
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
And an applicationContext.xml file to /src/main/resources
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="net.caimito.ale_news"/>
</beans>
Then I changed ArticleResource by adding a new class ArticleStorage and have Spring inject it into ArticleResource:
@Path("article")
public class ArticleResource {
@Autowired
private ArticleStorage articleStorage ;
ArticleStorage is simple:
@Repository
public class ArticleStorage {
private Map<String, ArticleMetadata> metaData = new HashMap<String, ArticleMetadata>() ;
public Map<String, ArticleMetadata> getStorage() {
return metaData;
}
}
After changing the methods in ArticleResource I was able to run mvn install on the whole project. The existing acceptance tests for the CRUD and list scooped articles feature that I have for the Article Service did all work but the ones for the web client did break.
Further investigation showed that Spring does not get initialized when Jetty loads the second war file.
So I researched and thought about that for quite a while. I even did an experiment using the Maven plugin for Glassfish.
In the end I decided to merge the article-service and web-client modules. I’m not happy with that but for the moment it should be ok to continue with more important things. I need to come back to this issue though.
Previous | 10 Oct 2014 | Next |
This article has been posted to social media sites. There might be comments. Just follow the links:
About me
Hello! My name is Stephan Schwab.
As International Software Development Coach and Consultant I help CEOs and Department Leaders to improve value creation and cohesion within their organization. The outcome will be higher quality, customer delight and more revenue.
Learn about my professional experience since 1986.
Professional Services
I'm fluent in these human languages:
Scrum Pair-Coaching to develop technical competence:
Resources for new clients:
Search
Special Content
Highlights of the Year
Living on planet Earth
Open Source Projects
Stay in touch
My Books
Everything
See a listing of all posts on this site.