1

I'm using maven with several modules, one in java, another in clojure. I'm calling a clojure function from java and want to pass in a HashMap as a parameter and return a 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 e.g. String, so the maven setup does work.)

I am getting the following error when I run some java unit tests calling the java code:

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? What about if the HashMap had a POJO object as a value rather than a String?

My java code:

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:

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

1 Answer 1

1

I guess that your error is caused by this definition in :gen-class:

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

From docs for :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. You should rewrite -non_empty_seats like this:

(defn -non_empty_seats
  [java-seats]
  (into {} (-filter-empty-seats java-seats)))
Sign up to request clarification or add additional context in comments.

2 Comments

You are perfectly right. And also I did not realize clojure maps are automatically converted to java Map. Thx!
@StephanKennedy They're not automatically converted. Instead, Clojure maps implement the java.util.Map interface.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.