| 1 | JSS |
|---|
| 2 | === |
|---|
| 3 | |
|---|
| 4 | Created by Alan Ruttenberg |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | JSS stands for either "Java Simple Syntax" or "Java Syntax Sucks", |
|---|
| 8 | depending on your mood. |
|---|
| 9 | |
|---|
| 10 | The dynamic dispatch of the java.lang.reflect package is used to make |
|---|
| 11 | it real easy, if perhaps less efficient, to write Java code since you |
|---|
| 12 | don't need to be bothered with imports, or with figuring out which |
|---|
| 13 | method to call. The only time that you need to know a class name is |
|---|
| 14 | when you want to call a static method, or a constructor, and in those |
|---|
| 15 | cases, you only need to know enough of the class name that is unique |
|---|
| 16 | wrt to the classes on your classpath. |
|---|
| 17 | |
|---|
| 18 | Java methods look like this: #"toString". Java classes are represented |
|---|
| 19 | as symbols, which are resolved to the appropriate java class |
|---|
| 20 | name. When ambiguous, you need to be more specific. A simple example |
|---|
| 21 | from CL-USER: |
|---|
| 22 | |
|---|
| 23 | (require :jss) |
|---|
| 24 | (in-package :jss) |
|---|
| 25 | (let ((sw (new 'StringWriter))) |
|---|
| 26 | (#"write" sw "Hello ") |
|---|
| 27 | (#"write" sw "World") |
|---|
| 28 | (print (#"toString" sw))) |
|---|
| 29 | |
|---|
| 30 | What's happened here? First, all the classes in all the jars in the |
|---|
| 31 | classpath have been collected. For each class a.b.C.d, we have |
|---|
| 32 | recorded that b.c.d, b.C.d, C.d, c.d, and d potentially refer to this |
|---|
| 33 | class. In your call to new, as long as the symbol can refer to only |
|---|
| 34 | one class, we use that class. In this case, it is |
|---|
| 35 | java.io.StringWriter. You could also have written |
|---|
| 36 | |
|---|
| 37 | (new 'io.stringwriter) |
|---|
| 38 | |
|---|
| 39 | or |
|---|
| 40 | (new '|io.StringWriter|) |
|---|
| 41 | |
|---|
| 42 | or |
|---|
| 43 | (new 'java.io.StringWriter) |
|---|
| 44 | |
|---|
| 45 | The call |
|---|
| 46 | |
|---|
| 47 | (#"write" sw "Hello ") |
|---|
| 48 | |
|---|
| 49 | uses the code in invoke.java to call the method named "write" with |
|---|
| 50 | the arguments sw and "Hello ". JSS figures out the right java method |
|---|
| 51 | to call, and calls it. |
|---|
| 52 | |
|---|
| 53 | An interactive restart is available to resolve class ambiguity. |
|---|
| 54 | |
|---|
| 55 | Static calls are possible as well with the #" macro, but the |
|---|
| 56 | first argument MUST BE A SYMBOL to distinguish |
|---|
| 57 | |
|---|
| 58 | (#"getProperties" "java.lang.System") |
|---|
| 59 | |
|---|
| 60 | from |
|---|
| 61 | |
|---|
| 62 | (#"getProperties" 'java.lang.System) |
|---|
| 63 | |
|---|
| 64 | The first attempts to call a method on the java.lang.String object |
|---|
| 65 | with the contents "java.lang.System", which results in an error, while |
|---|
| 66 | the second invokes the static java.lang.System.getProperties() method. |
|---|
| 67 | |
|---|
| 68 | If you want to do a raw java call, use #0"toString". Raw calls |
|---|
| 69 | return their results as Java objects, avoiding doing the usual Java |
|---|
| 70 | object to Lisp object conversions that ABCL does. |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | (with-constant-signature ((name jname raw?)*) &body body) |
|---|
| 74 | |
|---|
| 75 | binds a macro which expands to a jcall, promising that the same method |
|---|
| 76 | will be called every time. Use this if you are making a lot of calls and |
|---|
| 77 | want to avoid the overhead of a the dynamic dispatch. |
|---|
| 78 | e.g. |
|---|
| 79 | |
|---|
| 80 | (with-constant-signature ((tostring "toString")) |
|---|
| 81 | (time (dotimes (i 10000) (tostring "foo")))) |
|---|
| 82 | |
|---|
| 83 | runs about three times faster than |
|---|
| 84 | |
|---|
| 85 | (time (dotimes (i 10000) (#"toString" "foo"))) |
|---|
| 86 | |
|---|
| 87 | So, something like |
|---|
| 88 | |
|---|
| 89 | (with-constant-signature ((tostring "toString" t)) ...) |
|---|
| 90 | |
|---|
| 91 | will cause the toString to be a raw java call. See |
|---|
| 92 | JSS::GET-ALL-JAR-CLASSNAMES for an example. |
|---|
| 93 | |
|---|
| 94 | Implementation is that the first time the function is called, the |
|---|
| 95 | method is looked up based on the arguments passed, and thereafter |
|---|
| 96 | that method is called directly. Doesn't work for static methods at |
|---|
| 97 | the moment (lazy) |
|---|
| 98 | |
|---|
| 99 | (japropos string) finds all class names matching string |
|---|
| 100 | |
|---|
| 101 | (jcmn class-name) lists the names of all methods for the class |
|---|
| 102 | |
|---|
| 103 | Compatibility |
|---|
| 104 | ------------- |
|---|
| 105 | |
|---|
| 106 | The function ENSURE-COMPATIBILITY attempts to provide a compatibility |
|---|
| 107 | mode to existing users of JSS by importing the necessary symbols into |
|---|
| 108 | CL-USER. |
|---|
| 109 | |
|---|
| 110 | Some notes on other compatibility issues: |
|---|
| 111 | |
|---|
| 112 | *classpath-manager* |
|---|
| 113 | |
|---|
| 114 | Since we are no longer using Beanshell, this is no longer present. |
|---|
| 115 | For obtaining the current classloader use JAVA:*CLASSLOADER*. |
|---|
| 116 | |
|---|
| 117 | # API |
|---|
| 118 | |
|---|
| 119 | 1.0 |
|---|
| 120 | Equivalent to Alan Ruttenberg's version included with the original |
|---|
| 121 | [lsw](). |
|---|
| 122 | |
|---|
| 123 | [lsw]: http://mumble.net:8080/svn/lsw/trunk/ |
|---|
| 124 | [lsw2]: let-me-google-that-for-you |
|---|
| 125 | |
|---|
| 126 | |
|---|
| 127 | 3.0 |
|---|
| 128 | In the JSS package loaded from [abcl-contrib]() |
|---|
| 129 | |
|---|
| 130 | abcl-contrib: http://abcl.org/svn/trunk/abcl/contrib/ |
|---|
| 131 | |
|---|
| 132 | # Colophon |
|---|
| 133 | |
|---|
| 134 | <> dc:created "2005" ; |
|---|
| 135 | dc:author "Mark <evenson.not.org@gmail.com>"; |
|---|
| 136 | dc:revised "06-DEC-2012" ; |
|---|
| 137 | <> abcl:documents <urn:abcl.org/release/1.3.0-dev/contrib/jss#3.0.5" . |
|---|
| 138 | |
|---|
| 139 | |
|---|