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 | (let ((sw (new 'StringWriter))) |
---|
25 | (#"write" sw "Hello ") |
---|
26 | (#"write" sw "World") |
---|
27 | (print (#"toString" sw))) |
---|
28 | |
---|
29 | What's happened here? First, all the classes in all the jars in the |
---|
30 | classpath have been collected. For each class a.b.C.d, we have |
---|
31 | recorded that b.c.d, b.C.d, C.d, c.d, and d potentially refer to this |
---|
32 | class. In your call to new, as long as the symbol can refer to only |
---|
33 | one class, we use that class. In this case, it is |
---|
34 | java.io.StringWriter. You could also have written |
---|
35 | |
---|
36 | (new 'io.stringwriter) |
---|
37 | |
---|
38 | or |
---|
39 | (new '|io.StringWriter|) |
---|
40 | |
---|
41 | or |
---|
42 | (new 'java.io.StringWriter) |
---|
43 | |
---|
44 | The call |
---|
45 | |
---|
46 | (#"write" sw "Hello ") |
---|
47 | |
---|
48 | uses the code in invoke.java to call the method named "write" with |
---|
49 | the arguments sw and "Hello ". JSS figures out the right java method |
---|
50 | to call, and calls it. |
---|
51 | |
---|
52 | An interactive restart is available to resolve class ambiguity. |
---|
53 | |
---|
54 | Static calls are possible as well with the SHARPSIGN-QUOTATION_MARK |
---|
55 | macro, but the first argument *must* be a symbol to distinguish |
---|
56 | |
---|
57 | (#"getProperties" "java.lang.System") |
---|
58 | |
---|
59 | from |
---|
60 | |
---|
61 | (#"getProperties" 'java.lang.System) |
---|
62 | |
---|
63 | The first attempts to call a method on the java.lang.String object |
---|
64 | with the contents "java.lang.System", which results in an error, while |
---|
65 | the second invokes the static java.lang.System.getProperties() method. |
---|
66 | |
---|
67 | If you want to do a raw java call, use #0"toString". Raw calls |
---|
68 | return their results as Java objects, avoiding doing the usual Java |
---|
69 | object to Lisp object conversions that ABCL does. |
---|
70 | |
---|
71 | |
---|
72 | (with-constant-signature ((name jname raw?)*) &body body) |
---|
73 | |
---|
74 | binds a macro which expands to a jcall, promising that the same method |
---|
75 | will be called every time. Use this if you are making a lot of calls and |
---|
76 | want to avoid the overhead of a the dynamic dispatch. |
---|
77 | e.g. |
---|
78 | |
---|
79 | (with-constant-signature ((tostring "toString")) |
---|
80 | (time (dotimes (i 10000) (tostring "foo")))) |
---|
81 | |
---|
82 | runs about three times faster than |
---|
83 | |
---|
84 | (time (dotimes (i 10000) (#"toString" "foo"))) |
---|
85 | |
---|
86 | So, something like |
---|
87 | |
---|
88 | (with-constant-signature |
---|
89 | ((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) |
---|
100 | |
---|
101 | finds all class names matching STRING. |
---|
102 | |
---|
103 | (jcmn class-name) |
---|
104 | |
---|
105 | lists the names of all methods for the CLASS-NAME. |
---|
106 | |
---|
107 | Java static fields may be addressed via the SHARPSIGN-QUOTATION_MARK macro as |
---|
108 | |
---|
109 | (#"java.lang.System.out") |
---|
110 | |
---|
111 | Java fields can by dynamically accessed with |
---|
112 | |
---|
113 | (let ((class 'java.lang.system) |
---|
114 | (field "out")) |
---|
115 | #"{class}.{field}") |
---|
116 | |
---|
117 | ### Javaparser |
---|
118 | |
---|
119 | Use #1"<java expression>" to use JAVAPARSER to parse an expression. JAVAPARSER will be loaded on first use. |
---|
120 | |
---|
121 | (#1"new ByteBuddy() |
---|
122 | .subclass(Object.class,t) |
---|
123 | .method(ElementMatchers.named("toString")) |
---|
124 | .intercept(FixedValue.value("Hello World!")) |
---|
125 | .make() |
---|
126 | .load(getClass().getClassLoader()) |
---|
127 | .getLoaded()" |
---|
128 | |
---|
129 | # Compatibility |
---|
130 | |
---|
131 | The function ENSURE-COMPATIBILITY attempts to provide a compatibility |
---|
132 | mode to existing users of JSS by importing the necessary symbols into |
---|
133 | CL-USER. |
---|
134 | |
---|
135 | Some notes on other compatibility issues: |
---|
136 | |
---|
137 | *classpath-manager* |
---|
138 | |
---|
139 | Since we are no longer using Beanshell, this is no longer present. |
---|
140 | For obtaining the current classloader use JAVA:*CLASSLOADER*. |
---|
141 | |
---|
142 | # API |
---|
143 | |
---|
144 | 1.0 |
---|
145 | Equivalent to Alan Ruttenberg's version included with the original |
---|
146 | [lsw2](). |
---|
147 | |
---|
148 | [lsw]: http://mumble.net:8080/svn/lsw/trunk/ |
---|
149 | [lsw2]: https://github.com/alanruttenberg/lsw2 |
---|
150 | |
---|
151 | |
---|
152 | 3.0 |
---|
153 | The results the of having JSS package loaded from [abcl-contrib][] |
---|
154 | |
---|
155 | [abcl-contrib]: http://abcl.org/svn/trunk/abcl/contrib/ |
---|
156 | |
---|
157 | # Colophon |
---|
158 | |
---|
159 | <> dc:created "2005" ; |
---|
160 | dc:author "Mark <evenson.not.org@gmail.com>"; |
---|
161 | dc:revised "11-JUN-2017" . |
---|
162 | |
---|
163 | |
---|
164 | |
---|