Sunday, February 4, 2018

Getting Started with Python's Virtualenv

This blog will teach you how to get started with virtualenv in Python. First install virtualenv if you have not installed it.
pip install virtualenv
Create a new virtualenv directory called hello.
virtualenv hello
The above command will a standard Python installation.
hello/
├── bin
├── include
├── lib
└── pip-selfcheck.json

To activate the virtualenv we just created, we need to source the activate script in the bin directory. Once we are in the virtualenv environment, we can install any Python libraries we want and the libraries will be installed in the hello virtualenv we just created, e.g.
cd hello
source bin/activate
pip install requests
To quit the virtualenv, simply type
deactivate
Let's now create a simple script that uses the new request module we just installed.
test.py
import requests

if __name__ == '__main__':
    r = requests.get('http://www.google.com')
    print(r.status_code)
To run the script in a virtualenv.
cd hello
source bin/activate
python test.py
deactivate

Friday, January 12, 2018

Getting Started with Java Module System

In this blog, I'm going to teach you how to get started with Java module system.
build.gradle
apply plugin: "java"

sourceCompatibility = 1.9

Now let's add module-info.java and put it in the root project.
module jigsaw {
}

Your project structure should look like this.
|-- build.gradle
`-- src
    `-- main
        `-- java
            |-- jigsaw
            |   `-- Main.java
            `-- module-info.java
Let's now build the JAR using Gradle.
gradle

Type the following command to run the application.
java --module-path build/libs -m jigsaw/jigsaw.Main

We can still run the JAR with a module system using a standard classpath.
java -cp build/libs/jigsaw.jar jigsaw.Main

In order to make it easy to distribute the application and to reduce the Java runtime size, we can create a custom Java runtime image using jlink.
jlink --module-path "build/libs;$JAVA_HOME/jmods" --add-modules jigsaw --output jigsaw

The command above creates a Java runtime image in the directory called jigsaw.
jigsaw          
|-- bin    
|-- conf   
|-- legal  
|-- lib    
`-- release

By using jlink, the jigsaw module that we just created will be part of the Java runtime image. You will not see the jigsaw JAR gets in the Java runtime image. If you run this command below, you will see the jigsaw module is now part of the image.
$ cd jigsaw
$ bin/java --list-modules
java.base@9.0.1
jigsaw

We can now run the jigsaw module by running the Java executable inside the Java runtime image without having to specify -m option.
$ cd jigsaw
$ bin/java -m jigsaw/jigsaw.Main

Friday, June 30, 2017

How to a Build Standalone REST Application in Java

There are many frameworks that allow you to build REST easily in Java. In this blog, however, I am going tho show you how to build a standalone REST application without any framework. We are going to use the following libraries:
  1. Jetty for web server
  2. Jersey for REST
  3. Jackson for JSON
  4. Swagger for API documentation

First we need the build script. I am going to use Gradle for this.
plugins {
    id "com.github.johnrengelman.shadow" version "2.0.1"
    id "java"
}

apply plugin: "java"
apply plugin: "com.github.johnrengelman.shadow"

defaultTasks = ["clean", "build", "shadowJar"]

repositories {
    jcenter()
}

dependencies {
    // Jetty dependencies
    compile "org.eclipse.jetty:jetty-server:9.4.6.v20170531"
    compile "org.eclipse.jetty:jetty-servlet:9.4.6.v20170531"

    // Jersey dependencies
    compile "org.glassfish.jersey.core:jersey-server:2.25.1"
    compile "org.glassfish.jersey.media:jersey-media-json-jackson:2.25.1"
    compile "org.glassfish.jersey.containers:jersey-container-servlet:2.25.1"

    // Swagger dependencies
    compile "io.swagger:swagger-core:1.5.15"
    compile "io.swagger:swagger-annotations:1.5.15"
    compile "io.swagger:swagger-jersey2-jaxrs:1.5.15"
    // Required by BeanConfig
    runtime "org.codehaus.groovy:groovy:2.4.12"

    // Required by Swagger
    runtime "ch.qos.logback:logback-core:1.2.3"
    runtime "ch.qos.logback:logback-classic:1.2.3"
}

jar {
    manifest {
        attributes "Main-Class": "org.fredy.example.rest.HelloServer"
    }
}

Second, we will write a typical JAX-RS application with JAX-RS, Jackson, and Swagger annotations.
package org.fredy.example.rest;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Api(value = "/hello", description = "API for Hello")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/hello")
public class HelloResource {
    @ApiModel("request")
    public static class HelloRequest {
        @ApiModelProperty(value = "The name", required = true)
        private final String name;

        @JsonCreator
        public HelloRequest(@JsonProperty("name") String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    @ApiModel("response")
    public static class HelloResponse {
        @ApiModelProperty(value = "The message", required = true)
        private final String message;

        @JsonCreator
        public HelloResponse(@JsonProperty("message") String message) {
            this.message = message;
        }

        public String getMessage() {
            return message;
        }
    }

    @ApiOperation(value = "Gets the message", response = HelloResponse.class)
    @ApiResponse(code = 200, message = "Successful operation")
    @Path("/message")
    @POST
    public Response getMessage(HelloRequest request) {
        return Response.ok(new HelloResponse("Hello, " + request.getName())).build();
    }
}

Third, we will need to register our REST resource into Jetty and start the server.
package org.fredy.example.rest;

import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.jaxrs.listing.SwaggerSerializers;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.servlet.ServletContainer;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.util.StringJoiner;

public class HelloServer {
    public static class Bootstrap extends HttpServlet {
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);

            BeanConfig beanConfig = new BeanConfig();
            beanConfig.setTitle("Hello API");
            beanConfig.setVersion("1.0.0");
            beanConfig.setSchemes(new String[]{"http"});
            beanConfig.setBasePath("/api");
            beanConfig.setResourcePackage("org.fredy.example.rest");
            beanConfig.setScan(true);
        }
    }

    public static void main(String[] args) throws Exception {
        ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletHandler.setContextPath("/");

        ServletHolder jerseyServlet = servletHandler.addServlet(ServletContainer.class, "/api/*");
        jerseyServlet.setInitOrder(0);

        jerseyServlet.setInitParameter(
            ServerProperties.PROVIDER_CLASSNAMES,
            new StringJoiner(",")
                .add(HelloResource.class.getCanonicalName())
                .add(JacksonJsonProvider.class.getCanonicalName())
                .add(ApiListingResource.class.getCanonicalName())
                .add(SwaggerSerializers.class.getCanonicalName())
            .toString());

        ResourceHandler staticHandler = new ResourceHandler();
        staticHandler.setWelcomeFiles(new String[]{"index.html"});
        staticHandler.setBaseResource(Resource.newClassPathResource("/webapp"));

        HandlerList handlers = new HandlerList();
        // Add two handlers, one for static content and the other one for dynamic content.
        handlers.setHandlers(new Handler[]{staticHandler, servletHandler});

        // The mapping doesn't really matter here.
        ServletHolder swaggerServlet = servletHandler.addServlet(Bootstrap.class, "/");
        swaggerServlet.setInitOrder(2);

        Server jettyServer = new Server(8080);
        jettyServer.setHandler(handlers);

        try {
            jettyServer.start();
            jettyServer.join();
        } finally {
            jettyServer.destroy();
        }
    }
}

Few important things to note.
  1. Add the Jersey servlet container (org.glassfish.jersey.servlet.ServletContainer). This servlet implementation comes from Jersey library.
  2. Register some providers, such as our own REST provider (org.fredy.example.rest.HelloResource), Jackson provider (com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider), and Swagger providers (io.swagger.jaxrs.listing.ApiListingResource and io.swagger.jaxrs.listing.SwaggerSerializers). The Swagger providers will create swagger.json specified by the servlet mapping path, which is api/swagger.json in this case.

Lastly, we need to add some Swagger UI so that we can display the API documentation in a nice format. What we need is basically download Swagger UI from https://github.com/swagger-api/swagger-ui and copy the dist directory into src/main/resources. The goal of this is to keep the Swagger UI in the JAR and is available in the classpath. Swagger UI is just a static content and we can tell Jetty to serve static content by using org.eclipse.jetty.server.handler.ResourceHandler. Make sure to modify the URL in Swagger's index.html from http://petstore.swagger.io/v2/swagger.json to http://localhost:8080/api/swagger.json since that's where our swagger.json file lives. To build and run the example, we can type the following command.
./gradlew && java -jar build/libs/java-rest-swagger-example-all.jar
Full source code can be found here.

Thursday, April 6, 2017

How to Shade a JAR and Relocate Classes in Maven

The example below shows how to shade org.fredy.myjar and guava JARS and rename the Guava classes that contain com.google.guava to org.fredy.com.google.guava.
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.fredy</groupId>
  <artifactId>shaded</artifactId>
  <version>0.0.1</version>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.fredy</groupId>
      <artifactId>myjar</artifactId>
      <version>0.0.1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <relocations>
            <relocation>
              <pattern>com.google.common</pattern>
              <shadedPattern>org.fredy.com.google.common</shadedPattern>
            </relocation>
          </relocations>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <filters>
                <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                  </excludes>1
                </filter>
              </filters>
              <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Friday, March 3, 2017

How to Cancel a Goroutine in Go

The example below shows how to cancel a goroutine while is in the middle of executing a long-running task.
package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    busyChan := make(chan bool)

    ctx, cancel := context.WithCancel(context.Background())
    go func(ctx context.Context) {
        for {
            select {
            case <-busyChan:
                fmt.Println("Pretending to be very busy")
                time.Sleep(5000 * time.Second)
            case <-ctx.Done():
                return
            }
        }
    }(ctx)
    busyChan <- true
    fmt.Println("Doing some other things")
    time.Sleep(3 * time.Second)
    fmt.Println("Stopping the goroutine")
    cancel()
}
Output:
Prentending to be very busy
Doing some other things
Stopping the goroutine

Wednesday, February 22, 2017

How to Embed JavaScript in Java

Java 8 came with a JavaScript engine called Nashorn. This makes it easy to call some JavaScript code from Java. In this example, I'm going to show how to pass some Java object into JavaScript and vice-versa as well as calling creating a Java object from JavaScript.
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;
import java.util.Map;

public class JsExample {
    public static class JavaClass {
        public String greet() {
            return "Hello from Java";
        }
    }

    public static void main(String[] args) throws Exception {
        final String script =
            "var File = Java.type(\"java.io.File\");" +
            "print(new File(\".\").exists());" +
            "var map = {\"msg\": \"Hello from JS\"};" +
            "print(javaClass.greet());" +
            "map;";

        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

        Bindings bindings = new SimpleBindings();
        bindings.put("javaClass", new JavaClass());

        Map<String, String> retVal = (Map<String, String>) engine.eval(script, bindings);
        System.out.println(retVal.get("msg"));
    }
}
Output:
true
Hello from Java
Hello from JS

Wednesday, December 14, 2016

How to Use Jetty to Serve Static Content

  1. Download Jetty.
  2. Extract it to some location. We will call this JETTY_HOME.
  3. Set JETTY_BASE environment variable. This is a separate directory where your configurations live.
  4. Copy $JETTY_HOME/start.ini into $JETTY_BASE.
  5. Create $JETTY_BASE/webapps directory.
  6. Create $JETTY_BASE/webapps/scratch.xml with the content explained here.
  7. Start Jetty by running $JETTY_HOME/bin/jetty.sh start.
  8. Stop Jetty by running $JETTY_HOME/bin/jetty.sh stop.