|
| 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 | + |
0 commit comments