- 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)
}
}
Subscribe to:
Comments (Atom)