Although I believe I have a solid beginner's understanding of Clojure, I am fairly at sea when interoperating with Java.
Thus I am struggling to fix some (unavoidable) interop code that generates JVM warnings. This is the code, it takes a W3C dom node and creates an LS serializer from it so I can spit out the corresponding XML string:
(defn serializer
[node]
(let [serializer (-> node
.getOwnerDocument
.getImplementation
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
The code works fine and did not result in warnings until a recent system update.
But JVM (for openjdk 11.0.10) does not seem to like the call to .getOwnerDocument
and it also does not like the call to .getImplementation
as I discovered when I rewrote to avoid the call to .getOwnerDocument
. The exact warning (arrows/linebreaks added):
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x00000008401e8040
(file:/home/user/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar)
-->to method com.sun.org.apache.xerces.internal.dom.NodeImpl.getOwnerDocument()<--
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x00000008401e8040
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
From this StackOverflow discussion it appears casting should be involved in the call to .getImplementation
, like so:
DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation();
LSSerializer lsSerializer = domImplementation.createLSSerializer();
This discussion seems to indicate that casting is not needed in Clojure and you can avoid reflection by type hinting:
(defn bar [^String x]
(.toCharArray x))
So I rewrote my function to use type hinting:
(defn serializer
[^com.sun.org.apache.xerces.internal.dom.NodeImpl node]
(let [serializer (-> node
.getOwnerDocument
.getImplementation
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
This seems to get me past warnings on .getOwnerDocument
and .getImplementation
. But now it's warning me about the call to .createLSSerializer
, which is a bit frustrating as I seem to be calling this last method exactly and on the same type of object as the well upvoted answer I quoted from this discussion above. This is the error I get with the type hinting (arrows/linebreaks added):
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x00000008401e8040
(file:/home/user/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar)
-->to method com.sun.org.apache.xerces.internal.dom.CoreDOMImplementationImpl.createLSSerializer()<--
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x00000008401e8040
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
If anyone has ideas on how to resolve this, or suggested areas for me to read up on in Java, I'd be very grateful. Thanks for any help.