如何避免;“非法反射访问”;Clojure互操作中的警告。(演员?)
尽管我相信我对Clojure有着坚实的初学者理解,但在与Java进行互操作时,我还是茫然不知所措 因此,我正在努力修复一些(不可避免的)生成JVM警告的互操作代码。这是代码,它获取一个W3C dom节点并从中创建一个LS序列化程序,这样我就可以输出相应的XML字符串:如何避免;“非法反射访问”;Clojure互操作中的警告。(演员?),clojure,Clojure,尽管我相信我对Clojure有着坚实的初学者理解,但在与Java进行互操作时,我还是茫然不知所措 因此,我正在努力修复一些(不可避免的)生成JVM警告的互操作代码。这是代码,它获取一个W3C dom节点并从中创建一个LS序列化程序,这样我就可以输出相应的XML字符串: (defn serializer [node] (let [serializer (-> node .getOwnerDocument
(defn serializer
[node]
(let [serializer (-> node
.getOwnerDocument
.getImplementation
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
该代码工作正常,直到最近的系统更新后才出现警告
但是JVM(对于openjdk 11.0.10)似乎不喜欢调用.getOwnerDocument
,它也不喜欢调用.getImplementation
,正如我在重写以避免调用.getOwnerDocument
时发现的那样。确切的警告(添加了箭头/换行符):
似乎表明Clojure中不需要强制转换,您可以通过类型暗示来避免反射:
(defn bar [^String x]
(.toCharArray x))
(defn serializer
[^com.sun.org.apache.xerces.internal.dom.NodeImpl node]
(let [serializer (-> node
.getOwnerDocument
.getImplementation
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
因此,我重写了我的函数以使用类型提示:
(defn bar [^String x]
(.toCharArray x))
(defn serializer
[^com.sun.org.apache.xerces.internal.dom.NodeImpl node]
(let [serializer (-> node
.getOwnerDocument
.getImplementation
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
这似乎让我越过了.getOwnerDocument
和.getImplementation
上的警告。但是现在它警告我调用.createLSSerializer
,这有点令人沮丧,因为我似乎在调用最后一个方法,并且调用的对象类型与我上面引用的答案完全相同。这是我在类型提示中遇到的错误(添加了箭头/换行符):
警告:clojure.lang.InjectedInvoker/0x00000008401e8040非法反射访问
(文件:/home/user/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar)
-->对于方法com.sun.org.apache.xerces.internal.dom.CoredomImplementImpl.createLSSerializer(),答案显然是提供一个额外的类型提示,如下所示:
DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation();
LSSerializer lsSerializer = domImplementation.createLSSerializer();
(defn serializer
[^com.sun.org.apache.xerces.internal.dom.NodeImpl node]
(let [serializer (-> node
.getOwnerDocument
^com.sun.org.apache.xerces.internal.dom.CoreDOMImplementationImpl
(.getImplementation)
.createLSSerializer)]
(.setParameter (.getDomConfig serializer) "xml-declaration" false)
serializer))
我之所以发现这一点,是因为在我的问题旁边找到了一个“相关”的问题/答案。抱歉没有提前找到它,如果有人遇到相同的问题,此线程可能会提供一些帮助。您还可以通过使用javax.xml.transform.Transformer进行序列化来避免非法的反射访问(和xerces引用)。获取一个TransformerFactory,生成一个DOMSource(给它一个DOM节点),设置一个StreamResult(给一个StringWriter),并将源“转换”为结果(没有实际的XSL转换)。