简体   繁体   English

调用将映射作为 java 参数的 clojure 函数时出现问题

[英]Problems calling a clojure function that takes a map as parameter from java

I'm using maven with several modules, one in java, another in clojure.我正在使用带有几个模块的 maven,一个在 java 中,另一个在 clojure 中。 I'm calling a clojure function from java and want to pass in a HashMap as a parameter and return a HashMap.我正在从 java 调用一个 clojure 函数,并希望传入一个 HashMap 作为参数并返回一个 HashMap。 (I ran lein uberjar and lein pom on the clojure project to make it work with maven. I can get things to work for clojure function with simple types eg String, so the maven setup does work.) (我在 clojure 项目上运行了 lein uberjar 和 lein pom 以使其与 maven 一起工作。我可以使用简单类型(例如 String)为 clojure 函数工作,因此 maven 设置确实有效。)

I am getting the following error when I run some java unit tests calling the java code:当我运行一些调用 java 代码的 java 单元测试时出现以下错误:

java.lang.ClassCastException: class clojure.lang.LazySeq cannot be cast to class java.util.Map (clojure.lang.LazySeq is in unnamed module o
f loader 'app'; java.util.Map is in module java.base of loader 'bootstrap')

How can I get this to work?我怎样才能让它工作? Is this the proper way to call clojure methods from java?这是从java调用clojure方法的正确方法吗? What about if the HashMap had a POJO object as a value rather than a String?如果 HashMap 将 POJO 对象作为值而不是字符串呢?

My java code:我的java代码:

import interop.Core;

public class BillingCalc {
       static Map<String, String> nonEmptyItems(Map<String, String> items) {
           return Core.non_empty_seats(new HashMap<String, String>());
       }
}

My clojure code:我的clojure代码:

(ns interop.core
     (:gen-class
      :name interop.Core
      :methods [^{:static true} [apply_vat_to_netto [java.math.BigDecimal java.math.BigDecimal] java.math.BigDecimal]
                ^{:static true} [non_empty_seats [java.util.Map] java.util.Map]]) )


(defn -filter-empty-seats
  "filter out those with empty seats"
  [seats]
  (filter (fn [[_ v]] (pos? (:booked-items v))) seats))

(defn -non_empty_seats
  [java-seats]
  (-filter-empty-seats (into {} java-seats)))

I guess that your error is caused by this definition in :gen-class :我猜你的错误是由:gen-class中的这个定义引起的:

[non_empty_seats [java.util.Map] java.util.Map]]

From docs for :gen-class :来自:gen-class 的文档:

:methods [ [name [param-types] return-type], ...]

The expected type of returned value is java.util.Map , but filter in -filter-empty-seats returns instance of clojure.lang.LazySeq .返回值的预期类型是java.util.Map ,但-filter-empty-seats中的filter返回clojure.lang.LazySeq的实例。 You should rewrite -non_empty_seats like this:您应该像这样重写-non_empty_seats

(defn -non_empty_seats
  [java-seats]
  (into {} (-filter-empty-seats java-seats)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM