Welcome! Please see the About page for a little more info on how this works.

0 votes
in Java Interop by

Before patch:

`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (.f ^I p)

ClassCastException user.proxy$java.lang.Object$I$383c225e cannot be cast to user.I user$eval7491.invokeStatic (:1)
`

After patch:

`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))

'user/p

user=> (.f ^I p)
1
`

Cause: proxy caches the generated class using a set of classnames (see https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L280-L286), this is not safe under redefinition of interfaces

Proposed: change the hashing function used to determine proxy class cache hits to take into account the identity of each interface/super class rather than just their name

Patch: 0001-CLJ-2379-idempotent-proxy-name-just-on-identical-ins-v2.patch

6 Answers

0 votes
by

Comment made by: alexmiller

Can you add a Proposed line to the description explaining the change?

0 votes
by

Comment made by: alexmiller

I'm not sure I get the problem/solution here.

0 votes
by

Comment made by: bronsa

sure, done

0 votes
by

Comment made by: alexmiller

Looks like this breaks the serialized objects in the (admittedly fragile) clojure.test-clojure.java-interop/test-proxy-non-serializable (see CLJ-2204, CLJ-2330).

0 votes
by

Comment made by: bronsa

As discussed in #clojure-dev, attached patch that disables the brittle tests and restores the determinism of proxy-name.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-2379 (reported by bronsa)
...