2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以了解关于这的工作方式的一些更多信息。

-1
记录和类型

由DynamicClassLoader加载的类返回nil的.getPackage。像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 留言

更新后的补丁,适用于当前主分支,保留归属,无语义变更。标记为预筛选。

0
by

评论由:gshayban 提出

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

0
by

评论由: alexmiller 留言

凭我的记忆,我看不出这会有什么负面影响,特别是关于 JDK9 模块系统

0
by

评论由: alexmiller 留言

v4 补丁重新绑定到主分支并保留归属,无语义变更。

0
by

评论由: bozhidar 留言

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

0
by

评论由: alexmiller 留言

这是当前的路径...

0
by
_评论由: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)'
用户.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)'
用户.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)'
用户.T
#object[java.lang.Package 0x6f3c660a "package user"]
➜  clojure git:(f5cfd24d) ✗



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