Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Testing Spring Boot with JUnit5

I decided that is time to move my tests in Spring app from JUnit 4 to Jupiter. It is not too complicated, given that Spring is already supporting JUnit 5, even though the default is still the previous version. However it requires being careful in a couple of steps.

Firstly, I have changed the POM in this way:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <!-- get rid of JUnit 4 -->
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- using JUnit 5 instead -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <!-- using the version set by Spring -->
    <scope>test</scope>
</dependency>
I have excluded JUnit 4 from the spring-boot-starter-test dependency, and then I have inserted a new dependency for Jupiter, all of them are obviously in the test scope. Notice that I didn't set the version for JUnit 5, accepting instead the one proposed by Spring. Just to stay on the safe side.

The changes in "normal" testing are quite simple, usually limited in using the right imports for the new library. Something a bit more engaging is to be done for Spring Application test. What I had for JUnit 4 was something like this
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyApplicationTests {
    // ...
In Jupiter, however, the annotation RunWith has been replaced with the more powerful ExtendWith, so the code has to be changed to
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class MyApplicationTests {
    // ...
Not too bad, isn't it?

Go to the full post

Autowired, Resource, Inject

In chapter three, Introducing IoC and DI in Spring, of Pro Spring 5, I have read the example about Using Setter Injection in the annotation flavor, where for the "renderer" service the Autowired annotation was used in its setter to inject the "provider" bean in its parameter.
A note hints that other annotations, Resource and Inject, could be used, but no example is provided. I thought it was better to practice a bit on them too.

Autowired

The provided example is actually what we usually see in Spring code:
@Override
@Autowired
public void setMessageProvider(MessageProvider provider) {
    this.messageProvider = provider;
}
We should only be aware that Autowired is pure Spring, as its full name documents.

Inject

We could get the same result using the JSR standard annotation Inject:
@Override
@Inject
public void setMessageProvider(MessageProvider provider) {
    this.messageProvider = provider;
}
I had to change the provided build.gradle file for chapter three, setter-injection project, since it didn't have the compile dependency for injection, named misc.inject and defined in the main build.gradle file as
inject         : "javax.inject:javax.inject:1"
Autowired and Qualifier

Say that we have more than one Component implementing the MessageProvider interface. The default one is name "provider", and so it is chosen by Spring in the above examples. But what if I want to inject a different one, for instance "pro2":
@Component("pro2")
class MessageProvider2 implements MessageProvider {

    @Override
    public String getMessage() {
        return "Hello from Message Provider 2!";
    }
}
The Spring commonly used approach is using the Qualifier annotation.
@Override
@Autowired
@Qualifier("pro2")
public void setMessageProvider(MessageProvider provider) {
    this.messageProvider = provider;
}
Both Autowired and Qualifier are Spring specific annotations.

Resource

A JSR standard alternative to the couple Autowired + Qualifier is given by the Resource annotation.
@Override
@Resource(name = "pro3")
public void setMessageProvider(MessageProvider provider) {
    this.messageProvider = provider;
}
Here above, the Component named "pro3" is going to be injected in provider.

Inject and Named

Another JSR standard alternative to Autowired + Qualifier is provided by the couple Inject + Named.
@Override
@Inject
@Named("pro4")
public void setMessageProvider(MessageProvider provider) {
    this.messageProvider = provider;
}
I have pushed to GitHub my changes. You could see there the build.gradle file, my new Components, and the alternative setters.

Go to the full post

How to close a Spring ApplicationContext

I've just finished reading chapter 2 Getting Started of Pro Spring 5. Nice and smooth introduction to Spring, and to Dependency Injection motivation.

Going through the provided examples, I had just a minor on the code provided. In a couple of cases, the created Spring contexts is stored in plain ApplicationContexts reference. This is normally considered a good way of writing code. We don't want to bring around a fat interface when a slimmer one would be enough. Anyway, ApplicationContext has no close() method declared, leading to an annoying warning "Resource leak: 'ctx' is never closed".

Here is one place where you could see the issue, in class HelloWorldSpringDI:
ApplicationContext ctx =
    new ClassPathXmlApplicationContext("spring/app-context.xml");

MessageRenderer mr = ctx.getBean("renderer", MessageRenderer.class);
mr.render();
An obvious solution would be explicitly cast ctx to ClassPathXmlApplicationContext, and call close() on it. However, we could do better than that. The Spring application contexts close()'s come from the interface Closeable. This means that we could refactor our code wrapping the ApplicationContext usage in a try-with-resource block. We let Java taking care of calling close() when the context goes out of scope.

The resulting code is something like that:
try (ClassPathXmlApplicationContext ctx =
        new ClassPathXmlApplicationContext("spring/app-context.xml")) {
    MessageRenderer mr = ctx.getBean("renderer", MessageRenderer.class);
    mr.render();
}
I pushed on GitHub my patched code for both HelloWorldSpringDI and HelloWorldSpringAnnotated, that is, the other class suffering for the same lack of application context closing.

Go to the full post

The Gradle nature of Pro Spring 5

I've started reading Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools. It looks fun and interesting. The first issue I had was on having its code from GitHub working in my STS IDE. Here are a few notes on what I did to solve it, if someone else stumble in the same place.

First step was easy. After navigating through the File menu in this way ...
File
    Import...
        Git
            Project from Git
                GitHub
                    Clone URI
I entered the repository address: https://github.com/Apress/pro-spring-5.git

Second step should have been even easier. Add Gradle Nature to the project. It's just a matter of right-clicking on the project, and from the menu select
Configure
    Add Gradle Nature
Unfortunately, there are a few version numbers in the main "build.gradle" file for the project that are not currently working, leading to a number of annoying exceptions like:
A problem occurred evaluating project ':chapter02:hello-world'.
Could not resolve all files for configuration ':chapter02:hello-world:compile'.
Could not resolve org.springframework:spring-context:5.0.4.BUILD-SNAPSHOT.
Required by:
    project :chapter02:hello-world
Could not resolve org.springframework:spring-context:5.0.4.BUILD-SNAPSHOT.
Could not get resource ...
Could not HEAD ...
Read timed out
org.gradle.tooling.BuildException: Could not run build action ...
I tried to minimize the impact of my changes on the original configuration file.

Basically, when I had an issue, I moved to a newer version, preferring a stable RELEASE to BUILD-SNAPSHOT's or release candidates.

I also had a problem for
io.projectreactor.ipc:reactor-netty:0.7.0.M1
That I moved to
io.projectreactor.ipc:reactor-netty:0.7.9.RELEASE
More complicated was the problem for chapter five. It looks that I have something wrong for aspectJ in my configuration. I didn't to spend too much time on that now, assuming that it would lead to to some detail in that specific area. So I opened the aspectj-aspects gradle build file and commented the dependency to gradle-aspectj and the plugin application for aspectj itself.

Now my build.gradle for chapter five - aspectj-aspects has these lines in:
}

    dependencies {
//      classpath "nl.eveoh:gradle-aspectj:2.0"
    }
}
// apply plugin: 'aspectj'
Sure enough, it won't compile. Still, I finally added the gradle nature to the project and I can go on reading the book. I'll take care of that issue when I'll reach chapter five.

I've forked the original APress repository, and there I pushed my variants for the main build.gradle file, and the one for chapter 5, aspectj-aspects. See there for details.

Go to the full post

Using JdbcTemplate in Spitter Web App

In the previous post I developed a CommandLineRunner Spring App to show how to use JdbcTemplate for simplify the JDBC access to an embedded instance of a H2 database. Here I port the changes to the Spittr Web App I have built up previously.

Actually, there is not much to say. There is some inconsistency between the two apps that spiced up the process, but nothing really complicated. I'd say the most interesting part is in the POM file. Here I removed, whenever it was possible, the versioning for each single dependency, relying instead on the parent element, where they are defined.
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
    <relativePath />
</parent>
However, for some reason, Spring could not find the version for the JSP dependency, so I kept it as before
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>${jsp.version}</version>
    </dependency>
And left the versioning for it among the properties.
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <jsp.version>2.3.1</jsp.version>
</properties>
I pushed the new version of Spittr on GitHub.

Go to the full post

Spring and JdbcTemplate

Let's say that we want to write a Spring application that requires some simple database activity. We decide to use an embedded database, H2 and, instead of choosing a higher level persistency framework, we decide to go for the JDBC support, mediating it with JdbcTemplate, a Spring class aimed at simplifying its use.

I create a Spring project using the STS wizard (File >> New >> Spring Starter Project).
Since I want to use JDBC and the H2 database support, I select these two options from the dependencies page:
From database schema to POJOs

In the source/main/resources folder, I put a file named schema.sql, this is enough for Spring, that knows it has to get it and run it at startup, so there I put the SQL commands to create my tables. I create two tables, spitter and spittle, connected by the id of the first, that is a foreign key in the second.

The tables defined in the database are reflected in a couple of plain old Java classes, Spitter.java and Spittle.java, having as fields what in the tables are the columns.

There is one thing that I think is interesting. The SQL spittle table has, among the other fields, a datetime, postedTime. We need to find a counterpart for it in the Java world. Since we are not interested here in time zones and the such, just in a plain timestamp, I decided to use Java 8 java.time.Instant.

That's it. If the SQL stuff is simple, and I have just a couple of tables, I could give it for done. To see that, I have created a basic version for the SpringBootApplication that implements the CommandLineRunner interface:
public class UsingJdbcApplication implements CommandLineRunner {
    private static final Logger log = LoggerFactory.getLogger(UsingJdbcApplication.class);

    @Autowired
    private JdbcTemplate template;  // 1

    public static void main(String[] args) {
        SpringApplication.run(UsingJdbcApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Long counter = template.queryForObject("SELECT count(id) FROM spitter", Long.class);  // 2
        log.info("Rows on spitter table: " + counter);

        log.info("Pushing a spitter in");
        Object[] admin = new Object[] { "admin", "password", "Admin", "admin@example.dd" };
        template.update("INSERT INTO spitter(username, password, fullname, email) VALUES(?, ?, ?, ?)", admin);  // 3

        template.query("SELECT * FROM spitter WHERE username = ?", new Object[] { "admin" },  // 4
                (rs, rowNum) -> new Spitter(rs.getLong("id"), rs.getString("username"), rs.getString("password"),
                        rs.getString("fullname"), rs.getString("email"), rs.getBoolean("updateByEmail")))
                .forEach(spitter -> log.info("Spitter: " + spitter.toString()));
    }
}
1. Sort of magic. We ask to Spring to wire this JdbcTemplate object. Since the H2 jar is in the classpath, it understands it has to use it as database. We don't provide any settings, and it uses a whole bunch of defaults. Usually not a good idea for production code, but very handy for prototyping.
2. Let's run a simple query that returns a single value. This line shows that actually Spring has initialized the database using the script named schema.sql that it found in the main resources folder. And how JdbcTemplate makes our life so much simpler. Notice that the queryForObject() method has a first parameter that is the SQL statement we want to run, and the second one that is the type for the expected return value.
3. A parametrized update(). Its first parameter is a parametrized JDBC SQL insert statement, the second one a vector of objects containing the values that we want to usein the query.
4. Something a bit more complicated. The query() method execute a query in a way similar to the update() seen above but, as third parameter, it accepts a lambda function that maps each row in the resulting resultset to a new Spitter object. We tipically have no use for the rowNum parameter, just access any resultset field we need.
This query() call returns a list of Spitter. On that list we apply a forEach() so that each element in the list is logged. Actually, here we are expecting just one Spitter, however this is a common pattern that we should learn to recognize and use.

Running the Spring Boot App, I can see in the console window the expected log.

Repositories and configuration

Usually we don't want to scatter SQL statements all over our Java code. So we create two interfaces, one for Spittle and one for Spitter, that act as repository for them, and then we implement them for our JDBC provider.
The two classes are quite similar. Let's see some parts of JdbcSpittleRepository, that is a tad more complicated.
// ...
private static final String SELECT = "select sp.id, s.id as spitterId, s.username, s.password, s.fullname, s.email, s.updateByEmail, sp.message, sp.postedTime from Spittle sp, Spitter s where sp.spitter = s.id";
private static final String SELECT_RECENT = SELECT + " order by sp.postedTime desc limit ?";

public List<Spittle> findRecent(int count) {
    return template.query(SELECT_RECENT, new SpittleRowMapper(), count);  // 1
}

// ...
private long insertSpittle(Spittle spittle) {
    SimpleJdbcInsert insert = new SimpleJdbcInsert(template).withTableName("Spittle");  // 2
    insert.setGeneratedKeyName("id");
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("spitter", spittle.getSpitter().getId());
    args.put("message", spittle.getMessage());
    args.put("postedTime", Timestamp.from(spittle.getPostedTime()));
    long spittleId = insert.executeAndReturnKey(args).longValue();
    return spittleId;
}

// ...
private static final class SpittleRowMapper implements RowMapper<Spittle> {  // 3
    public Spittle mapRow(ResultSet rs, int rowNum) throws SQLException {
        long id = rs.getLong("id");
        String message = rs.getString("message");
        Instant postedTime = rs.getTimestamp("postedTime").toInstant();
        long spitterId = rs.getLong("spitterId");
        String username = rs.getString("username");
        String password = rs.getString("password");
        String fullName = rs.getString("fullname");
        String email = rs.getString("email");
        boolean updateByEmail = rs.getBoolean("updateByEmail");
        Spitter spitter = new Spitter(spitterId, username, password, fullName, email, updateByEmail);
        return new Spittle(id, spitter, message, postedTime);
    }
}
1. Almost an innocent JdbcTemplate wrapper to a JDBC query, if we don't pay much attention to the second parameter, that would convert the ResultSet coming from the SQL select in a list of Spittles. See the SpittleRowMapper below for details.
2. Here we see how SimpleJdbcInsert helps us in writing readable code when we want to insert a row in a table, in the case where the database will take the burden of generating a key for us, and we need to return it to the caller. After specifying the table we are working on, we set the name of the field that is a generated key, and then, as a map, the field names and associated values. Finally we have just to pass them to the SimpleJdbcInsert by executeAndReturnKey().
3. The SpittleRowMapper seen in action in (1). Its mapRow() method maps a single row from the underneath table in a Spittle object.

In some way, Spring has to configure these repositories, passing to them a viable JdbcTemplate object. In this app, it is done by JdbcConfig, annotated as a Spring Configuration class. It generates a few beans (in the Spring sense of the term) representing the DataSource, JdbcTemplate, the repositories, and also a transaction manager. We'll see them at work in the tester. It interesting seeing how the DataSource is set, when we don't rely on the default initialization by Spring.
@Configuration
public class JdbcConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScripts("schema.sql", "test-data.sql")
                .build();
    }
 
    // ...
This data source represents an embedded database, H2 type, that would run a couple of scripts at startup. We already seen the first one, schema.sql, here I added a second one, that contains a bunch of SQL insert for spitters and spittles rows.

Testing

There are a couple of JUnit test, one for Spitter the other one for Spittle repository. They are quite similar. Let's have a fast look at first one.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = JdbcConfig.class)  // 1
public class JdbcSpitterRepositoryTest {
    @Autowired
    JdbcSpitterRepository spitterRepository;  // 2

    // ...
    @Test
    @Transactional  // 3
    public void findAll() {
        List<Spitter> spitters = spitterRepository.findAll();  // 4
        assertEquals(4, spitters.size());
        assertSpitter(0, spitters.get(0));
        assertSpitter(1, spitters.get(1));
        assertSpitter(2, spitters.get(2));
        assertSpitter(3, spitters.get(3));
    }

    //...
}
1. Here I'm saying to Spring to fetch the JdbcConfig class and use it to configure itself for testing.
2. Thanks to (1) we can ask to Spring to autowire the spitter repository.
3. Having defined a PlatformTransactionManager, we can use it to keep very simple the transaction management. A transaction is started and completed, eventually rolled-back, behind the curtains.
4. The spitters come from the test-data.sql called at startup by JdbcConfig dataSource().

Reference: Hitting the database with Spring and JDBC, from Spring in Action, Fourth Edition by Craig Walls, chapter ten.

This complete Spring application is on GitHub.

Go to the full post

A view on Spring error messages

We have seen in the previous post how to let Spring validate the data coming from the view against a bean (in the sense of a plain Java one) defined in the model of our web app, thanks to the Java Validation protocol, in the Hibernate implementation. Now we see how to let the resulting view acknowledge the errors, so that the user could correct them.

First thing, let's slightly change the controller, so that a empty spitter object is passed to the register view when we GET it.
@RequestMapping(value = "/register", method = GET)
public String showRegistrationForm(Model model) {
    model.addAttribute(new Spitter());
    return "registerForm";
}
Spring sees we want to push on the model a new Spitter. By default it names it as the class, first letter lowercase, "spitter".

The registerForm JSP now changes to use it. Our job is made simpler by using a Spring tag library, form, that provides a nice support for manage HTML forms. I associated the "sf" prefix to it, and I am going to use only a few of the many functionality it makes available.
I have rewritten the form in this way:
<sf:form method="POST" commandName="spitter">  <!-- 1 -->
  First Name: <sf:input path="firstName" />    <!-- 2 -->
 <sf:errors path="firstName" />         <!-- 3 -->
 <br />
  Last Name: <sf:input path="lastName" />
 <sf:errors path="lastName" />
 <br />
  Email: <sf:input path="email" />
 <sf:errors path="email" />
 <br />
  Username: <sf:input path="username" />
 <sf:errors path="username" />
 <br />
  Password: <sf:password path="password" />    <!-- 4 -->
 <sf:errors path="password" />
 <br />
 <input type="submit" value="Register" />
</sf:form>
1. Instead of using the standard HTML form, I used the Spring Form version. The attribute (in XML sense) commandName shows the name of the attribute that has to be used to populate the fields in the form. If we arrive here from GETting "/register", spitter would be empty. If we arrive here POSTing "/register", after detecting validation errors, spitter would contain the fields as entered by the user.
2. The Spring Form input tag uses its attribute path to select the field from the commandName object that is associated to it. In this case, firstName.
3. The Spring Form errors tag is just like a plain text label, but linked to the Spring Validation Errors object generated by the validation process - when available. Again, its path attribute refers to the specific field in it.
4. The Spring Form password tag is a sort of Spring aware HTML input-password tag.

And with this, we could claim that the job is done. However, we would like to have a better control on the messages showed to the user in case of errors. That is very easily done, as it is providing localized version of those messages.

To do that I have created a file named ValidationMessages.properties in the src/main/resources folder, and its ValidationMessages_it.properties counterpart for its Italian version. Each line represents an error message. For instance:
firstName.size=First name must be between {min} and {max} characters long.
Notice the words included in curly braces. These are variables that Spring will resolve when creating the actual message.

I am going to use the custom messages in the Spitter class:
@Size(min = 2, max = 30, message="{firstName.size}")
private String firstName;
Now, if I push the Register button without entering anything, I get:
(Notice that there is no error message for the empty email address - no email is considered a valid alternative)

In a browser localized for Italy, I have this alternative result:
Reference: Rendering web views, from Spring in Action, Fourth Edition by Craig Walls. Chapter six.

I have pushed the project changes to GitHub.

Go to the full post

Using tha Java Validation API

The user registration shown in the previous post has one very visible issue, there is no validation at all. The user could enter whatever value in each required field and the web app happily register it. Using Java Validation we could easily solve this problem.

We need to add an implementation of the javax.validation validation API, the Hibernate validator is a good candidate. So I add its dependency to my Spring Web App POM configuration file:
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>
Then I modify the Spitter bean (in the sense of plain Java Bean), annotating its properties so to impose the rules I want the registration to observe.
For instance, I want the first name to be not null and having a size in [2 .. 30]:
@NotNull
@Size(min = 2, max = 30)
private String firstName;
NotNull and Size are standard Java Validation annotations. Since I use the Hibernate implementation of that JSR, I can use a non-standard, hibernate specific annotation to enforce that the email field represents a valid e-mail address:
@NotNull
@Email
private String email;
These checks are enforced in the controller. I change the processRegistration() method in this way:
@RequestMapping(value = "/register", method = POST)
public String processRegistration(@Valid Spitter spitter, Errors errors) {  // 1
    if (errors.hasErrors()) {  // 2
        return "registerForm";
    }

    spitterRepository.save(spitter);  // 3
    return "redirect:/spitter/" + spitter.getUsername();
}
1. The Spitter input parameter is tagged with the Valid Java Validation annotation, in this way I'm saying to the Hibernate Validator to check its fields accordingly to the annotations specified on this data members. Any error on the validation is pushed in the Errors object.
2. In a real app I would do much more than simply check if there is any validation error. For sure we need to say something to the user, so to help him to correct his mistakes. And it would be probably a good idea to log them.
3. Only if no validation error is detected we go on saving the user and giving a confirmation to the caller.

Reference: Validating form, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section 4.2.

The complete Java Spring Web App project is on GitHub.

Go to the full post

Spitter registration

We need to provide a way to let people register to our spittr web application, this is done here relying on the support offered by the Spring framework, that easily support the forms, giving a natural way for processing them.

The Model

A registered user is defined as a Spitter:
public class Spitter {

    private Long id;

    private String username;
    private String password;
    private String firstName;
    private String lastName;
    private String email;
    // ...
}
We'll need to check for equality on different Spitters, so we need to override both equals() and hashCode(). I did it using Objects.equals() and Objects.hash() in their implementions. I feel they helps to keep the code compact and readable without using external libraries.

We'll have a repository where storing our spitters, but we don't need to fix its type here, just the interface that each spitter repository has to implements:
public interface SpitterRepository {
    Spitter save(Spitter spitter);
    Spitter findByUsername(String username);
}
Actually, just to do some smoke testing, it is nice to have a concrete repository to play with:
@Repository
public class JdbcSpitterRepository implements SpitterRepository {
    @Override
    public Spitter save(Spitter spitter) {
        // TODO: actual implementation
        return spitter;
    }

    @Override
    public Spitter findByUsername(String username) {
        // TODO: actual implementation
        return new Spitter(username, "password", "John", "Doe", "jdoe@somesite.dd");
    }
}
I assumed it will be refactored in future to become a real JDBC repository, hence its name. Notice that the class is annotated as Spring repository.

Data Configuration

Having introduced a new repository in the web app, we should say to Spring how to get it. To do that I added a bean (in the sense of Spring Bean) in the already existing DataConfig java class, annotated as Spring configuration.
@Configuration
public class DataConfig {
    // ...

    @Bean
    public SpitterRepository spitterRepository() {
        return new JdbcSpitterRepository();
    }
}
The View

The user enters data filling a simple HTML form, something like that:
<form method="POST">
    First Name: <input type="text" name="firstName" /><br />
    Last Name: <input type="text" name="lastName" /><br />
    Email: <input type="email" name="email" /><br />
    Username: <input type="text" name="username" /><br />
    Password: <input type="password" name="password" /><br />
    <input type="submit" value="Register" />
</form>
Being no action attribute specified in the form tag, the post is done referring to the same URL accessed originally. Not much more to say on this part, you could see the full registerForm.jsp file on GitHub.

We'll also have a way to show a registration, accessing profile.jsp. Our Spring web app should take care of putting in a variable named spitter, an instance of the above discussed Spitter class, that represents the currently registered user. So, to display it, using JSP EL, we'll write something like:
<c:out value="${spitter.username}" /><br />
<c:out value="${spitter.firstName}" />
<c:out value="${spitter.lastName}" /><br />
<c:out value="${spitter.email}" />
The Controller

As usual, the controller keeps model and view together. The Spitter controller reacts to calls based in "/spitter". We want it to convert a call to "/spitter/register" showing the register form view or redirecting it to /spitter/xxx, where xxx is the username, accordingly to the HTTP command used. GET is for the first one, POST for the second. Any "/spitter/xxx" GET call will drive to the profile view.
@Controller
@RequestMapping("/spitter")
public class SpitterController {  // 1
    private SpitterRepository spitterRepository;  // 2

    public SpitterController(SpitterRepository spitterRepository) {
        this.spitterRepository = spitterRepository;
    }

    @RequestMapping(value = "/register", method = GET)  // 3
    public String showRegistrationForm() {
        return "registerForm";
    }

    @RequestMapping(value = "/register", method = POST)  // 4
    public String processRegistration(Spitter spitter) {
        spitterRepository.save(spitter);
        return "redirect:/spitter/" + spitter.getUsername();
    }

    @RequestMapping(value = "/{username}", method = GET)  // 5
    public String showSpitterProfile(@PathVariable String username, Model model) {  // 6
        Spitter spitter = spitterRepository.findByUsername(username);  // 7
        model.addAttribute(spitter);
        return "profile";
    }
}
1. This class is annotated as Spring controller, and it maps calls rooted in "/spitter".
2. We are going to use a repository that has to implement the SpitterRepository.
3. Maps a GET to "/spitter/register" to the registerForm view.
4. Redirects a POST to "/spitter/register" to the "/spitter/xxx" view. A spitter is expected as parameter, and it is going to be saved to the repository before the redirect is performed.
5. Maps a GET to "/spitter/xxx" to the profile view.
6. The username is extracted from the path by the PathVariable Spring binding annotation.
7. The repository is asked to give the spitter associated with the username, then we push it to the model.

Testing

The controller design has been driven by a couple of mock JUnit tests, using Mockito, defined in the SpitterControllerTest class. Besides, having provided a (fake) concrete implementation for the spitter repository, it is possible to run the web app and see its general behavior.

So, GETting "/spitter/register", we'll see the input form:
As soon as we push the Register button, a POST will be generated for the same URL. As seen above, the controller will redirect to "/spitter/jdoe"

So. Our app works. At least in a sort of demo mode. It is easy to spot how weak is, however. We are going to improve its robustness in the next post.

Reference: Processing forms, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section four.

Full Java Spring code available on GitHub.

Go to the full post

Showing a single Spittle

In our Spring Spitter Web App we want to display any single Spittle, just passing its id. This could be easily done accepting a request in the form of "spittles/show?id=42", following the style we have just used for getting a list of spittles, but we don't like it that much here, since we feel that "spittles/42" will be more expressive of the access to a resource.

Good for us, the Spring Framework has an handy approach to this problem.

Stripping down the view to the limit, what we want to get is something like this:
I have get it through a JSP page with JSTL tags, spittle.jsp, accessing an attribute named spittle that contains a Spittle object. Besides that minimal JSP, I have added a mock test to ensure the new functionality works fine. I have not much to say about them, and anyway you can see them on GitHub.

Let's see instead the new method added to SpittleController.
@RequestMapping(value = "/{spittleId}", method = RequestMethod.GET)
public String spittle(@PathVariable long spittleId, Model model) {
    model.addAttribute(spittleRepository.findOne(spittleId));
    return "spittle";
}
The spittle() method returns a string, the name of the view that should be generated for the caller, and expects two parameters, the spittle id and the model where we are going to push the Spittle object.
Notice that its first parameter is annotated as PathVariable, and notice also as the method is annotated as RequestMapping, with value set to a path. the path is built using curly brackets, signalling to Spring what is a variable that has to be extracted and used as parameter.
Being the class itself annotated as RequestMapping on "/spittles", the Spring framework is smart enough to understand what we want to do here.

Reference: Taking input via path parameters, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section 3.2.

You can find the code I have written on GitHub.

Go to the full post

Showing a paged list of spittles

As next step in our little Spring Web App, we are going to add in the view a way to display spittles specifying the "end" id, using the standard convention that it is excluded from the interval, and how many of them we want to show.

To do that, I firstly change the SpittleController so that its method mapped to the GET request method would accept the two parameters, giving them default values so that the previous functionality still works.
@RequestMapping(method = RequestMethod.GET)
public List<Spittle> spittles(
        @RequestParam(value = "max", defaultValue = MAX_ID) long max,
        @RequestParam(value = "count", defaultValue = DEFAULT_COUNT) int count) {
    return spittleRepository.findSpittles(max, count);
}
Actually, this version looks quite different from the previous one. The return value here is a List of Spittles, the one that was put in the spittleList model, and so we should wonder how Spring could guess which JSP call to generate a view.

However, internally, they are equivalent - if we don't consider how findSpittles() is called. The job of generating the JSP page and the attribute name is done by the mighty Spring framework, that understands that the first should be extracted from the URI passed as string to the class RequestMapping annotation, "/spittles", stripping the leading slash, and builds the latter from the method return type.

Just a minor nuisance. As the Java compiler states, "The value for annotation attribute RequestParam.defaultValue must be a constant expression". So I can't define MAX_ID converting on the fly the Long.MAX_VALUE to a String:
private static final String MAX_ID = Long.toString(Long.MAX_VALUE); // WON'T WORK!
I have to operate the conversion "by hand", instead.
private static final String MAX_ID = "9223372036854775807"; // Boring!
Besides the already existing shouldShowRecentSpittles() test, that should still work, I added a new shouldShowPagedSpittles() test that is very close to the other one but passes parameters to the (mock) call to the controller. See the tester on GitHub for more details.

Given the fake implementation I gave to the JdbcSpittleRepository, I can also see a result from the browser.
Reference: Accepting request input, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section three.

Full code for this Spring project is on GitHub.

Go to the full post

From Model to View through a Spring Controller

Another improvement to our little Spittr Spring Web App. We'll fake a JDBC model, create a controller that would get some data from it and pass it to the view, a JSP page that uses EL to access the attribute.

In the end we want to display to the user a very simple web page like this one:
enter in the details of the JSP page, you can find it in my GitHub repository, I just mention the fact that the controller puts a list of Spittles in an attribute named spittleList, and the page reads it by EL looping through a core forEach JSTL tag.

The data is moved around in a POJO, spittr.Spittle, that contains the data identifying a spittle. There is not much to say about it, besides it has its own equals() and hashCode() implementation, that are respectively based on the equals() and hash() methods from the utility class Objects:
// ...

public class Spittle {
    private final Long id;
    private final String message;
    private final LocalDateTime time;
    private Double latitude;
    private Double longitude;

 // ...

    @Override
    final public boolean equals(Object that) {  // 1
        if(this == that) {
            return true;
        }
        if (!(that instanceof Spittle))
            return false;

        Spittle other = (Spittle) that;
        return this.id == other.id && Objects.equals(this.time, other.time);  // 2
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, time);  // 3
    }
}
1. I do not expect the class Spittle to be extended. In case a subclass would be created, it's implementation won't modify the assumption that two spittles are considered equals if they have same id and creation timestamp, as stated in this equals() method. To enforce it, I mark it as final.
2. Using Objects.equals() saves me from the nuisance of checking the time component against null, keeping the code more readable.
3. Since id and time define Spittle equality, it makes sense using them to determine the hash code.

I have written a test case to ensure the Spittle class works as I expected. There is nothing very interesting in it and, as usual, you can look it on GitHub.

The model will be based on the interface spittr.data.SpittleRepository:
public interface SpittleRepository {
    List<Spittle> findRecentSpittles();

    List<Spittle> findSpittles(long max, int count);

    Spittle findOne(long id);

    void save(Spittle spittle);
}
The idea is creating a JDBC repository, for the moment I have faked it. Here is its findSpittles() method:
@Repository
public class JdbcSpittleRepository implements SpittleRepository {
    // ...
    @Override
    public List<Spittle> findSpittles(long max, int count) {
        List<Spittle> result = new ArrayList<>();
        for (long i = 0; i < count; i++) {
            result.add(new Spittle(i, "Message " + i, LocalDateTime.now(), 1.0 * i, 2.0 * i));
        }

        return result;
    }
    // ...
}
The repository interface is used in the SpittleController to find spittles an put them as attribute to be consumed by the view.
@Controller
@RequestMapping("/spittles")
public class SpittleController {
    private SpittleRepository spittleRepository;

    @Autowired
    public SpittleController(SpittleRepository spittleRepository) {
        this.spittleRepository = spittleRepository;
    }

    @RequestMapping(method = RequestMethod.GET)
    public String spittles(Model model) {
        model.addAttribute("spittleList", spittleRepository.findSpittles(Long.MAX_VALUE, 20));
        return "spittles";
    }
}
I use the concrete repository to see what happens when the app actually runs on my tomcat server, however, the real testing is performed on the interface, using the mocking features included in Spring integrated to the mockito framework. For this reason I added this dependence to the application POM.
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>${mokito.version}</version>
    <scope>test</scope>
</dependency>
I also have to tell Spring where the repository is. For this reason I created a new configuration class, DataConfig, that simply returns the JdbcSpittleRepository as a bean. This configuration class is called by the already existing RootConfig, by importing it.
@Configuration
@Import(DataConfig.class)
public class RootConfig {
}
The web app works fine both running it "by hand" and through the mock test. So I pushed the code on GitHub.

Reference: Passing model data to the view, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section 2.3.

Go to the full post

Mock test for a Spring controller

Having built a simple Spring Web App, now I want to test its only controller. In the previous post I have done it "by hand", running a browser on its url and verifying that I actually get the expected page, now I use the mock testing support provided by the Spring framework.

Firstly I add to the pom file the Spring test dependency:
<properties>
 <!-- ... -->
 <spring-test.version>4.3.0.RELEASE</spring-test.version>
 <!-- ... -->
</properties>
<dependencies>
 <!-- ... -->
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>${spring-test.version}</version>
  <scope>test</scope>
 </dependency>
 <!-- ... -->
</dependencies>
Then I write a JUnit tester for my HomeController, following a simple pattern:
@Test
public void testHome() {
    HomeController controller = new HomeController();  // 1
    try {
        MockMvc mockMvc = standaloneSetup(controller).build();  // 2
        mockMvc.perform(get("/")).andExpect(view().name("home"));  // 3
    } catch(Throwable t) {  // 4
        // ...
    }
}
1. I create an object from my controller.
2. I build a mock MVC test object from my controller.
3. I perform a mock HTTP GET command for "/" and verify I get back a view named "home".
4. There is not much control on what a MockMvc would throw in case something goes wrong, we have to be ready to catch any possible throwable.

It looks very clean and simple. However I had a problem in the form of this exception:
java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig at
 org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.
  initWebAppContext(StandaloneMockMvcBuilder.java:329)
...
The fact is that I specified in the POM a dependency for the ancient javax.servlet servlet-api 2.5, while I should use at least a version 3 to get the job done. For my purposes, 3.1.0 is more than enough.
Pay attention to the artifact name change that happened right at the time of moving from 2 to 3. Now the servlet api is identified by the id javax.servlet-api.

Let's slightly improve my web app. We want now that the controller returns the home view while getting both root and "/homepage".

I add another test case, testHomeExtra(), that is just like testHome() but it performs a GET on the other URI.
As expected, it fails, giving as reason, "No ModelAndView found".

I change my controller, specifying at class level which URI's it has to manage:
@Controller
@RequestMapping({"/", "/homepage"})
public class HomeController {
    @RequestMapping(method = GET)
    public String home(Model model) {
        return "home";
    }
}
And now I have green light while testing.
Reference: Building Spring web applications, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section two, Testing the controller.

I have committed the project changes to GitHub.

Go to the full post

Spittr - a Spring Web Application

I am going to create a Spring Web Application using as IDE the Spring Tool Suite, friendly known as STS, version 3.8.4, without the Spring Boot support. To do that, we can theoretically use the wizard named Spring Legacy Project, but the support from Pivotal is not so strong as I expected and the result needs so many adjustments that in the end I opted to use the basic Maven Project wizard instead.

I selected the archetype with artifact id maven-archetype-webapp from the group id org.apache.maven.archetypes, gave a group and artifact id to my app, and let the wizard go.

Annoyingly, I got an error and a warning:
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path means that the generated POM lacks that dependency. Actually, opening the POM, I see that it lacks almost any dependency, and the only one present, JUnit, refers to the old 3.8.1 version.
The warning points out to the fact that the wizard was designed to support the ancient Java 5, and we'd probably better adjust the project also in this area.

I changed the POM adding these properties and dependencies:
<properties>
 <java.version>1.8</java.version>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <jsp.version>2.2</jsp.version>
 <jstl.version>1.2</jstl.version>
 <servlet.version>2.5</servlet.version>
 <spring-framework.version>4.3.7.RELEASE</spring-framework.version>
 <junit.version>4.12</junit.version>
</properties>

<dependencies>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>${spring-framework.version}</version>
 </dependency>
 <dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
  <version>${jstl.version}</version>
 </dependency>
 <dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>${servlet.version}</version>
  <scope>provided</scope>
 </dependency>
 <dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>${jsp.version}</version>
  <scope>provided</scope>
 </dependency>
 <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>${junit.version}</version>
  <scope>test</scope>
 </dependency>
</dependencies>
To get rid of the warning, I opened the Project Properties and in the page Project Facets I set Java to 1.8.
The wizard created an index.jsp page in the webapp folder. I removed it and I created instead a home.jsp in the WEB-INF views subfolder. This JSP page uses the JSTL core library and a style sheet named style.css from the resources folder. All of these details are not much relevant with the job of creating the web app, so I won't say more on them. For more reference see the full source code on GitHub.

More interestingly, let see the dispatching stream of our application. We are going to use the MVC Spring structure, at the center of it there is the DispatcherServlet that decides how to manage the user requests to generate appropriate responses. From our side, we provide a Java class to configure it. The job is simplified by extending AbstractAnnotationConfigDispatcherServletInitializer and a couple of configuration classes. Our class would be automatically seen by Spring and used to configure the DispatcherServlet.

At the end of all this dispatching and configuring, we'll have a tiny web app that would have just the home.jsp as available view.
Here is the project structure:

Our initializer should override three methods from its super class:
public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {  // 1
        return new String[] { "/" };
    }

    @Override
    protected Class[] getRootConfigClasses() {  // 2
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class[] getServletConfigClasses() {  // 3
        return new Class[] { WebConfig.class };
    }
}
1. It returns the paths that the DispatcherServlet will be mapped to. We are mapping to the root directory, handling all the requests to our app.
2. It returns the configuration classes for the application context created by the ContextLoaderListener. You would usually find here middle and data tier components. In this trivial version of our app, there will be nothing in here. I still delegate to RootConfig, even if it won't do anything, to keep the code clean. More brutally, I could have let this method return null.
3. This is about the standard DispatcherServlet configuration. Controllers, view resolvers and handler mappings are returned by this method.

Let's see our WebConfig:
@Configuration  // 1
@EnableWebMvc  // 2
@ComponentScan("spittr.web")  // 3
public class WebConfig extends WebMvcConfigurerAdapter {  // 4
    @Bean
    public ViewResolver viewResolver() {  // 5
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();  // 6
    }
}
1. It is a Spring configuration class.
2. This is a typical way to say that our app should enable the Spring MVC.
3. Ask Spring to enable component scanning from the passed package.
4. We extends our configuring class from this configurer adapter provided by Spring
5. We create a very simple view resolver that would set a prefix, the /WEB-INF/views/ folder, and a suffix, the jsp extension. In this way, a view named "home" would be resolved to "/WEB-INF/views/home.jsp".
6. We say to the DispatcherServlet that it should delegate to static resources the requests it gets.

Then I created a controller in the spittr.web package, so to actually provide something to do to WebConfig:
@Controller
public class HomeController {
    @RequestMapping(value = "/", method = GET)
    public String home(Model model) {
        return "home";
    }
}
Very simple, it just maps the GET requests to root returning the string "home".

Now we can Run on Server our app for the first time.
Reference: Building Spring web applications, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section one, Getting started with Spring MVC.
Full code is available on GitHub.

Go to the full post

The Spring AOP around advice

I am going to add a plain Spring component to my Spring Boot practice web application. The interesting part of it is that I am developing an AOP aspect that is designed to give a few advices in conjunction with a stated join point.

Here is the component, nothing fancy.
@Component
public class PopConcert implements Performance {
    private static final Log log = LogFactory.getLog(PopConcert.class);

    @Override
    public boolean perform(int level) throws PerformanceException {
        if (level > 8) {
            log.info("A nice gig");
            return true;
        } else if (level > 6) {
            log.info("Not in the mood tonight");
            return false;
        } else {
            throw new PerformanceException("Drunk drummer");
        }
    }
}
Its only method returns a boolean or throws and exception, when something really unusual happens.

I have already talked about Spring AOP with aspects in a previous post, let's see now a sligher more complex aspect, that define more advices:
@Aspect
public class Audience {
    private final static Log log = LogFactory.getLog(Audience.class);

    @Pointcut("execution(boolean Performance.perform(int))")  // 1
    public void performance() {}
    
    @Before("performance()")  // 2
    public void silenceMobile() {
        log.info("Silencing mobile phones");
    }

    @Before("performance()")
    public void takingSeat() {
        log.info("Taking seat");
    }

    @AfterReturning("performance()")  // 3
    public void applaude() {
        log.info("Applauding");
    }

    @AfterThrowing("performance()")  // 4
    public void complain() {
        log.info("Demanding a refund");
    }
}
1. Here I define a pointcut. Not a strict necessity, but it saves some typing, and should improve the code readability. I named it "performance()" and I state it refers to the method perfmorm() defined in the Performance interface. All the advices below refer to it.
2. I have a couple of before advices, as the AspectJ annotation says. Here the point is that I can have more methods associated to the same advice.
3. After the execution of the join point has been completed, Spring should follow this advice.
4. If an exception break the join point run, this advice should be followed by Spring.

As usual I let the magic of putting together everything to be performed by a Spring configuration class:
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackageClasses = Performance.class)  // 1
public class ConcertConfig {
    @Bean
    public Audience audience() {  // 2
        return new Audience();
    }
}
1. In this case the only component in the hierarchy based on Performance is the PopConcert class we have seen above.
2. This method let the aspect spring to life.

I have written a JUnit testcase to see it at work:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConcertConfig.class)
public class PopConcertTest {
    @Autowired
    private Performance performance;

    @Test
    public void testPerform() {
        try {
            assertTrue(performance.perform(11));
        } catch (PerformanceException pe) {
            fail("Unexpected PerformanceException: " + pe.getMessage());
        }
    }

    @Test(expected=PerformanceException.class)
    public void testPerformBadly() throws PerformanceException {
        performance.perform(2);
    }
}
Running it I have the greenlight and I can see in the log that the aspect has done its job

When an exception occurs in the join point, the AfterThrowing advice is executed, and when all works fine, the AfterReturning is called:
That's nice. But let's see how put all this stuff in a single advice.

AspectJ Around

The around advice gets its join point as an annotation parameter, as usual, and it gets in input, as a parameter a reference to a ProceedingJoinPoint. What we have to do is just specifying in its body what we want to be executed before, after, and even in case of exception. In a natural way, but with a few caveats.
@Aspect
public class AudienceAround {
    private final static Log log = LogFactory.getLog(AudienceAround.class);

    @Around("execution(boolean Performance.perform(int))")
    public Object watchPerformance(ProceedingJoinPoint pjp) throws PerformanceException {  // 1
        Object result = null;  // 2
        try {
            log.info("Ensure mobile is off");
            log.info("Take place");
            result = pjp.proceed();  // 3
            log.info("Cheer");
        } catch (Throwable t) {  // 4
            log.info("Demand a refund: " + t.getMessage());
            if (t instanceof PerformanceException) {
                throw ((PerformanceException) t);  // 5
            } else {
                throw new PerformanceException("Unexpected:" + t.getMessage());  // 6
            }
        }
        return result;
    }
}
1. Our join point throws an exception, so also its Around advice has to throw it too.
2. When it does not throw an exception, it returns a value, so we have to be prepared to to the same. Notice that it returns a primitive type, but the proceed() method in ProceedingJoinPoint returns an object. Some boxing and unboxing is expected.
3. We are passing the control to Spring, that is going to give it to the specified join point.
4. If the join point throws an exception, we'll get a Throwable. It is more or less the same issue we have in (2). Since Spring doesn't know beforehand what throws it, it falls back to the mother of all exceptions.
5. It won't be a good idea to swallow the exception, the caller wants to get it. So here I rethrow it.
6. If I have done everything right, this should never happen.

I have swapped the beans in ConcertConfig. Now a AudienceAround is seen by Spring as the aspect it should care about. I run again the tester and nothing changes, just the log, and in the right way:
Reference: Aspect-oriented Spring, from Spring in Action, Fourth Edition by Craig Walls. Chapter four.
Repository on GitHub: See the JUnit test case, and browse the concert package.

Go to the full post

Spring Prototype Bean

By default, the Spring framework creates beans as singleton. However we can instruct it to create a different bean each time a request is made specifying the prototype mode. Another couple of ways are available, to create a bean for each request or session.

I have written a simple JUnit test to see the difference between prototype and singleton.

I have created two empty classes, both of them implementing the empty interface Scoping:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class UniqueThing implements Scoping {
}

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad implements Scoping {
}
The SCOPE_SINGLETON scope is the default, so usually you won't see it explicitly set in production code. Here is just to remark its existence.
The class Notepad, marked with SCOPE_PROTOTYPE is the interesting stuff.

This is what normally happens with beans:
@Test
public void testSingleton() {
    UniqueThing thing1 = context.getBean(UniqueThing.class);
    UniqueThing thing2 = context.getBean(UniqueThing.class);
    assertSame(thing1, thing2);
}
When I get a bean - here I get them through the Spring application context - the same bean is returned.

But if the bean is marked as SCOPE_PROTOTYPE, we have a different behavior:
@Test
public void testPrototype() {
    Notepad notepad1 = context.getBean(Notepad.class);
    Notepad notepad2 = context.getBean(Notepad.class);
    assertNotSame(notepad1, notepad2);
}
Each bean is a newly created one!

Reference: Advanced wiring, from Spring in Action, Fourth Edition by Craig Walls. Chapter three, section four, Scoping beans.

I pushed the code I created on GitHub, see the scoping package and the associated JUnit test case.

Go to the full post

Autowiring ambiguity

I have a hierarchy of Spring Components rooted in the interface Dessert. Let's see what could go wrong when I try to autowire on them.

Here is the base interface:
public interface Dessert {
    default double getPrice() {
        return 0;
    }
}
It has three empty implementing classes named Cake, Cookies, and IceCream. For instance, here is the third one:
@Component
public class IceCream implements Dessert {
}
In my test case, I autowire a Dessert that I am going to use in the tests, like this:
@Autowired
Dessert dessert;

@Test
public void test() {
    assertThat(dessert.getPrice(), is(0.0));
}
Spring has to know which Dessert to create and wire, and this could be done by class configuration. In this case, the tester should know it, by annotating as SpringApplicationConfiguration the class, that should be defined and annotated as a Spring Configuration file, like this:
@Configuration
@ComponentScan(basePackageClasses = Dessert.class)
public class DessertConfig {
}
Do not forget to specify the component scan annotation, otherwise Spring won't see the beans, and would complain something like:
org.springframework.beans.factory.BeanCreationException:
 Error creating bean with name 'dd.sia.restaurant.DessertTest':
 Injection of autowired dependencies failed; nested exception is
  org.springframework.beans.factory.BeanCreationException:
Could not autowire field:
 dd.sia.restaurant.Dessert dd.sia.restaurant.DessertTest.dessert;
nested exception is
 org.springframework.beans.factory.NoSuchBeanDefinitionException:
 No qualifying bean of type [dd.sia.restaurant.Dessert] 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)}
However, activating the ComponentScan is only the first step. Since we have three Components based on Dessert, we should say to Spring which one to choose. If we don't we are going to have a different, albeit similar, exception:
org.springframework.beans.factory.BeanCreationException:
 Error creating bean with name 'dd.sia.restaurant.DessertTest':
 Injection of autowired dependencies failed; nested exception is
 org.springframework.beans.factory.BeanCreationException:
Could not autowire field:
 dd.sia.restaurant.Dessert dd.sia.restaurant.DessertTest.dessert;
nested exception is 
 org.springframework.beans.factory.NoUniqueBeanDefinitionException:
 No qualifying bean of type [dd.sia.restaurant.Dessert] is defined:
 expected single matching bean but found 3: cake,cookies,iceCream
One way to solve this issue is annotating a Component as primary:
@Component
@Primary
public class Cake implements Dessert {
}
In this way, Spring knows that Cake is the Dessert it should pick up when it is in doubt.

We can always bypass this default, specifying a default in the autowiring:
@Autowired
@Qualifier("cookies")
Dessert dessert;
Now Spring knows that we want cookies and won't pay attention to the primary annotation.
If we don't like the name generated by Spring for the component, that is, the class name but starting lowercase, we can set it as we please, using again the Qualifier annotation, this time on the Component itself. So, for instance, I can qualify Cookies as "yummy" and use this qualification when autowiring to ask Spring to select it.

Reference: Advanced wiring, of Spring in Action, Fourth Edition by Craig Walls. Chapter three, section three, Addressing ambiguity in autowiring.

I pushed the code I have written on this stuff to GitHub. See the package restaurant for the Java classes in the Spring application, and the DessertTest for the JUnit testcase.

Go to the full post

Conditional bean

We have a bean in our application, but we want it instantiated only if some condition applies. To do that, we can use the Spring Conditional annotation, and let the framework decide if it has to be created or not.

Firstly, I create a very simple class in the restfun package:
public class MagicBean {
    @Override
    public String toString() {
        return "Magic Bean!";
    }
}
Then I create a class that implements the Condition Spring interface defining its matches() method.
public class MagicExistsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        return !env.containsProperty("lack_of_magic");
    }
}
I am saying that the condition hold when the environment does not contain the property named lack_of_magic.

And here is a configuration class that is putting all together in its method annotated as Conditional Bean, that specify the Condition class to verify if there is the condition for acting and that returns a new instance of the required class.
@Configuration
public class MagicConfig {
    @Bean
    @Conditional(MagicExistsCondition.class)
    public MagicBean magicBean() {
        return new MagicBean();
    }
}
To check if my magic bean works as expected, I have created a test case where I get it through both the Spring application context and directly by autowiring the specific bean.
@Test
public void testBeanInContext() {
    MagicBean mb = (MagicBean) context.getBean("magicBean");
    assertThat(mb.toString(), is("Magic Bean!"));
}

@Test
public void testBeanWired() {
    assertThat(magic.toString(), is("Magic Bean!"));
}
I played a bit around this code, changing the Condition and the tests, and enjoing the JUnit green light.
Until I felt satisfied, and I pushed the code to GitHub. See the source package and the JUnit test class for details.

I have written this post while reading the third chapter, Advanced wiring, of Spring in Action, Fourth Edition by Craig Walls. I ported the original code to a Maven Spring Boot Web project on the STS IDE, using AspectJ annotations instead of using the classic xml configuration. You should expect a few other minor changes in this code, basically because I wanted to have some fun too.

Go to the full post

Testing a Spring Profile Bean

We have seen in a previous post how to use the Spring Profile annotation to let the framework select which Bean to load at runtime. Let's see now how to test this behavior with JUnit.

Say that for some peculiar reason, my Web Application needs to have different beans in different environments. To address this delicate matter, we can create a Spring Configuration class that autowires objects implementing classes in the same hierarchy using a specific factory method.

For instance, here is how I could let Spring know that I want to create CharSequence Beans in an application:
@Configuration
public class CharSeqConfig {
    @Bean
    @Profile("dev")
    public CharSequence myString() {
        return new String("String");
    }

    @Bean
    @Profile("prod")
    public CharSequence myStringBuilder() {
        StringBuilder sb = new StringBuilder();
        sb.append("StringBuilder");
        return sb;
    }
}
When the "dev" profile is specified, Spring will use the myString() method when asked to wire a CharSequence bean. When in "prod", myStringBuilder() will be selected instead.

Testing this code with JUnit it is not much more complicated than the usual job we have already seen, basically, we have to specify which profile we want check using the ActiveProfiles annotation. However, usually we want to keep together the same tests for different profiles, and the nice thing is that we can easily do it, using static classes:
public class CharSeqConfigTest {
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes=CharSeqConfig.class)
    @ActiveProfiles("dev")
    public static class DevCharSeqTest {
        @Autowired
        private CharSequence charSeq;
        
        @Test
        public void testCharSeq() {
          assertThat(charSeq.toString(), is("String"));
        }
    }

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes=CharSeqConfig.class)
    @ActiveProfiles("prod")
    public static class ProdCharSeqTest {
        @Autowired
        private CharSequence charSeq;
        
        @Test
        public void testCharSeq() {
          assertThat(charSeq.toString(), is("StringBuilder"));
        }
    }
}
A minor nuisance is that we have to tell to STS which family of tests we want to run with JUnit:
However it pays off well.
Having seen the green light for both the profiles, I have pushed the code on GitHub, both for the configuration class and the JUnit test case.

I have written this post while reading the third chapter, Advanced wiring, of Spring in Action, Fourth Edition by Craig Walls. I ported the original code to a Maven Spring Boot Web project on the STS IDE, using AspectJ annotations instead of using the classic xml configuration. I have also done a few minor changes to keep the post as slim and readable as possible. Here I have used CharSequence as root for my bean hierarchy instead of DataSource. In this way my example code makes less sense, but it give some immediate satisfaction.

Go to the full post

Testing Spring autowiring in a more complex scenario

Let's improve the code seen in the previous Spring post. I add a CD player components that implements a media player interface and it is autowired to the CD component.

The media player interface has just a couple of methods
public interface MediaPlayer {
    String play();
    boolean hasMedia();
}
The second one checks if a media is inserted in the player and, you have probably guessed, it's there just to let me check if the autowiring of a CD is done as expected.

Then I have written a CD player, implementing this interface
@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

    @Autowired
    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }

    // ...
}
Notice that this class is annotated as Spring component, and its constructor is autowired. So we expect the framework will look for a suitable component in the CompactDisc hierarchy and wire it to the ctor parameter.

To have the wiring working we need to configure properly the component scan class, so I modify it in this way:
@Configuration
@ComponentScan(basePackageClasses = { CompactDisc.class, MediaPlayer.class })
public class CDPlayerConfig {
}
To test it, I have change the CDPlayerTest to use just a MediaPlayer.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
    @Autowired
    private MediaPlayer player;

    @Test
    public void testPlayerNotNull() {
        assertNotNull(player);
    }

    @Test
    public void testCDInserted() {
        assertTrue(player.hasMedia());
    }

    @Test
    public void testPlay() {
        assertEquals("Sgt. Pepper's Lonely Hearts Club Band by The Beatles", player.play());
    }
}
JUnit, using the Spring class runner, let the framework to do all the required wiring, in the app source code, and also here in the test. I ran it, and I was happy to get full green light.

I have written this post while reading the second chapter, Wiring beans, of Spring in Action, Fourth Edition by Craig Walls. While doing it, I have ported the original code to a Maven Spring Boot Web project on the STS IDE, using AspectJ annotations instead of using the classic xml configuration.
I have also done a few minor changes to keep the post as slim and readable as possible. For instance I removed the references to the brilliant System Rule library by Stefan Birkner & Marc Philipp.

Full code on github.
Have a look at the soundsystem package and the test file.

Go to the full post