Skip to content

Commit fb44c29

Browse files
committed
ch 9 gen-class example tweaks
1 parent 28368f1 commit fb44c29

3 files changed

Lines changed: 76 additions & 2 deletions

File tree

ch09-gen-class/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
## _Clojure Programming_, Chapter 9
2+
3+
### `gen-class`
4+
5+
This project contains examples related to using `gen-class` to generate
6+
Java-style classes from within Clojure.
7+
8+
9+
#### "Wrapping" a Clojure API with a Java-friendly class
10+
11+
The
12+
[`com.clojurebook.imaging`](src/com/clojurebook/imaging.clj)
13+
namespace defines a Clojure API for loading and resizing images. It then uses `gen-class` to produce a Java class (`ResizeImage` in the default package) whose static utility methods delegate to the API's `resize-image` function.
14+
15+
You can see this in action by first building an uberjar containing all
16+
of the code in the project, and its dependencies:
17+
18+
```
19+
$ lein uberjar
20+
```
21+
22+
Then you can choose to run either `ResizeImage` directly:
23+
24+
```
25+
$ java -cp target/gen-class-1.0.0-standalone.jar ResizeImage clojure.png small.png 0.3
26+
```
27+
28+
…or you can run a [Java shim class](src/ResizeClient.java) that calls
29+
into `ResizeImage` to demonstrate that Java->Clojure interop:
30+
31+
```
32+
$ java -cp target/gen-class-1.0.0-standalone.jar ResizeClient clojure.png java-small.png 0.3
33+
```
34+
35+
#### A custom `Exception` type
36+
37+
The
38+
[`com.clojurebook.CustomException`](src/com/clojurebook/CustomException.clj)
39+
namespace defines a custom `Exception` subclass that has a couple of interesting properties:
40+
41+
* a `java.util.Map` value can be provided when constructing an instance
42+
of `CustomException`
43+
* `CustomException` implements Clojure's `IDeref` interface, so
44+
instances can be dereferenced (i.e. `@e`) to easily obtain the
45+
aforementioned `java.util.Map`.
46+
47+
The [`BatchJob`](src/BatchJob.java) class shows an example of using this
48+
custom `Exception` type from Java. Assuming you've built an uberjar
49+
(`lein uberjar`), you can run `BatchJob`'s `main` method, which echos
50+
the contents of the exception's info map:
51+
52+
```
53+
$ java -cp target/gen-class-1.0.0-standalone.jar BatchJobError! Operation failed {"timestamp" 1333488510315, "customer-id" 89045, "priority" "critical", "jobId" "verify-billings"}
54+
```
55+
56+
57+
58+

ch09-gen-class/java-resize.png

-679 Bytes
Binary file not shown.

ch09-gen-class/project.clj

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
(defproject com.clojurebook/gen-class "1.0.0"
2+
:description "A set of examples showing how you can use the
3+
`gen-class` form to produce full-featured Java classes from Clojure.
4+
From chapter 9 of 'Clojure Programming' by Emerick, Carper, and Grand."
5+
:url "http://github.com/clojurebook/ClojureProgramming"
26
:dependencies [[org.clojure/clojure "1.3.0"]]
3-
:aot :all
4-
:warn-on-reflection true)
7+
:aot :all)
8+
9+
(require '(leiningen compile javac)
10+
'robert.hooke)
11+
12+
(robert.hooke/add-hook #'leiningen.compile/compile
13+
(fn [compile project & args]
14+
(apply compile project args)
15+
(leiningen.javac/javac (assoc project
16+
;; Leiningen 1 uses :java-source-path
17+
:java-source-path "src"
18+
;; Lein 2 uses :java-source-paths
19+
:java-source-paths ["src"]))))
20+

0 commit comments

Comments
 (0)