具有需要枚举参数的注释的 clojure gen-class

Posted

技术标签:

【中文标题】具有需要枚举参数的注释的 clojure gen-class【英文标题】:clojure gen-class with annotation that require enum parameter 【发布时间】:2020-04-04 11:26:59 【问题描述】:

我想编写一个 clojure 库并公开生成的类,以便其他 java 项目可以使用它。 我阅读并遵循了 gen-class 文档,一切都按我的预期进行,除了带有枚举参数的类注释。

(ns common.exception.unauthorized
  (:gen-class :name
    ^org.springframework.web.bind.annotation.ResponseStatus
      org.springframework.http.HttpStatus/UNAUTHORIZED  ; <- here
              com.lalala.common.exception.Unauthorized
              :extends java.lang.RuntimeException
              :init init
              :constructors [String] [String]
              :main false
              :prefix "unauthorized-"))

(defn unauthorized-init [^String message]
  [[message] nil])

这个异常类的生成没有任何错误,它也可以用作Exception。但是,此异常旨在与 spring web 一起用作 http 响应。 spring框架读取注解,发现是HttpStatus/UNAUTHORIZED,然后响应401。但是spring框架抛出异常,抱怨java.lang.EnumConstantNotPresentException: org.springframework.http.HttpStatus

我查看了生成的类,它是这样的:

@ResponseStatus(HttpStatus.401)
public class Unauthorized extends RuntimeException 
    private static final Var init__var = Var.internPrivate("common.exception.unauthorized", "unauthorized-init");
    private static final Var getStackTrace__var = Var.internPrivate("common.exception.unauthorized", "unauthorized-getStackTrace");
    // ...... ellipsis

如图所示,HttpStatus/UNAUTHORIZED 编译为无效的HttpStatus.401

我也试过:code org.springframework.http.HttpStatus/UNAUTHORIZED:value org.springframework.http.HttpStatus/UNAUTHORIZED,可以编译成@ResponseStatus(code/value = HttpStatus.401),但是枚举值本身还是无效的形式HttpStatus.401

我是否以错误的方式对 gen-class 使用类注释?还是只是 Clojure 编译器有这个错误?

附:尝试使用 Clojure 1.9、1.10、1.10.1

【问题讨论】:

IMO gen-class 通常是一个杯子游戏。如果您需要为 Java 互操作生成 Java 类,javac 非常擅长制作它们,因此我为我在 Clojure 中实现的逻辑编写了一个小型 Java 包装器。该 Java 包装器可以具有 Java 库期望的任何注释和其他奇怪的东西,但它以一种直接的、数据驱动的方式与我的 Clojure 代码通信。 【参考方案1】:

最后,我改用本机 Java 代码。我意识到,在只有 ctor 转发到超级类的 clojure 中编写类给自己带来了麻烦。 我在项目中嵌入了java代码以及defproject中配置的:java-source-paths,解决了我的问题。

【讨论】:

以上是关于具有需要枚举参数的注释的 clojure gen-class的主要内容,如果未能解决你的问题,请参考以下文章

在绑定向量中注释 Clojure

Clojure 中的循环负载依赖关系

Clojure:gen-class并在java中导入它;包,路径,类路径

在 Clojure 中需要命名空间时出现 FileNotFoundException

注释掉导致 clojure 运行时错误的代码

将 Clojure 命名空间拆分为多个文件