【问题标题】:Call to invokeStaticMethod can't be resolved?调用invokeStaticMethod 无法解决?
【发布时间】:2012-10-04 14:17:32
【问题描述】:

我编写了一个相当原始的测试程序(我正在为 LWJGL 的 OpenGL 类编写一个包装器,主要是出于美观的原因,我决定在其中引入多线程,因为我之前实际上从未编写过并发程序)。 程序结束时,我总是收到警告

我实际上在程序进入主函数之前得到了警告。很抱歉造成混淆(我认为这可能根本不是我的程序,而是 clojure 本身的东西):

Reflection warning, NO_SOURCE_PATH:1 - call to invokeStaticMethod can't be resolved.

我在编译过程中没有收到任何警告,我觉得这很奇怪。无论如何,这是程序:

(ns opengltuts.core
  (:import (org.lwjgl.opengl GL11 Display))
  (:use opengltuts.opengl)) ;my wrapper

(def world-state (ref {:running true :color [1.0 0.0 0.0 1.0]}))

(defn render-world [state]
  (apply glClearColor (:color state))
  (glClear GL11/GL_COLOR_BUFFER_BIT)
  (Display/update))

(defn render []
  (Display/create)
  (loop []
    (let [world @world-state]
      (when (:running world)
        (do (render-world world)
          (recur)))))
  (Display/destroy))

(defn -main []
  ; without the annotation, I get a warning here too.
  (let [render-thread (doto (Thread. ^Runnable render) (.start))]
    (Thread/sleep 3000)
    (dosync (commute world-state assoc :color [0.0 1.0 0.0 1.0]))
    (Thread/sleep 3000)
    (dosync (commute world-state assoc :running false))
    (.join render-thread)))

这可能不太惯用(我听说在 Clojure 中,您通常不会使用 new Thread 来启动线程,而是使用 Agents 或其他东西,但我还没有完全掌握它是如何工作的),但我猜猜这么短的程序没关系。

【问题讨论】:

  • 如果需要简单的线程,可以使用future代替agent。即(future (render))。另外,Thread/sleep 也可以,见clojuredocs.org/clojure_core/clojure.core/future
  • 你确定警告不是来自opengltuts.opengl吗?在某处,您正在调用重载的静态方法,但它无法解析确切的调用。关于它发生在运行时,你是在运行时生成代码吗?
  • @noahz 不,我没有生成代码。这只发生在程序结束时,当我已经很长时间调用 opengl 函数时。此外,为此使用未来有点奇怪。它确实为我节省了一些点,但现在我需要在最后对 (shutdown-agents) 进行这个奇怪的调用,因为 clojure 无法确定什么时候该退出了。哦,当然,取消引用 nil 值以引起副作用也不适合我。我弄错时间了 - 我在进入主函数之前收到了警告。
  • 关于 shutdown-agents - 那是 Java Executor API,而不是 Clojure。您是否使用提前编译?
  • 提前编译?我在 lein run 之前运行 lein compile,如果这就是你的意思(确切地说,因为我尽量避免不必要的反思,只要它可以轻松完成)。

标签: clojure


【解决方案1】:

您的 Clojure 源代码正在运行时加载和编译(请参阅 http://clojure.org/compilation),这就是为什么在程序执行之前您不会看到反射警告的原因。

很难确定您在哪里对静态方法进行反射调用,因此我推荐以下步骤:

  1. (:gen-class) 添加到您的(ns) 声明中
  2. 在您怀疑发生反射调用的位置添加 (set! *warn-on-reflection* true)(binding [*warn-on-reflection* true] body)

【讨论】:

  • 我使用 leiningen 项目设置进行编译:warn-on-reflection。我的所有模块都收到了反射警告,但在编译过程中没有一个会导致。
  • 在你运行lein compile 之后你在target/classes/ 下看到了什么?
  • opengltuts-> 一堆具有 ns$function.class 名称的类。还有core__init.classcore$loading__4784__auto__.class core$_main$fn__155.classcore$_main$fn__157.class
  • 好的,这就是我的全部。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多