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

欢迎!请参阅 关于 页面以获取更多关于本网站如何运作的信息。

–1
Records and Types

由 DynamicClassLoader 加载的类对 .getPackage 返回 nil。像 CIDER 和 vim-fireplace 这样的工具正在依靠这个信息来实现代码补全等功能。

(.getPackage String) ;; => #<Package package java.lang, Java 平台 API 规范,版本 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
by

由:hiredman发表的评论

如果在盘上手动编译(为deftype生成类文件),getPackage将正常工作,这让我怀疑这是一个JVM问题

0
by

由:hiredman发表的评论

实际上,可能只是动态classloader没有为其加载的类定义一个包

0
by

评论者:alexmiller

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

0
by

由:stu发表的评论

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

0
by

评论者:bozhidar

我已经链接了上面的问题。基本上,像CIDER和vim-fireplace这样的工具依赖于这些信息来实现诸如自动完成等操作。
当运行您的应用时,这可能不是问题,但检查它们的状态时,这绝对是个问题...

0
by

由:michaelblume发表的评论

将Packate更改为Package

0
by

评论者:alexmiller

更新补丁,可供当前主分支应用,保留归属,无语义变更。已标记为预审通过。

0

评论者:gshayban

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

0

评论者:alexmiller

坦白说,我觉得这不会对 JDK9 模块系统造成任何负面影响

0

评论者:alexmiller

第 4 版补丁回滚至上一次提交,保留归属,无语义变更。

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



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