Clojure 2024 年度调查 中分享您的想法!

欢迎!请参阅关于页面了解有关如何使用本站的一些更多信息。

–1 投票
Records and Types

通过 DynamicClassLoader 加载的类的 .getPackage 返回 nil。CIDER 和 vim-fireplace 等工具依靠这些信息来实现诸如自动完成提示等功能。

(.getPackage String) ;; => #<Package package java.lang, Java Platform API Specification, version 1.7> (deftype T []) (.getPackage T) ;; => nil

建议:在 DynamicClassLoader.defineClass() 中,对正在定义的类调用 definePackage()(与 URLClassLoader 的做法类似)。

补丁:clj-1550-v4.patch

审核:Alex Miller

19 答案

0 投票

评论者:alexmiller

根据http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getPackage(),此方法返回由类加载器找到的包信息;如果没有找到,返回 null。在我看来,当前行为并没有违反规范。我需要进一步实验以确定这是否不同寻常。

0 投票

评论者:bozhidar

关于此问题的背景信息。我对这个话题不是专家,但能够获取所有类信息除了它的包确实在我看来看起来很奇怪。

0 投票

由 hiredman 发表的评论:

如果你进行预编译(在磁盘上为 deftype 生成类文件),getPackage 运作正常,这使我怀疑这是一个 JVM 问题。

0 投票

由 hiredman 发表的评论:

实际上,可能是 dynamicclassloader 没有为它加载的类定义包。

0 投票

评论者:alexmiller

我相信这是正确的。

0 投票

由 stu 发表的评论:

这里没有问题陈述。需要包信息做什么?”

0 投票

评论者:bozhidar

我已经在上面的链接中提到了问题。基本上,像 CIDER 和 vim-fireplace 这样的工具依赖于这些信息来实现诸如自动完成提示等功能。
这在使用您的应用程序时可能不会有问题,但检查它们的��态时肯定是个问题...

0 投票

由 michaelblume 发表的评论:

将“Packate”更正为“Package”。

0 投票

评论者:alexmiller

更新补丁以应用到当前主分支,保留归属,没有语义更改。已标记审查通过。

0 投票

评论:gshayban

在此处应考虑与JDK9模块系统的交互

0 投票

评论者:alexmiller

据我所知,这并不会对JDK9模块系统产生任何负面影响

0 投票

评论者:alexmiller

v4补丁重新基于master版,并保留了归属,没有语义更改。

0 投票

评论者:bozhidar

Alex,这会被包含在Clojure 1.10中吗?

0 投票

评论者:alexmiller

这是目前的路径...

0 投票
_评论:gshayban_

这是一个不良的补丁,已经误入其中。上面链接的解释展示了nREPL摘录,试图符号化包,基本上

(symbol (.getName (.getPackage TheClass))). 原始代码可以通过这种方式从二进制名称中导出包名,就像JVM抓取它一样。(取最后一个句点之前的前缀。)

修复还引入了一个过时的调用,并且在类加载过程中需要更多的工作(这是关键路径)。

顺便说一句,JDK9+在类定义后会自动根据二进制名称定义一个包


## JDK 8
➜  clojure git:(f5cfd24d) ✗ docker run --rm -v $HOME/.m2:/m2 openjdk:8-slim java -jar /m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar -e '(:deftype T [])' -e '(:or (.getPackage T) :nada)'
user.T
:nada

## JDK 9
➜  clojure git:(f5cfd24d) ✗ docker run --rm -v $HOME/.m2:/m2 openjdk:9-slim java -jar /m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar -e '(:deftype T [])' -e '(:or (.getPackage T) :nada)'
user.T
#object[java.lang.Package 0x10993713 "package user"]

## JDK 11
➜  clojure git:(f5cfd24d) ✗ docker run --rm -v $HOME/.m2:/m2 openjdk:11-slim java -jar /m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar -e '(deftype T [])' -e '(or (.getPackage T) :nada)'
user.T
#object[java.lang.Package 0x6f3c660a "package user"]
➜  clojure git:(f5cfd24d) ✗



我认为这应该撤销,并让用户空间从二进制名中计算包。
...