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.


Sunday, August 21, 2016

How to Use Vendoring in Go

Vendoring is a way to put dependencies in a Go project without having to mess with the GOPATH. The idea is simple, that is to put the dependencies in a directory called "vendor".
awesomego/
|-- foo (this directory contains a library, i.e. non-main package)
|   `-- foo.go
|-- main.go (this is the main program)
`-- vendor (this is where the third-party libs live)
    `-- goini
        |-- goini.go
        |-- goini_test.go
        |-- LICENSE
        |-- README.md
        `-- testdata
            |-- test_expected.ini
            `-- test.ini

The project structure above has the following benefits.
  1. It can be used to build a library.
  2. It can be used to build an executable.
  3. It is go-gettable.
This is an example of using it in a standard Go workspace.
go-workspace/
`-- src
    `-- awesomego
        |-- foo
        |   `-- foo.go
        |-- main.go
        `-- vendor
            `-- goini
                |-- goini.go
                |-- goini_test.go
                |-- LICENSE
                |-- README.md
                `-- testdata
                    |-- test_expected.ini
                    `-- test.ini
To build it as a library:
GOPATH=`pwd` go install awesomego/foo
To build it as an executable:
GOPATH=`pwd` go install awesomego

Wednesday, August 3, 2016

Compile-Time Enum in Go

Unlike other languages, Go does not support enum. However, it is pretty straightforward to create something that behaves similar to enum. There are a lot of articles on the internet on how to create an enum in Go, which pretty much looks like below.
package main

import (
    "fmt"
)

type myType string

const (
    Foo myType = "foo"
    Bar myType = "bar"
)

func doSomething(t myType) {
    fmt.Println(t)
}

func main() {
    // baz := "baz"
    // This will result in compilation error:
    // "cannot use baz (type string) as type myType in argument to doSomething"
    // doSomething(baz)

    // However, this is allowed.
    doSomething("baz")
}
As you can see in the code above, calling doSomething("baz") does not result in a compilation error. To fix that, we can change the code to look like below.
package main

import (
    "fmt"
)

type myType string

const (
    Foo myType = "foo"
    Bar myType = "bar"
)

func doSomething(t *myType) {
    fmt.Println(*t)
}

func main() {
    // This will now result in a compilation error.
    // doSomething("baz")

    baz := myType("baz")
    doSomething(&baz)
}

Wednesday, July 6, 2016

Compile-time Builder Pattern in Java

Builder pattern is a pattern that is usually used for a language that does not support named parameters. However, the typical builder pattern has a limitation, such at it can't at compile-time check the required parameters. Below are some suggestions how to use a builder pattern that has compile-time check.
  • Option 1
  • public class Foo {
        private String a;
        private String b;
        private String c;
    
        private Foo() {
        }
    
        public static ABuilder newBuilder() {
            return new ABuilder(new Foo());
        }
    
        private static class ABuilder {
            private final Foo foo;
    
            private ABuilder(Foo foo) {
                this.foo = foo;
            }
    
            public BBuilder a(String a) {
                foo.a = a;
                return new BBuilder(foo);
            }
        }
    
        private static class BBuilder {
            private final Foo foo;
    
            private BBuilder(Foo foo) {
                this.foo = foo;
            }
    
            public CBuilder b(String b) {
                foo.b = b;
                return new CBuilder(foo);
            }
        }
    
        private static class CBuilder {
            private final Foo foo;
    
            private CBuilder(Foo foo) {
                this.foo = foo;
            }
    
            public FinalBuilder c(String c) {
                foo.c = c;
                return new FinalBuilder(foo);
            }
        }
    
        private static class FinalBuilder {
            private final Foo foo;
    
            private FinalBuilder(Foo foo) {
                this.foo = foo;
            }
    
            public Foo build() {
                return foo;
            }
        }
    
        public static void main(String[] args) {
            Foo foo = Foo.newBuilder().a("a").b("b").c("c").build();
            System.out.println(foo);
        }
    }
    
  • Option 2
  • public class Bar {
        private final String a;
        private final String b;
        private final String c;
    
        public static class False {}
        public static class True {}
    
        public static class Builder<Has1, Has2, Has3> {
            private String a;
            private String b;
            private String c;
    
            public static Builder<False, False, False> create() {
                return new Builder<>();
            }
    
            public Builder<True, Has2, Has3> a(String a) {
                this.a = a;
                return (Builder<True, Has2, Has3>) this;
            }
    
            public Builder<Has1, True, Has3> b(String b) {
                this.b = b;
                return (Builder<Has1, True, Has3>) this;
            }
    
            public Builder<Has1, Has2, True> c(String c) {
                this.c = c;
                return (Builder<Has1, Has2, True>) this;
            }
        }
    
        public Bar(Builder<True, True, True> builder) {
            a = builder.a;
            b = builder.b;
            c = builder.c;
        }
    
        public static void main(String[] args) {
            Bar bar = new Bar(Builder.create().a("a").b("c").c("a"));
            System.out.println(bar);
        }
    }