请在2024 年 Clojure 状态调查!中分享您的看法。

欢迎!请参阅关于页面以了解更多有关此网站的工作方式的信息。

–1
记录与类型

通过 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

关于这个问题的背景信息(链接:https://github.com/clojure-emacs/cider-nrepl/pull/127 文本:背景)。我并不是这个领域的专家,但是除了它的包名之外的类信息都完整对我来说显得有些奇怪。

0
通过

评论者:hiredman

如果你进行AOT编译(在磁盘上为deftype生成一个类文件),getPackage工作正常,这让我觉得可能是一个JVM问题。

0
通过

评论者:hiredman

实际上,可能是因为动态类加载器没有为加载的类定义包名。

0
通过

评论者:alexmiller

是的,我认为这是正确的。

0
通过

评论者:stu

这里没有问题声明。需要包信息是用来做什么的?

0
通过

评论者:bozhidar

我已在上文链接了问题。基本来说,像CIDER和vim-fireplace这样的工具依赖于这个信息来实现如自动完成提示等功能。
这可能在你运行应用程序时不是问题,但当检查它们的状态时会成为问题...

0
通过

评论者:michaelblume

将“Packate”更正为“Package”。

0
by

评论者:alexmiller

刷新补丁以便应用于当前主分支,保留版权信息,无语义变更。已标记为预筛选。

0
by

由 gshayban 发布的评论:

我们应该考虑与此 JDK9 模块系统的交互

0
by

评论者:alexmiller

据我所知,这似乎对 JDK9 模块系统没有任何负面影响

0
by

评论者:alexmiller

v4 补丁变基至 master 并保留版权信息,无语义变更。

0
by

评论者:bozhidar

Alex,这将包含在 Clojure 1.10 中吗?

0
by

评论者:alexmiller

这是目前的路径...

0
by
_由 gshayban 发布的评论_

这是一个坏补丁,它通过了审查。上面的动机链接显示了一个尝试将包符号化的 nREPL 摘要,基本上

((.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) ✗



我认为这应该被回滚,并让用户空间根据二进制名称计算包。
...