Docker for Java developers

Today, it has been one of this days to learn something new. If you have seen any of my blogs, you should know that I like to write about what I am learning and I like to write it myself, I am not a fan of just paste resources or other people’s materials or tutorials but, sometimes, I need to make exceptions.

Today, I was learning Docker, you know, the container platform that allows us to deploy applications in containers in a easy way. Unless you have been living for a long time under a rock probably you what I am talking about.

Looking for resources I have found a video of one of the presentation in the Devnexus conferences in 2015 that it has help me a lot. Considering it is a great resource, I am gonna link the video here, instead of writing myself an article, because I consider that it is very well explained and the tricks and solutions he shows are very interesting.

The speaker is Burr Sutter, a former employee (at the time the article is written) of Red Hat. He has a blog, a github account and a twitter account you can check. The video is quite interesting and not boring at all, it is more than one hour but it feels much shorter than that.

In addition, I strongly recommend you to go to his github account (listed before) and take a look to the tutorials he is using during the video:

  • Docker tutorial: Simple deploy of a Java EE application.
  • Docker MySQL tutorial: Same application than the previous one but with two different containers, one with the application server and the application and another one with the MySQL database.

Just a tiny addition to the excellent job he has done. Right now, we can download from the Docker page the native version of Docker for MAC and for Windows. They are still in beta version but I have not had any problem with that and everything looks a bit simpler.

Good luck with your learning and enjoy it.

See you.

Docker for Java developers

WildFly Swarm REST example

Microservices are here. They have been here for a long time now and it looks like they are going to be here for a while. Some technologies have born in recent years to help developers to implement their systems following this architectural style. One of these technologies is WildFly Swarm.

Probably, if you are familiar with the Java EE world, you know the WildFly application server. WildFly Swarm is a derivate of this application server but it has been created with microservices architectural style in mind. Taking the definition from the WildFly Sward documentation page:

WildFly Swarm is a project that has taken the WildFly Java Application Server and deconstructed it into fine-grained parts. WildFly Swarm then allows the selective reconstitution of those parts back together with your application to allow building self-contained executable “uberjars”.

It has some other components and functions but, mainly, reading the definition we can understand the concept.

As I have said this technology is here to fill the gap that the old and big application servers cannot cover (This is a huge discussion) in the microservises world. It is comparable with Spring Boot or Payara Micro. With its different flavors and features, all of them cover the same gap.

One of the things that it calls our attention in the definition is the word “uberjars“. Considered a buzzword or maybe not, it is just defining a JAR file that contains a package and all its dependencies. In this case, for example, it is going to be a package that it is going to contain our code plus all the dependencies to run a server with our application just executing the order “java -jar file.jar” in a command line prompt.

After this little explanation, let’s go to build our first WildFly Swarm application. It is going to be a very simple REST application just with a method returning some text. And it is going to look like basically as a tradicional Java EE application. One of the best things of migrating a Java EE 7 application to WildFly Swarm is that the code doesn’t change at all. We can take the old and monolithic code and run it as an uberjar just with a few modifications in the maven pom.xml file.

The first step is to define the correct pom.xml file. In this file we are going to include the proper dependencies to build our REST service and a plugin that it is going to allow us to create our uberjar and/or run our application.

...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>bom</artifactId>
            <version>${version.wildfly.swarm}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>
 
<dependencies>
    ...
    <!-- Wildfly Swarm Fractions -->
    <dependency>
        <groupId>org.wildfly.swarm</groupId>
        <artifactId>jaxrs</artifactId>
    </dependency>     
</dependencies>
 
<build>
    <finalName>RestWildFlySwarm</finalName>
    <plugins>
        <plugin>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>wildfly-swarm-plugin</artifactId>
            <version>${version.wildfly.swarm}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>package</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The second thing, it is just add the necessary code to the project to implement the REST service. Like I have said before, it is simple Java EE 7 code, I don’t think it need any especial explanation, if you need some additional explanation you have in this blog some articles about REST services and how to implement them in Java EE 7. One of this examples can be found here.

package com.example.rest;
 
import javax.ws.rs.core.Application;
import javax.ws.rs.ApplicationPath;
 
@ApplicationPath("/rest")
public class RestApplication extends Application {
}
package com.example.rest;
 
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
 
@Path("/messages")
@Produces(MediaType.APPLICATION_JSON)
public class MessagesEndPoint {
    @GET
    public Response getMessage() {
        return Response.ok("This is our first WildFly Swarm App. Awesome!").build();
    }
}

And that’s all we need to add to our first project. Now, we just need to run it.

The first way to do this, it is just running a simple maven command:

mvn wildfly-swarm:run

This first time is going to download a big bunch of dependencies and stuff, and it is going to take some time. Future executions will be much faster.

The second way to execute our application is creating our uberjar file and running it from the console.

mvn wildfly-swarm:run

You can see the full code for the example here.

See you.

WildFly Swarm REST example

Java EE 7: Servlets

A servlet is a Java program that it is executed in a web server and it builds or serve web pages. This allows us to build dynamic pages.

Servlets are a standard implementation in Java EE, for this reason, we can find it under the packages javax.servlet. Here we can find all the classes and interfaces we need to use to work with servlets. The basic elements we need to know are:

  • Servlet interface: It defines the method implemented in any servlet.
  • Class GenericServlet: It is an abstract class that implements the Servlet inteface. It is a generic servlet, and it is not tied to any protocol.
  • HttpServelt: We can find this class inside the package javax.servlet.http. This class inherit from GenericServlet and it is an abstract class too. We will inherit from this class to build our servlets.
  • When a servlet receives a request from a client it receives two objects:
    • ServletRequest: This class contains all the incoming data received in the client request. This object allows us to read all the parameters like the protocol used by the client, the parrameters send by them, and so on. We can obtain an object ServletInputStream to obtain data about the client that it is doing the request. For the HTTP protocol, we can find the subclass HttpServletRequest.
    • ServletResponse: It will contain the servlet response. We can obtain an object ServletOutputStream and/or a Writer to write the response. Again, we have a concrete subclass for the HTTP protocol, HttpServletResponse.

The servlets, like some components in Java EE, have a concrete life cicle and this life cicle is common to all the servlets. The different phases of this life cicle are:

  • The server starts and initializes the servlet.
  • The server processes the clients requests. Each request starts a new thread, and all of them are executed concurrently in the same servlet object.
  • The server destroys the servlet, usually when they have periods without requests or when the server stops.

The different phases of the servlet’s life cicle have associated some specific methods that we can override and use to implement our desired behavior.

Associated to the first phase, the initialization phase, we can find two methods:

public void init() throws ServletException { ... }
public void init(ServletConfig conf) throws ServletException {
    super.init(conf);
    ...

The first method does not need external configuration parameters, but, for the second one, we can supply these parameters in an object ServletConfig. I should remark that the call to the super.init(conf) is very important due to allow the servlet to use the configuration everywhere. If we want to perform any task during the execution of these methods, we should rewrite one or both methods. It is a good practice to return an UnavailableException if there is any error during the initialization process.

During the second phase, when a request arrives from the client, it launches a new thread that calls the service() method.

public void service(HttpServletRequest request,
        HttpServletResponse response)
            throws ServletException, IOException { ... }

This method obtains the request type: GET, POST, PUT, DELETE, OPTIONS or TRACE and, depending on the type of request, it calls the appropriate method in charge to manage the request. The most important are, in general, GET and POST, the signatures of these methods are:

public void doGet(HttpServletRequest request,
        HttpServletResponse response)
            throws ServletException, IOException { ... }
public void doPost(HttpServletRequest request,
        HttpServletResponse response)
            throws ServletException, IOException { ... }

We can find similar methods for the rest of the request types: doDelete(), doPut(), doOptions(), doTrace().

The last phase, the destruction phase, calls a method to destroy the servlet and destroy any element created during the initializacion. The method signature is:

public void destroy() throws ServletException { ... }

We should pay special attention if our servlet is launching time consuming task, we should implement some way to be sure all the tasks have finished. A counter with some synchronization code to control the number of tasks, or a flag visible for the tasks to stop them if the servlet must be destroyed quickly.

Let’s see a basic code example to see everything we have seen so far.

Basic servlet:

package com.wordpress.binaycoders.examples;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
public class BasicServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // code for GET request
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // code for POST request
    }
}

The next step is to configure the access to the servlet. In previous versions of Java EE we should perform this configuration with XML in the web.xml file, but in the Java EE 7 version we can do this with annotations. In any case, here, we are going to see both ways.

For the XML configuration, we should declare the servlet and the URL where is going to be available:

<servlet>
    <servlet-name>basicServlet</servlet-name>
    <servlet-class>com.wordpress.binaycoders.examples.BasicServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>basicServlet</servlet-name>
    <url-pattern>/basicservlet</url-pattern>
</servlet-mapping>

With this configuration the servlet should be available in the URL:

http://localhost:8080/<theapp>/basicservlet

Inside the servlet mapping we can define a pattern instead of a concrete URL, something like:

<servlet-mapping>
    <servlet-name>basicServlet</servlet-name>
    <url-pattern>/basicservlet/*</url-pattern>
</servlet-mapping>

Or we can define a JSP page:

<servlet>
    <servlet-name>basicServlet</servlet-name>
    <jsp-file>/page.jsp</jsp-file>
</servlet>

We can initialize some parameters when the servlet starts:

<servlet>
    <servlet-name>basicServlet</servlet-name>
    <servlet-class>BasicServlet</servlet-class>
    <init-param>
        <param-name>parameter</param-name>
        <param-value>value</param-value>
    </init-param>
</servlet>

And, we can load the servlet when the server starts. Even we can define the order they are going to follow when the server starts using numbers to sort properly the different servlets.

<servlet>
    <servlet-name>basicServlet</servlet-name>
    <servlet-class>BasicServlet</servlet-class>
    <load-on-startup/>
</servlet>
<servlet>
       <servlet-name>basicServlet</servlet-name>
       <servlet-class>BasicServlet</servlet-class>
       <load-on-startup>2</load-on-startup>
</servlet>

In this case, the Java EE 7 brings us the Servlet 3.0 API, and this API allows us to use annotations to configure our servlets.

Declaring the servlet and the URL where is going to be available:

package com.wordpress.binaycoders.examples;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // code for GET request
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // code for POST request
    }
}

In the same way, we can use annotations to initializate parameters like we have done in the XML.

@WebServlet(urlPatterns = "/basicservlet",
        initParams = { @InitParam(name = "parameter", value = "value") }
)

The way to access to these initialized parameters from our java code is:

getServletConfig().getInitParameter("parameter");

And, in the same way, we have stablished the initialization order for the servlets in the XML, we can do it with annotations:

@WebServlet(name = "basicServlet",
        urlPatterns = "/basicservlet",
        loadOnStartup = "2")

And, to finish the post, let’s see some very basic examples:

Servlet to generate plain text:

package com.wordpress.binaycoders.examples;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        PrintWriter out = response.getWriter();
        out.println ("I am the basic servlet. Welcome!");
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

Servlet to generate HTML:

package com.wordpress.binaycoders.examples;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        response.setContentType("text/html");
 
        PrintWriter out = response.getWriter();
        out.println ("<!doctype html>");
        out.println ("<html>");
        out.println ("<body>");
        out.println ("<br>I am the basic servlet (HTML). Welcome!");
        out.println ("</body>");
        out.println ("</html>");
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

And, that’s all for now.

See you.

Java EE 7: Servlets

Java REST API + cURL + python3

During the next lines, I am going to implement a very simple REST API using JavaEE 7 and Java SE 8 technologies, maven as build tool and GlassFish as application server. I am going to test this API with cURL and, I am going to consume this API using python3 using the Requests module.

Java EE 7 REST API

First, we need to create a maven project in our favorite IDE and add our dependencies to the pom.xml file

...
<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
 
<dependencies>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
 
<build>
    <finalName>apicrud</finalName>
</build>
...

Second, we are going to create a persistence.xml file. In this case, we are not interested in how to configure a DB, then, we are going to use the default datasource that GlassFish provides us as default “jdbc/__default“. With all of this in mind, the file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="ApiCrudPU" transaction-type="JTA">
        <jta-data-source>jdbc/__default</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

Now, we need to create our Entity. In this case, I have chosen a simple one, User with three attributes:

  • id: Autogenerated id to identify the user.
  • name: User’s name.
  • email: User’s email.

The result should be something like:

package com.wordpress.binarycoders.apicrud;
 
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
 
@Entity
@Table (name = "users")
@NamedQueries ({
    @NamedQuery (name = User.FIND_ALL, query = "SELECT u FROM User u")
})
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
     
    private static final long serialVersionUID = 1L;
     
    public static final String FIND_ALL = "User.findAll";
     
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
     
    @Column(name = "name")
    private String name;
     
    @Column(name = "email")
    private String email;
 
    /* Getters, Setters, equals and hashCode methods */   
}

The next step, it is to implement the boundary or service layer. Being a simple example, we can skip this layer, but I like to implement everything for learning purposes. This layer is going to be very simple, only the necessary object to perform the operation in the DB and the basic operations to implement a CRUD. The result looks like:

package com.wordpress.binarycoders.apicrud;
 
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.validation.constraints.NotNull;
 
@Stateless
public class UserService {
     
    @PersistenceContext
    private EntityManager em;
     
    public void create(@NotNull User user) {
        this.em.persist(user);
    }
     
    public User findById(@NotNull Long id) {
        return this.em.find(User.class, id);
    }
     
    public List<User> findAll() {
        TypedQuery<User> typedQuery = this.em.createNamedQuery(User.FIND_ALL, User.class);
 
        return typedQuery.getResultList();
    }
     
    public void update(@NotNull User user) {
        this.em.merge(user);
    }
     
    public void delete(@NotNull Long id) {
        this.em.remove(this.findById(id));
    }
}

To do all of this available to the world, we need to implement our REST API, and for this, we need to configure the REST capabilities in our system, piece of cake with the last version of Java EE. We just need to create a class to enable these capabilities:

package com.wordpress.binarycoders.apicrud;
 
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
 
@ApplicationPath("/rs")
public class ApplicationConfig extends Application {
     
}

And, finally, we need to implement our REST layer with the four actions that are going to allow us to perform the CRUD operations:

package com.wordpress.binarycoders.apicrud;
 
import java.net.URI;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
 
@Path("/users")
@Produces ({ MediaType.APPLICATION_JSON })
@Consumes ({ MediaType.APPLICATION_JSON })
@Stateless
public class UserEndPoint {
     
    @EJB
    private UserService service;
     
    @Context
    private UriInfo uriInfo;
     
    @GET
    public Response findAll() {
        List<User> users = this.service.findAll();
         
        GenericEntity<List<User>> list = new GenericEntity<List<User>>(users) {};
         
        return Response.ok(list).build();
    }
     
    @GET
    @Path("/{id}")
    public Response findById(@PathParam("id") Long id) {
        User user = this.service.findById(id);
         
        if (user == null) {
            throw new NotFoundException();
        }
         
        return Response.ok(user).build();
    }
     
    @POST
    public Response create(User user) {
        this.service.create(user);
         
        URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build();
         
        return Response.created(uri).build();
    }
     
    @PUT
    public Response update(User user) {
        this.service.update(user);
         
        return Response.ok().build();
    }
     
    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") Long id) {
        this.service.delete(id);
         
        return Response.noContent().build();
    }
}

I think that in this point, assuming that everyone reading this, it is a developer and this is not an entry level post, all of you should be capable to understand everything has been written in the above lines. If there are things that you do not know or you do not understand due to a lack of information or your knowledge is not enough (all of us have been there), look at the note at the end of this post.

cURL test

Now, obviously, we need to test if our REST API is working properly. For this, we can implement some solution based on test frameworks or manual code but, due to the simplicity of the object User, it is enough with the cURL tool. To test our API we are going to perform these operations:

  • Select all the users
  • Create a user
  • Select the created user
  • Update the user
  • Delete the user

These operations can be performed with the next commands:

curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"john","email":"john@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users/1
curl -i -H "Content-Type: application/json" -X PUT -d '{"id”:1,”name":"John Doe","email":"john.doe@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X DELETE http://localhost:8080/ApiCRUD/rs/users/1

Everything should look well, and the appropriate HTTP codes should be received.

Python3 client

The last step today, it is to implement a very very simple python3 client to consume our API. This is going to be a basic script to invoke the CRUD operations available in the API.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
import requests
import json
 
URL = 'http://localhost:8080/ApiCRUD/rs/users'
 
def getUsers():
    print('Get users...\n')
 
    response = requests.get(URL)
 
    assert response.status_code == 200
 
    users = response.json()
    print(json.dumps(users, indent = 4, separators = (',', ':')))
 
def getUser(location):
    print('Get single user ...\n')
 
    response = requests.get(location)
 
    assert response.status_code == 200
 
    users = response.json()
    print(json.dumps(users, indent = 4, separators = (',', ':')))
 
def createUser():
    print('Creating user...\n')
 
    headers = {'content-type': 'application/json'}
    user = {"name": "John Doe", "email": "john.doe@example.org"}
    response = requests.post(URL, data = json.dumps(user), headers = headers)
 
    assert response.status_code == 201
 
    print('Location: ' + response.headers['location'])
 
    return response.headers['location']
 
def updateUser(location):
    print('Updating user...')
 
    loc = location.split('/')
 
    headers = {'content-type': 'application/json'}
    user = {"id": loc[-1], "name": "Jane Doe", "email": "jane.doe@example.org"}
    response = requests.put(URL, data = json.dumps(user), headers = headers)
 
    assert response.status_code == 200
 
def deleteUser(location):
    print('Deleting user...')
 
    response = requests.delete(location)
 
    assert response.status_code == 204
 
    print('Checking delete operation')
    response = requests.get(location)
 
    assert response.status_code == 404
 
def main():
    getUsers()
    location = createUser()
    getUser(location)
    updateUser(location)
    getUser(location)
    deleteUser(location)
 
if __name__ == "__main__":
    main()

And that’s all. Now, we have a little REST AP, a python3 client and a basic knowledge about how to use cURL to test it.

See you.

You can find the code for the REST API available here.

Note: All the content in this post will be splitter and explained in future post, one for each one of the three big point explained in here: Java EE 7 REST API creation, cURL test and python3 REST client.

Java REST API + cURL + python3

Customizing our connections with proxies

Nowadays, it is clear that Java / Java EE are mainly back end technologies. In this role, it is quite common for a Java / Java EE application to connect to different systems to collect data or perform different operations, using REST web services, SOAP web services, sockets or other technologies that allow different systems to exchange information without a human being interference.

In complex systems, in addition to the big number of external and internal connections the system performs, we need to consider that sometimes we need to use one or more different proxies to reach the destiny.

Sometime the objects we are using to create and manage connections allow us to add this proxy information inside, but not always, and this creates always a big headache. We usually end, wrapping our object inside others that support a proxy addition.

Today, I have another suggestion that, in some cases, can do our lives easier. This option is to extend the ProxySelector class. This class has been around for a long time, you can find the API page for different Java version:

The idea is to extend this class and implement its abstract methods and assign this extended class as the default class for our system. Each time that a connection is going to be performed, the method List<Proxy> select(URI uri) is going to be called. In this method, we can decide if we need to add a proxy or not to this connection.

The resultant code should be something like that:

package com.wordpress.binarycoders.proxy;
 
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
 
public class CustomProxySelector extends ProxySelector {
 
    private static final int DEFAULT_PORT = 80;
 
    private final ProxySelector defaultProxySelector;
 
    private Proxy proxy;
 
    private List<Proxy> proxyList = new ArrayList<Proxy>();
 
    public CustomProxySelector(String proxyHost, Integer proxyPort) {
 
        defaultProxySelector = ProxySelector.getDefault();
 
        proxy = new Proxy(Proxy.Type.HTTP,
                          new InetSocketAddress(proxyHost,
                                                (proxyPort == null) ?
                                                 DEFAULT_PORT :
                                                 proxyPort));
        proxyList.add(proxy);
    }
 
    @Override
    public List<Proxy> select(URI uri) {
 
        if (uri == null) {
            throw new IllegalArgumentException("URI cannot be null.");
        }
 
        if (needsProxy(uri)) {
            return proxyList;
        }
 
        return def.select(uri);
    }
 
    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
 
        if ((uri == null) || (sa == null) || (ioe == null)) {
            throw new IllegalArgumentException("Arguments cannot be null.");
        }
 
        defaultProxySelector.connectFailed(uri, sa, ioe);
    }
 
    private boolean needsProxy(URI uri) {
        return uri.getHost().contains("urlNeedsProxy");
    }
}

As you can see, we only need a few lines to make it works. Obviously, we can make as complex as you want the method to determinate if a connection needs a proxy or not.

To use this class, we only need to add a simple line to the code in the start point of our application:

ProxySelector.setDefault(new CustomProxySelector(proxyHost, proxyPort));

And that’s all. Now with a few tests we can check if our solution works fine or not.

See you.

Note: Take care if your application share the server with other applications. Remember to test all of them just in case.

Customizing our connections with proxies

Generic DAO

Sometimes we, as a developers, need to deal with huge applications with hundreds of classes with a lot of methods inside. It is very common sometimes, when developers have time (it should be always mandatory), they try to do some code refactoring trying to improve the code quality: removing duplicated methods, renaming methods and variables to something with more sense, splitting complex methods…

Today, I am going to focus this post in the persistence layer. Sometimes, when I take a look to the DAOs in an application, all of them have the same methods that are written again and again, these methods usually are:

  • findById
  • findAll
  • persist
  • update
  • delete
  • countAll

In addition, usually the annotation “@PersistenceContext” (javax.persistence package) and the variable “EntityManager” (javax.persistence package) are defined over and over in all the DAOs. In fact, there are some DAOs that only have these methods. In this situation, sometimes is a good idea to create a generic DAO with all this stuff, avoiding in this way to repeat the same code in all the DAOs and only adding new methods to the DAOs when it is needed. Let’s see how we can do that in a easy way.

First, we need to define the interface of our generic DAO:

public interface GenericDAO<T, ID extends Serializable> {
    void persist(T entity);
    void update(T entity);
    void delete(T entity);
    T findById(ID id);
    List<T> findAll();
    Long countAll();
}

As you can see, it is quite simple. We are creating an interface but, in this case, using Generics notation we are going to allow to define the type of the object and the type of the object identifier later.

The second step, it is to create a class that implements this interface with the code for these methods. In addition, we are going to create this class as an abstract class just in case we want to add some methods without implementation or allowing easily to rewrite our defined methods in specific situations. The class is going to be as much simple as possible: no error handling, no data validation… only the implementation.

public abstract class GenericImplDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {
 
    @PersistenceContext
    protected EntityManager em;
     
    private Class<T> persistentClass;
 
    @SuppressWarnings("unchecked")
    public JPAGenericDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
    }
 
    public Class<T> getPersistentClass() {
        return persistentClass;
    }
 
    @Override
    public T findById(ID id) {
        return em.find(getPersistentClass(), id);
    }
 
    @Override
    public List<T> findAll() {
        TypedQuery<T> query = em.createQuery("from " + persistentClass.getName(), persistentClass);
        return query.getResultList();
    }
 
    @Override
    public Long countAll() {
        StringBuilder sb = new StringBuilder();
        sb.append("select count(E) from ");
        sb.append(persistentClass.getName());
        sb.append(" E");
 
        TypedQuery<Long> query = em.createQuery(sb.toString(), Long.class);
        return query.getSingleResult();
    }
 
    @Override
    public void persist(T entity) {
        em.persist(entity);
    }
 
    @Override
    public void update(T entity) {
        em.merge(entity);
    }
 
    @Override
    public void delete(T entity) {
        em.remove(entity);
    }
}

The next step is to create the interface for our concrete DAO. In this case, for example, the PersonDAO. The class Person is an entity and is something like:

  • id: Integer
  • name: String
  • surname: String
  • email: String
public interface PersonDAO extends GenericDAO<Person, Integer> {
    Person findByEmail(String email);
}

As you can see, the DAO now is very simple due to all the common methods are defined in our generic DAO and here, we only need to add the specific methods for this DAO. Another thing that deserves our attention is that we have replaced the generics notations for the specific values that apply to this class: T -> Person and ID -> Integer.

Finally, we can implement our DAO:

public class PersonImplDAO extends GenericImplDAO<Person, Integer> implements PersonDAO {
 
    @Override
    public Person findByEmail(String email) {
        TypedQuery<Person> query = em.createQuery("select P from Person P where P.email = :email", Person.class);
        query.setParameter("email", email);
         
        return query.getSingleResult();
    }
}

And this is all. Now we can do the same with all our DAOs been sure that all of them are going to have the basic methods implemented. As you can see, we have create the EntityManager as a protected variable. Doing this, we are allowed to use it in our specific DAOs. Another approach is to create the variable with private visibility and to create the getter and setter to make it accessible.

See you.

Generic DAO

Java EE: Lo básico

Hoy vamos a hacer algo muy simple. Estos días he estado escuchando discusiones sobre que los proyectos hechos en Java EE requieren muchos ficheros, configuraciones y demás, y la verdad, es que me temo que no estoy nada de acuerdo. Quizás antiguas versiones J2EE lo requerian, pero ahora Java EE nos permite centrarnos en el negocio y la única complejidad que se añade se debe a este. Así que he decidido implementar un ejemplo muy básico con ellos para ver cuanta complejidad obtenía implementando un pequeño servicio REST sin BBDD.

Lo primero que tenemos que hacer es crear un proyecto maven en nuestro IDE favorito, en mi caso yo usaré Eclipse. Este proyecto maven será con el arquetipo básico o sin arquetipo. El contenido del fichero pom.xml sera:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wordpress.infow</groupId>
	<artifactId>MostBasicJavaEEApp</artifactId>
	<version>1.0</version>
	<packaging>war</packaging>
	<name>MostBasicJavaEEApp</name>
	
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<failOnMissingWebXml>false</failOnMissingWebXml>
	</properties>
	
	<dependencies>
	
		<!-- Java EE 7 -->
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>
	
	</dependencies>
	
	<build>
		<finalName>basic</finalName>
	</build>
</project>

Lo siguiente es crear el servicio REST para esto necesitamos la clase que nos configura REST en nuestra aplicación, cuyo contenido será:

package com.wordpress.infow.basic.rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/rs")
public class ApplicationConfig extends Application {

}

Como podéis ver, muy simple.

Y ahora creamos nuestros servicio REST:

package com.wordpress.infow.basic.rest;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.wordpress.infow.basic.boundary.BasicStuff;

@Path("/sessions")
public class Session {

	@GET
	public String getSession() {
		return "Jonh Doe";
	}
}

Con esto, ya podremos arrancar nuestro servidor, yo estoy usando GlassFish 4, y accediento a la URL correcta podremos ver el resultado.

Lo siguiente es añadir el servicio al que el servicio REST va a invocar e injectar este en nuestro código REST.

package com.wordpress.infow.basic.boundary;

import java.util.Date;

import javax.ejb.Stateless;
import javax.inject.Inject;

import com.wordpress.infow.basic.entity.BasicEntity;

@Stateless
public class BasicStuff {

	public String getDate() {
		return new Date().toString();
	}
}
package com.wordpress.infow.basic.rest;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.wordpress.infow.basic.boundary.BasicStuff;

@Path("/sessions")
public class Session {

	@Inject
	BasicStuff bs;

	@GET
	public String getSession() {
		return "Jonh Doe" + this.bs.getDate();
	}
}

Con esto ya tenemos nuestro servicio REST invocando a la lógica de negocio de nuestra aplicación, y sin un xml todavía ni nada raro.

El siguiente paso será añadir la entidad que debería conectar con la BBDD.

package com.wordpress.infow.basic.entity;

public class BasicEntity {

	public String getStatus() {
		return "OK";
	}
}
package com.wordpress.infow.basic.boundary;

import java.util.Date;

import javax.ejb.Stateless;
import javax.inject.Inject;

import com.wordpress.infow.basic.entity.BasicEntity;

@Stateless
public class BasicStuff {

	@Inject
	BasicEntity be;

	public String getDate() {
		return new Date().toString() + " - " + this.be.getStatus();
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

Vaya, aquí s’i que hemos tenido que añadir un xml para permitir al contenedor web la injección de todos los objectos.

Y ahora, vamos a… Ummm, espera, ya está todo. No necesitamos hacer nada más.

Como se ve Java EE nos deja centrarnos en la lógica de negocio y los problemas derivados de está, en vez de, en complejas configuraciones.

Podeís encontrar el código del proyecto como siempre en mi repositorio:

MostBasicJavaEEApp

Nos vemos.

Java EE: Lo básico

JavaEE: QuoteWall

La primera aplicación publicada en el nuevo repositorio mencionado anteriormente, se trata de una simple aplicación implementada en Java EE 7. En ella se puede observar el uso de varias tecnologías como:

  • JPA (MySQL)
  • JAX-RS
  • JAX-WS
  • EJB
  • JSF (PrimeFaces)
  • I18N y L10N
  • Bootstrap
  • Maven y Git

Toda ellas ha sido desplegada en un servidor GlassFish durante su desarrollo, con un DataSource configurado en él.

Como podréis ver echándole un rápido vistazo al código, es una aplicación muy simple que consiste únicamente en un muro de citas famosas dichas por personajes famosos o anónimos. No lleva ningún tipo de seguridad, ni gestión de usuarios ni nada por el estilo. El objetivo  de la aplicación no era más que usar algunas de las tecnologías de Java EE 7 y practicar un poco con Bootstrap, que siendo un desarrollado de Back-end, nuca está de más.

Para el que no lo sepa, Bootstrap es un Framework para front-end muy popular a día de hoy, y que nos hace muy fácil maquetar nuestras páginas y maquetarlas en diferentes dispositivos,

La aplicación la podéis encontrar en el repositorio de ejemplos java ee bajo el nombre de QuoteWall.

La aplicación tiene el típico esquema de directorios que nos aporta el usar maven, aunque en este caso, no ha sido creada a partir de un arquetipo, sino que se ha generado un fichero pom.xml vacío, y se le ha añadido el contenido necesario, incluyendo las dependencias necesarias para correr nuestra aplicación.

Como ya he comentado para las conexiones con base de datos se ha usado un servidor MySQL, y se ha creado en el servidor de aplicaciones GlassFish un DataSource llamado “jdbc/quoteWall”. Por lo demás, es un proyecto bastante estándar que podéis tomar como referencia para la implementación y creación de otros más grandes.

Como plus, se ha añadido otro proyecto más al repositorio: QuoteWallNoSQL, el cual es exactamente el mismo proyecto, pero con los cambios necesarios para hacerlo funcionar con una base de datos NoSQL, en este caso, MongoDB, de lo cual ya escribimos una par de artículos anteriormente aquí en el blog. Si no los habéis visto, os remito a la serie de artículos de NoSQL.

Bueno, hasta aquí todo. Nos vemos.

JavaEE: QuoteWall

Interceptores

La siguiente tecnología incluida en Java EE 7 de la que vamos a hablar son los interceptores, los cuales nos permites realizar alguna acción antes de que los métodos sean llamados. Aunque está mal usar la palabra definida en la definición, es un modo de interceptar invocaciones a métodos para de esta forma poder realizar alguna tarea previa a su ejecución o posterior a ella. También se pueden encadenar interceptores para realizar varias tareas diferentes. Un uso muy común suele ser para realizar tareas como generar logs de los métodos ejecutados.

Existen cuatro tipos de interceptores:

  • Interceptores a nivel del constructor: @AroundConstruct
  • Interceptores a nivel de método: @AroundInvoke
  • Interceptores asociados a timeout de métodos: @AroundTimeout (solo se usan en EJB con servicios de timer)
  • Interceptores a nivel de ciclo de vida: @PostConstruct y @PreDestroy

Para el primer ejemplo vamos a mostrar uno a nivel de método que es el más simple e intuitivo (no significa que los demás sean complejos):

public class MyService {
    @Inject
    private Logger logger;

    public void actionOne(MyObject obj) { ... }

    public void actionTwo(MyObject obj) { ... }

    @AroundInvoke
    private Object logMethod(InvocationContext ic) throws Exception {
        logger.entering(ic.getTarget().toString(), ic.getMethod().getName());
        try {
            return ic.proceed();
        } finally {
            logger.exiting(ic.getTarget().toString(), ic.getMethod().getName();
        }
    }
}

La primera cosa en la que tenemos que prestar atención es en la utilización de la anotación para marcar cual es el método que se va a utilizar como interceptor, la segunda, e igualmente importante, es que el prototipo del método utilizado como interceptor debe ser:

[public|private|protected] Object <methodName>(Invocationcontext ic) throws Exception;

Y dicho prototipo ni puede ser static o final.

Básicamente cuando alguna clase invoque alguno de los métodos de nuestra clase, esta llamada será interceptada por nuestro interceptor. La secuencia de ejecución para una llamda al método “actionOne” será:

  1. Llamada a “actionOne”
  2. Interceptación. Llamada a “logMethod”.
  3. Escritura del log: “entering”.
  4. Ejecución del método invocado: “proceed”.
  5. Escritura del log: “exiting”.

Mostrar un ejemplo del resto de tipos de interceptores no tiene mucho sentido, ya que no es más que seleccinar la anotación adecuada y colocarla de igual modo que hemos hecho con “@AroundInvoke”.

Lo que si que va a resultar interesante, y seguro que más de uno ya ha pensado es, ¿y tengo que crear un interceptor por cada clase para poder escribir en el log (nuestro caso particular)? Pues bien, la respuesta es no. Podemos crear un interceptor genérico y aplicarlos a las clases o métodos que deseemos. Para ello vamos a crear este interceptor genérico y luego ver como usarlo con los siguientes ejemplo:

Interceptor genérico:

public class LoggingInterceptor {
    @Inject
    private Logger logger;

    @AroundConstruct
    private void init(InvocationContext) throws Exception {
        logger.fine("My logging interceptor constructor: Entering");
        try {
            ic.proceed();
        } finally {
            logger.fine("My logging interceptor constructor: Exiting");
        }
    }

    @AroundInvoke
    public Object logMethod(InvocationContext) throws Exception {
        logger.entering(ic.getTarget().toString(), ic.getMethod().getName());
        try {
            return ic.proceed();
        } finally {
            logger.exiting(ic.getTarget().toString(), ic.getMethod().getName();
        }
    }
}

Usándolo en una clase a nivel de método, tendríamos el siguiente resultado:

public class MyService {
    @Interceptors(LoggingInterceptor.class)
    public void actionOne(MyObject obj) { ... }

    public void actionTwo(MyObject obj) { ... }
}

Con esto nuestro inerceptor sería llamada cada vez que el método “actionOne” sea invocado, pero no al llamar al método “actionTwo”.

También podemo asignar el interceptor a nivel de clase, donde todos los método llamados de esa clase invocarían a nuestro interceptor:

@Interceptors(LoggingInterceptor.class)
public class MyService {
    public void actionOne(MyObject obj) { ... }

    public void actionTwo(MyObject obj) { ... }
}

E incluso si tenemos muchos métodos en una clase y queremos que alguno de ellos no invoque a nuestro interceptor, pero los demás sí, podemos excluir este método:

@Interceptors(LoggingInterceptor.class)
public class MyService {
    public void actionOne(MyObject obj) { ... }

    public void actionTwo(MyObject obj) { ... }

	@ExcludeClassInterceptors
	public void actionTree(MyObject obj) { ... }
}

Como añadido a esto, y para potenciar aún más el uso de interceptores, estás anotaciones nos permiten mucha más versatilidad aún, como la de invocar varios y diferentes interceptores según necesitemos, pudiendo hacer cosas como estas:

@Interceptors({Int1.class, Int2.class})
public class MyService {
    public void actionOne(MyObject obj) { ... }

    @Interceptors({Int3.class, Int4.class})
    public void actionTwo(MyObject obj) { ... }

	@ExcludeClassInterceptors
	public void actionTree(MyObject obj) { ... }
}

Aunque no lo parezca, el orden en el que aparecen los interceptores en la anotación es importante, ya que será este el orden en el que se invocarán.

Pero si pensabais que aquí habíamos terminado, estáis equivocados. Aún nos queda una forma más de declarar nuestros interceptores, por suerte, es una forma muy similar a la que se definen los “Qualifiers” que vimos en el artículo anterior. Se suele conocer como “Interceptor Binding”, y aquí si que lo siento, porque no he encontrado ninguna traducción que me haya convencido. Decir antes de empezar, que para poder utilizar este tipo necesitamos de forma obligatoria tener el soporte para CDI activado. De esta forma podremos hacer cosas como estas:

Interceptor Binding:

@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Loggable { }

Interceptor:

@Interceptor
@Loggable
public class LoggingInterceptor {
    @Inject
    private Logger logger;

    @AroundInvoke
    public Object logMethod(InvocationContext ic) throws Exception {
        ...
    }
}

Nuestro servicio:

@Loggable
public class MyService {
    public void actionOne(MyObject obj) { ... }

    public void actionTwo(MyObject obj) { ... }

	@ExcludeClassInterceptors
	public void actionTree(MyObject obj) { ... }
}

Se puede utilizar tanto a nivel de clase como de método.

En este punto tenemos que añadir que estos interceptores están deshabilitados por defecto, con lo cual tenemos que añadir en nuestro “bean.xml” explicitamente que queremos usarlos. Esto sería añadiendo al fichero el siguiente nodo:

<interceptors>
    <class>org.example.LoggingInterceptor</class>
</interceptors>

Y ya por fín, lo último. Utilizando este último tipo de interceptores perdemos la posibilidad de ordenar estos según el orden de ejecución que deberían seguir. Para paliar esta desventaja se ha introducido el concepto de prioridad, pudiendo asignar un valor numérico positivo a cada interceptor. Cuanto más bajo sea el valor, antes se ejecutará el interceptor.

En nuestro ejemplo, el código del interceptor quedaría algo como:

@Interceptor
@Loggable
@Priority(100)
public class LoggingInterceptor {
    @Inject
    private Logger logger;

    @AroundInvoke
    public Object logMethod(InvocationContext ic) throws Exception {
        ...
    }
}

Bueno, hasta aquí hemos llegado. Espero que os haya sido de utilidad y que os haya quedado claro toda esta parte de los interceptores. Nos vemos.

Interceptores

Inyección de dependencias y “Qualifiers”

El artículo de hoy va ser un poco técnico y enfocado a Java EE 7. Vamos a hablar sobre la inyección de dependencias. Imagino que a estas alturas no habrá un solo desarrollador Java/Java EE que no sepa lo que es esto. Para aquellos despistados añadiré, que la inyección de dependencias es un patrón en el que se le suministran objetos a una clase, en lugar de que la clase los cree. Para el que aún no sepa lo que es, le recomiendo que lo mire antes de proseguir leyendo porque el objetivo del artículo es solo dejar unos breves apuntes sobre la parte técnica, y no el de dar una amplia explicación sobre este concepto.

Para empezar, vamos a ver un ejemplo de como crearíamos un dependencia sin utilizar inyección. Esto sería utilizando la palabra reservado “new” como se ha hecho durante mucho tiempo. Para los ejemplos, vamos a utilizar una especie de sistema bancario de tarjetas, el cual adaptaremos a nuestras necesidades para la explicación.

Bien, pues aquí tenemos el primer ejemplo de dependencias sin inyección:

public class CustomerService {
    private Card card;

    public CustomerService() {
        this.card = new DebitCard();
    }

    public Customer createCustomer(String name, String surname) {
        Customer customer = new Customer(name, surname);
        customer.setCardNumber(card.generateNumber());

        return customer;
    }
}

Esto sería el modo tradicional de la creación de un objeto y el manejo de este. En caso de tener varios tipos de tarjetas, podríamos utilizar el constructor para crear un tipo u otro:

public class CustomerService {
    private Card card;

    public CustomerService(Card card) {
        this.card = card;
    }

    public Customer createCustomer(String name, String surname) {
        Customer customer = new Customer(name, surname);
        customer.setCardNumber(card.generateNumber());

        return customer;
    }
}

CustomerService customerService = new CustomerService(new DebitCard());
CustomerService customerService = new CustomerService(new CreditCard());

Con esto vemos como podemos pasar el tipo de tarjeta a nuestro servicio según cual necesitemos en cada momento.

Ahora bien, para ahorrarnos esto, la injección de dependencias viene en nuestra ayuda pudiendo hacer cosas como la que vemos a continuación y donde será nuestro contenedor el que maneje el objeto y se encargue de hacer el “new”:

public class CustomerService {
    @Inject
    private Card card;

    public Customer createCustomer(String name, String surname) {
        Customer customer = new Customer(name, surname);
        customer.setCardNumber(card.generateNumber());

        return customer;
    }
}

public DebitCard implements Card {
    public String generateNumber() {
        ...
    }
}

Existen varias formas de hacer la inyección del objeto (varios puntos de inyección): en la propiedad, en el constructor o en el método “set”. Técnicamente no hay una mejor o una peor, esto queda un poco a gusto del desarrollador. Los ejemplo de cada una de ellas serían los siguientes:

@Inject
private Card card;
@Inject
public CustomerService(Card card) {
    this.card = card;
}
@Inject
public void setCard(Card card) {
    this.card = card;
}

Ahora bien, más de uno se estará preguntando en este punto que sucedería en caso de haber más de una clase que implementara el interfaz “Card”. Pues bien, aquí es donde los “Qualifiers” cobran su importancia, permitiéndonos establecer que clase es la que debe ser inyectada. Como ejemplo, vamos a crear los “Qualifiers” de nuestras tarjetas de crédito y débito:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface Debit { }
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface Credit { }

Que usaríamos en las clases correspondientes:

@Debit
public DebitCard implements Card {
    public String generateNumber() {
        ...
    }
}

@Credit
public CreditCard implements Card {
    public String generateNumber() {
        ...
    }
}

Y a la hora de la inyección el código quedaría tal que así:

public class CustomerDebitService {
    @Inject @Debit
    private Card card;

    public Customer createCustomer(String name, String surname) {
        Customer customer = new Customer(name, surname);
        customer.setCardNumber(card.generateNumber());

        return customer;
    }
}

public class CustomerCreditService {
    @Inject @Credit
    private Card card;

    public Customer createCustomer(String name, String surname) {
        Customer customer = new Customer(name, surname);
        customer.setCardNumber(card.generateNumber());

        return customer;
    }
}

Pero claro, esto con solo dos clases está muy bien y es manejable, pero imaginemos ahora que sacamos más modelos de tarjetas: normal, online, endMonthPay y premium. Y además, todas ellas pueden ser de débito o de crédito. Está claro que se volvería inmanejable además de complicar innecesariamente con clases extras nuestra aplicación. Para evitar esto, en los “Qualifiers” podemos definir miembros, o lo que es lo mismo, propiedades para el “Qualifier”. Así que vamos a ver el ejemplo de como sería esto:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface CardType {
    CType value();
    boolean debit();
}

public enum CType {
    NORMAL, ONLINE, END_MONTH_PAY, PREMIUM
}

En este caso el código quedaría así para una tarjeta de débito normal:

@CardType(value = CType.NORMAL, debit = true)
public DebitCard implements Card {
    public String generateNumber() {
        ...
    }
}

@Inject @CardType(value = CType.NORMAL, debit = true)
private Card card;

Bueno, hasta aquí el pequeño esquema de hoy sobre inyección de dependencias y “Qualifiers”. Para cualquier duda, ya sabéis. Nos vemos.

Inyección de dependencias y “Qualifiers”