Docker Java Client

No questions about containers been one of the latest big things. They are everywhere, everyone use them or want to use them and the truth is they are very useful and they have change the way we develop.

We have docker for example that provides us with docker and docker-compose command line tools to be able to run one or multiple containers with just a few lines or a configuration file. But, we, developers, tend to be lazy and we like to automize things. For example, what about when we are running our application in our favorite IDE the application starts the necessary containers for us? It will be nice.

The point of this article was to play a little bit the a docker java client library, the case exposed above is just an example, probably you readers can think about better cases but, for now, this is enough for my learning purposes.

Searching I have found two different docker java client libraries:

I have not analyze them or compare them, I have just found the one by GitHub before and it looks mature and usable enough. For this reason, it is the one I am going to use for the article.

Let’s start.

First, we need to add the dependency to our pom.xml file:

<dependency&gt;
    <groupId&gt;com.github.docker-java</groupId&gt;
    <artifactId&gt;docker-java</artifactId&gt;
    <version&gt;3.1.1</version&gt;
</dependency&gt;

The main class we are going to use to execute the different instructions is the DockerClient class. This is the class that establishes the communication between our application and the docker engine/daemon in our machine. The library offers us a very intuitive builder to generate the object:

DockerClient dockerClient = DockerClientBuilder.getInstance().build();

There are some options that we can configure but for a simple example is not necessary. I am just going to say there is a class called DefaultDockerClientConfig where a lot of different properties can be set. After that, we just need to call the getInstance method with our configuration object.

Image management

Listing images

List<Image&gt; images = dockerClient.listImagesCmd().exec();

Pulling images

dockerClient.pullImageCmd("postgres")
                .withTag("11.2")
                .exec(new PullImageResultCallback())
                .awaitCompletion(30, TimeUnit.SECONDS);

Container management

Listing containers

// List running containers
dockerClient.listContainersCmd().exec();

// List existing containers
dockerClient.listContainersCmd().withShowAll(true).exec();

Creating containers

CreateContainerResponse container = dockerClient.createContainerCmd("postgres:11.2")
                .withName("postgres-11.2-db")
                .withExposedPorts(new ExposedPort(5432, InternetProtocol.TCP))
                .exec();

Starting containers

dockerClient.startContainerCmd(container.getId()).exec();

Other

There are multiple operations we can do with containers, the above is just a short list of examples but, we can extended with:

  • Image management
    • Listing images: listImagesCmd()
    • Building images: buildImageCmd()
    • Inspecting images: inspectImageCmd("id")
    • Tagging images: tagImageCmd("id", "repository", "tag")
    • Pushing images: pushImageCmd("repository")
    • Pulling images: pullImageCmd("repository")
    • Removing images: removeImageCmd("id")
    • Search in registry: searchImagesCmd("text")
  • Container management
    • Listing containers: listContainersCmd()
    • Creating containers: createContainerCmd("repository:tag")
    • Starting containers: startContainerCmd("id")
    • Stopping containers: stopContainerCmd("id")
    • Killing containers: killContainerCmd("id")
    • Inspecting containers: inspectContainerCmd("id")
    • Creating a snapshot: commitCmd("id")
  • Volume management
    • Listing volumes: listVolumesCmd()
    • Inspecting volumes: inspectVolumeCmd("id")
    • Creating volumes: createVolumeCmd()
    • Removing volumes: removeVolumeCmd("id")
  • Network management
    • Listing networks: listNetworksCmd()
    • Creating networks: createNetworkCmd()
    • Inspecting networks: inspectNetworkCmd().withNetworkId("id")
    • Removing networks: removeNetworkCmd("id")

And, that is all. There is a project suing some of the operations listed here. It is call country, it is one of my learning projects, and you can find it here.

Concretely, you can find the code using the docker java client library here, and the code using this library here, specifically in the class PopulationDevelopmentConfig.

I hope you find it useful.

Docker Java Client

Java reflection: Accessing a private field

Sometimes, when we import 3rd-party libraries, we can find cases where the information we want is has been populated in an object but, the property is a private one and there are no methods to recover it. Here, it is where the Java reflection capabilities can help us.

Note: Use reflection carefully and, usually, as a last resource.

Let’s say we have a simple class with a private property:

class A {
    private String value = "value";
}

We want to access the property “value” but, for obvious reasons, we cannot do it.

We can implement our reflection method to access the property value:

import java.lang.reflect.Field;

public class Reflection {

   public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
      final A a = new A();
      final Field secureRenegotiationField = a.getClass().getDeclaredField("value");

      secureRenegotiationField.setAccessible(true);

      System.out.println((String) secureRenegotiationField.get(a));
   }
}

With these few lines of code, we will be able to access the value.

Java reflection: Accessing a private field

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

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&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <servlet-class&gt;com.wordpress.binaycoders.examples.BasicServlet</servlet-class&gt;
</servlet&gt;
<servlet-mapping&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <url-pattern&gt;/basicservlet</url-pattern&gt;
</servlet-mapping&gt;

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

http://localhost:8080/<theapp&gt;/basicservlet

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

<servlet-mapping&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <url-pattern&gt;/basicservlet/*</url-pattern&gt;
</servlet-mapping&gt;

Or we can define a JSP page:

<servlet&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <jsp-file&gt;/page.jsp</jsp-file&gt;
</servlet&gt;

We can initialize some parameters when the servlet starts:

<servlet&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <servlet-class&gt;BasicServlet</servlet-class&gt;
    <init-param&gt;
        <param-name&gt;parameter</param-name&gt;
        <param-value&gt;value</param-value&gt;
    </init-param&gt;
</servlet&gt;

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&gt;
    <servlet-name&gt;basicServlet</servlet-name&gt;
    <servlet-class&gt;BasicServlet</servlet-class&gt;
    <load-on-startup/&gt;
</servlet&gt;
<servlet&gt;
       <servlet-name&gt;basicServlet</servlet-name&gt;
       <servlet-class&gt;BasicServlet</servlet-class&gt;
       <load-on-startup&gt;2</load-on-startup&gt;
</servlet&gt;

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&gt;");
        out.println ("<html&gt;");
        out.println ("<body&gt;");
        out.println ("<br&gt;I am the basic servlet (HTML). Welcome!");
        out.println ("</body&gt;");
        out.println ("</html&gt;");
    }
 
    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

Customized date format in JAXB

Nowadays, it is very common to work with JAXB to help us to marshal and unmarshal objects into XML or XML into objects. These objects can be simple object or objects created by us if we use the correct annotations. It is clear that JAXB is very useful but, sometimes, it is not enough with the default values the API is offering us.

Recently, we had a problem with the date format. The external system where we were trying to send information was expecting a very concrete pattern for the date objects in the XML, and the default format JAXB was offering us was not correct. After test a couple of solutions, we find one that it was working very good and it was quite simple to implement.

The idea was to rewrite the adapter with the desired format and after that, using the correct annotation, tell JAXB be the correct format. Easier than it sounds.

The first step is to write our adapter object extending the object XmlAdapter. In there, we can define the exact format we want to use when the marshalling operation is performed.

package com.wordpress.binarycoders.services.jaxb.utils;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
 
public class DateAdapter extends XmlAdapter<String, XMLGregorianCalendar&gt; {
 
    private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
    @Override
    public String marshal(XMLGregorianCalendar v) throws Exception {
        Calendar calendar = v.toGregorianCalendar();
         
        return dateFormat.format(calendar.getTime());
    }
 
    @Override
    public XMLGregorianCalendar unmarshal(String v) throws Exception {
         
        GregorianCalendar c = new GregorianCalendar();
        c.setTime(dateFormat.parse(v));
         
        return  DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    }
}

This example is using a XMLGregorianCalendar object, but this can be done with any date object.

The second step, it is to indicate JAXB that this adapter should be used instead of the default one. We do this with the annotation @XmlJavaTypeAdapter. Something like this:

@XmlSchemaType(name = "date")
@XmlJavaTypeAdapter(DateAdapter.class)
protected XMLGregorianCalendar date;

That´s all. Now, when the marshaling operation is performed, we should obtain the desired date format in our XMLs.

See you.

Customized date format in JAXB

Checksum calculation

Today, we have another little code snipped. Sometimes, we need to transfer files between systems, and in these cases, it is usually interesting to have some kind of system to check the file content integrity. In these cases, it is when a checksum can be very useful. Here we have a little implementation done in Java. Simple to write, simple to use.

package com.wordpress.binarycoders.checksum;
 
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
 
public class CheckSum {
 
    private static final String MD5 = "MD5";
    private static final String SHA1 = "SHA-1";
     
    public static String md5CheckSum(byte[] content) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance(MD5);
         
        return byteArray2Hex(md.digest(content));
    }
     
    public static String sha1CheckSum(byte[] content) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance(SHA1);
         
        return byteArray2Hex(md.digest(content));
    }
     
    private static String byteArray2Hex(final byte[] hash) {
        String result = "";
         
        try (Formatter formatter = new Formatter()) {
            for (byte b : hash) {
                formatter.format("%02x", b);
            }
             
            result = formatter.toString();
        }
         
        return result;
    }
}

See you.

Checksum calculation

Image URL to byte array

Today, I only have a little code snippet to take a URL with an image and transform it in a byte array in Java 8, the image, not the URL. It is something very simple, but sometimes, it is very useful to have this kind of snippets in a place where we can find it easily.

package com.wordpress.binarycoders.image.recovery;
 
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class ImageRecover {
     
    public byte[] recoverImageFromUrl(String urlText) throws Exception {
        URL url = new URL(urlText);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
         
        try (InputStream inputStream = url.openStream()) {
            int n = 0;
            byte [] buffer = new byte[ 1024 ];
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
        }
     
        return output.toByteArray();
    }
}

See you.

Image URL to byte array