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 提出

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

0

评论者:alexmiller

是的,我相信这是正确的。

0

评论由:stu 提出

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

0

评论者:bozhidar

我已经在上面的问题中链接了该问题。基本上,像 CIDER 和 vim-fireplace 这样的工具是依赖这个信息来实现代码补全等功能。
当运行你的应用程序时可能没问题,但当检查它们的运行状态时绝对是个问题...

0

评论由:michaelblume 提出

将“Packate”改为“Package”

0

评论者:alexmiller

已更新补丁以应用于当前 master,保留归属,没有语义变化。已标记预审。

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



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