Expose a subset of java.lang.ref to enable hooking into the destruction/GC of objects (#1359)

* reify java.lang.Object with optional toString and finalize

* reify java.lang.Runnable

* reflection support for java.lang.Runnable

* java.lang.ref.* class exposure

* test for detection of garbage collection of Object

* added change to changelog
This commit is contained in:
Crispin Wellington 2022-09-09 23:25:32 +08:00 committed by GitHub
parent c4c76d58ac
commit ea4f56886d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 1 deletions

View file

@ -5,6 +5,10 @@ For a list of breaking changes, check [here](#breaking-changes).
A preview of the next release can be installed from
[babashka-dev-builds](https://github.com/babashka/babashka-dev-builds).
## Unreleased
- [#1358](https://github.com/babashka/babashka/issues/1358): Expose a subset of java.lang.ref to enable hooking into the destruction/GC of objects
## 0.9.162 (2022-09-04)
Check out our new project: [bbin](https://github.com/babashka/bbin): install any Babashka script or project with one command.

View file

@ -61,6 +61,19 @@
java.lang.Object
(toString [this] (toString-fn this)))))
(defn reify-runnable [m]
(let [methods (:methods m)
run-fn (or (get methods 'run)
(fn [_]))]
(reify
sci.impl.types.IReified
(getMethods [_] (:methods m))
(getInterfaces [_] (:interfaces m))
(getProtocols [_] (:protocols m))
java.lang.Runnable
(run [this] (run-fn this))))
)
(defmacro gen-reify-fn []
`(fn [~'m]
(when (> (count (:interfaces ~'m)) 1)
@ -78,7 +91,9 @@
["clojure.lang.IFn"
`(reify-ifn ~'m)
"java.lang.Object"
`(reify-object ~'m)]
`(reify-object ~'m)
"java.lang.Runnable"
`(reify-runnable ~'m)]
(for [i interfaces]
(let [in (.getName ^Class i)]
[in

View file

@ -84,6 +84,8 @@
java.lang.reflect.Array
{:methods [{:name "newInstance"}
{:name "set"}]}
java.lang.Runnable
{:methods [{:name "run"}]}
java.net.Inet4Address
{:methods [{:name "getHostAddress"}]}
java.net.Inet6Address
@ -264,6 +266,9 @@
java.lang.System
java.lang.Throwable
;; java.lang.UnsupportedOperationException
java.lang.ref.WeakReference
java.lang.ref.ReferenceQueue
java.lang.ref.Cleaner
java.math.BigDecimal
java.math.BigInteger
java.math.MathContext

View file

@ -128,3 +128,26 @@
(reify
java.lang.Object (toString [_] \"foo\")
clojure.lang.Seqable (seq [_] '(1 2 3)))")))))
(deftest reify-runnable-and-garbage-collection-test
(is (bb nil "
(def cleaner (java.lang.ref.Cleaner/create))
(def deleted? (atom false))
(defn make-cleanable-ref []
(let [obj (Object.)]
(.register cleaner obj
(reify java.lang.Runnable
(run [_]
(reset! deleted? true))))
nil))
(defn force-gc []
(let [t (atom (Object.))
wr (java.lang.ref.WeakReference. @t)]
(reset! t nil)
(while (.get wr)
(System/gc)
(System/runFinalization))))
(make-cleanable-ref)
(force-gc)
@deleted?
")))