
Clojure 内置的 clojure.core.server 启动的是纯文本 Socket REPL,不兼容 nREPL 协议;Leiningen 的 lein repl :connect 依赖 nREPL 协议,因此需改用 nrepl.server/start-server 启动兼容服务。
clojure 内置的 `clojure.core.server` 启动的是纯文本 socket repl,不兼容 nrepl 协议;leiningen 的 `lein repl :connect` 依赖 nrepl 协议,因此需改用 `nrepl.server/start-server` 启动兼容服务。
要使 Spring Boot 应用中的 Clojure REPL 支持 lein repl :connect,必须替换原生 Socket REPL 为 nREPL 服务器——因为 Leiningen 客户端(包括 lein repl :connect)严格遵循 nREPL 协议,而 clojure.core.server/repl 仅提供裸 TCP 文本交互(如 nc 或 telnet 可用),二者协议层完全不互通。
✅ 正确做法:集成 nREPL 服务器
首先,在 pom.xml(Maven)或 build.gradle 中添加 nREPL 依赖(以 Maven 为例):
<dependency><groupid>nrepl</groupid><artifactid>nrepl</artifactid><version>1.0.0</version><!-- 推荐使用最新稳定版,如 1.2.0 --></dependency>
然后修改你的 ClojureRepl 服务类,使用 nrepl.server/start-server 替代原生 clojure.core.server/start-server:
@Service
public class ClojureRepl {
private final Logger logger = LoggerFactory.getLogger("CLOJURE");
private volatile Object server; // 保存 nREPL server 实例,用于优雅关闭
@PostConstruct
public void init() {
try {
// 加载 nREPL 命名空间
Clojure.var("clojure.core", "require").invoke(Clojure.read("nrepl.server"));
// 启动 nREPL 服务器(端口 5555,无认证,支持标准中间件)
IFn startServer = Clojure.var("nrepl.server", "start-server");
server = startServer.invoke(
Clojure.read("{:port 5555 :bind \"127.0.0.1\" :handler nrepl.server/default-handler}")
);
logger.info("nREPL server started on 127.0.0.1:5555");
} catch (Exception e) {
logger.error("Failed to start nREPL server", e);
throw new RuntimeException(e);
}
}
@PreDestroy
public void destroy() {
if (server != null) {
try {
Clojure.var("nrepl.server", "stop-server").invoke(server);
logger.info("nREPL server stopped");
} catch (Exception e) {
logger.warn("Error stopping nREPL server", e);
}
}
}
}
? 关键说明:
- :handler nrepl.server/default-handler 是必需参数,它组合了 eval、interruptible-eval、complete 等核心中间件,确保 Leiningen 客户端能执行表达式、获取结果、补全等完整功能;
- :bind "127.0.0.1" 显式限制监听地址,增强安全性(避免暴露到公网);
- 返回的 server 对象必须保存,供 stop-server 正确关闭(原生 core.server/stop-server 不接受该对象,不可混用)。
✅ 验证连接
启动 Spring Boot 应用后,执行:
lein repl :connect 127.0.0.1:5555
你将看到类似输出:
Connecting to nREPL at 127.0.0.1:5555 nREPL server started on port 5555 on host 127.0.0.1 - nrepl://127.0.0.1:5555 user=>
此时即可正常使用 (println "Hello from nREPL!")、C-c C-r(在 Emacs + CIDER 中)、或 VS Code + Calva 等 IDE 工具进行交互开发。
⚠️ 注意事项
- ❌ 不要尝试用 lein repl :connect 连接 clojure.core.server/start-server 启动的端口——协议不匹配,连接会挂起(如问题中“只输出 Connecting… 然后无响应”);
- ✅ 若需同时支持 nc 和 lein repl,可并行启动两个服务器(不同端口),但通常推荐统一使用 nREPL;
- ?️ 生产环境请务必禁用 nREPL 或启用认证(如 :authenticators),避免未授权代码执行风险;
- ? Leiningen 2.10+ 默认内置 nREPL 1.0+,无需额外插件;若使用旧版 Lein,请升级或显式声明 :nrepl-port。
通过以上配置,你的 Spring Boot 应用便具备了与现代 Clojure 开发工具链(Leiningen、CIDER、Calva、Portkey)无缝协作的 nREPL 能力。










