- Download Jetty.
- Extract it to some location. We will call this JETTY_HOME.
- Set JETTY_BASE environment variable. This is a separate directory where your configurations live.
- Copy $JETTY_HOME/start.ini into $JETTY_BASE.
- Create $JETTY_BASE/webapps directory.
- Create $JETTY_BASE/webapps/scratch.xml with the content explained here.
- Start Jetty by running $JETTY_HOME/bin/jetty.sh start.
- Stop Jetty by running $JETTY_HOME/bin/jetty.sh stop.
Wednesday, December 14, 2016
How to Use Jetty to Serve Static Content
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.
- It can be used to build a library.
- It can be used to build an executable.
- It is go-gettable.
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/fooTo 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 2
- 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);
}
}
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);
}
}
Thursday, April 21, 2016
How to Create a Command Line Spinner in Go
package main
import "fmt"
import "time"
func main() {
chars := "|/-\\"
i := 0
for {
i++
char := chars[i%len(chars)]
fmt.Printf("\rDownloading: %c", char)
time.Sleep(100 * time.Millisecond)
}
}
Monday, August 17, 2015
Parallel Merge Sort using Fork and Join
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class MergeSortForkJoin {
public static class MergeSortTask extends RecursiveAction {
private static final long serialVersionUID = 1L;
private final List<Integer> list;
private final int lo;
private final int hi;
public MergeSortTask(List<Integer> list, int lo, int hi) {
this.list = list;
this.lo = lo;
this.hi = hi;
}
@Override
protected void compute() {
if (lo >= hi) {
return;
} else {
int mid = (lo + hi) / 2;
MergeSortTask task1 = new MergeSortTask(list, lo, mid);
MergeSortTask task2 = new MergeSortTask(list, mid+1, hi);
invokeAll(task1, task2);
merge(list, lo, mid, hi);
}
}
private void merge(List<Integer> list, int lo, int mid, int hi) {
List<Integer> tmp = new ArrayList<>();
for (int i : list) {
tmp.add(i);
}
int left = lo;
int right = mid + 1;
int idx = lo;
while (left <= mid && right <= hi) {
if (tmp.get(left) <= tmp.get(right)) {
Integer element = tmp.get(left);
list.set(idx, element);
left++;
idx++;
} else {
Integer element = tmp.get(right);
list.set(idx, element);
right++;
idx++;
}
}
while (left <= mid) {
Integer element = tmp.get(left);
list.set(idx, element);
idx++;
left++;
}
while (right <= hi) {
Integer element = tmp.get(right);
list.set(idx, element);
idx++;
right++;
}
}
}
public static void main(String[] args) throws Exception {
ForkJoinPool pool = new ForkJoinPool();
List<Integer> list = Arrays.asList(4, 9, 1, 5, 8, 0, 7, 6, 3, 2);
System.out.println("Unsorted: " + list);
MergeSortTask task = new MergeSortTask(list, 0, list.size()-1);
try {
do {
pool.execute(task);
} while (!task.isDone());
} finally {
pool.shutdown();
}
System.out.println("Sorted: " + list);
}
}
Monday, August 10, 2015
How to Organize a Go Project
The official has a good information on how to structure your Go code. In this blog, I am going to explain a little bit more about it.
Let's say we want to create a Go project containing a command and a package.
workspace1/
|-- build.sh
`-- src
`-- mylib
|-- hello
| `-- hello.go (package)
`-- main.go (command)
hello.go
package hello
import "fmt"
func SayHello() {
fmt.Println("Hello")
}
main.go
package main
import "mylib/hello"
func main() {
hello.SayHello()
}
build.sh
#!/bin/bash export GOPATH=`pwd` go install mylib/hello go install mylibCalling build.sh will create this structure.
workspace1/
|-- bin
| `-- mylib (executable)
|-- build.sh
|-- pkg
| `-- linux_amd64
| `-- mylib
| `-- hello.a (library)
`-- src
`-- mylib
|-- hello
| `-- hello.go (package)
`-- main.go (command)
In order to make mylib project go-gettable, let's make it into a Git project. Take a note that we will be creating a Git project in the mylib directory and not in the workspace1 directory.
1. cd workspace1/src/mylib 2. git init 3. git add . 4. git commit -m "Initial commit" 5. Push this repository to the remote URLNow let's create another project that uses mylib. This new project is a simple project that uses mylib.
workspace2/
|-- build.sh
`-- src
`-- myapp
`-- app
`-- app.go (command)
1. cd workspace2 2. git init 3. git add submodule [mylib_git_url] src/mydomain/user/mylib (the src/mydomain/user is just a convention, you can also set the path to src/mylib)After the submodule addition, we will have this structure.
workspace2/
|-- build.sh
`-- src
|-- myapp
| `-- app
| `-- app.go (command)
`-- mydomain
`-- user
`-- mylib
|-- hello
| `-- hello.go (package)
`-- main.go (command)
app.go
package main
import (
"fmt"
"mydomain/user/mylib/hello"
)
func main() {
fmt.Println("Do something")
hello.SayHello()
}
build.sh
#!/bin/bash export GOPATH=`pwd` go install mydomain/user/mylib/hello go install myapp/appCalling build.sh will create this structure.
workspace2/
|-- bin
| `-- app (executable)
|-- build.sh
|-- pkg
| `-- linux_amd64
| `-- mydomain
| `-- user
| `-- mylib
| `-- hello.a (library)
`-- src
|-- myapp
| `-- app
| `-- app.go (command)
`-- mydomain
`-- user
`-- mylib
|-- hello
| `-- hello.go (package)
`-- main.go (command - not used)
Subscribe to:
Posts (Atom)