1

This is my code. I would like to make an array of Fruit (an custom java object class).

(defn build-fruit
  [part]
  (let [name (:name part)
        color (:color part)
        price (:price part)
        is_available (:is_available part)]
  (-> (Fruit/newBuilder)
      (.setName name)
      (.setColor color)
      (.setPrice price)
      (.setIsAvailable is_available)
      (.build))))

(defn build-fruits
  [result length]
  (loop [remaining-fruits result
         final-fruits (make-array Fruit length)]
    (if (empty? remaining-fruits)
      final-fruits
      (let [[part & remaining] remaining-fruits]
        (recur remaining
               (into-array final-fruits (build-fruit part)))))) ;got an error here
  )

(defn -getAllFruits [this ^Empty req ^StreamObserver res]
  (let [result (clj-grpc.database/findAllFruit)
        length (count result)
        fruits (build-fruits result length)]
    (doto res
      (.onNext (-> (ListOfFruits/newBuilder)
                   (.addAllFruit fruits)
                   (.build)))
      (.onCompleted))))

But got an error

java.lang.ClassCastException: [Lorg.example.fruitproto.Fruit; cannot be cast to java.lang.Class
    at clojure.core$into_array.invokeStatic(core.clj:3431)
    at clojure.core$into_array.invoke(core.clj:3431)
    at clj_grpc.fruitservice$build_fruits.invokeStatic(fruitservice.clj:118)
    at clj_grpc.fruitservice$build_fruits.invoke(fruitservice.clj:110)

My guess is I cann't use make-array. I also can't use simple array like this [] because it also got another error. What is the proper way to achieve this?

5
  • It is often more helpful to provide a repro that is not dependent on any Java libraries, so people can more easily help you. Commented Mar 2, 2022 at 10:54
  • into-array has a 2-arity version, where the first argument is a component type. Note the second argument is a sequence, so there's no need for using a loop in build-fruits. I would provide a code sample, but as Michiel points out, the repro code in the question is not standalone, so it's hard to provide an example. Commented Mar 2, 2022 at 11:21
  • See clojuredocs.org/clojure.core/into-array Commented Mar 2, 2022 at 11:24
  • @SteffanWestcott without loop? How do i build Fruit object for every item in result variable? Commented Mar 2, 2022 at 12:09
  • See my answer below, building an array of LocalDate, where map is used to transform the input maps to LocalDate instances. Commented Mar 2, 2022 at 12:44

1 Answer 1

2

Here is a standalone example of using into-array, building an array of LocalDate rather than Fruit:

(ns overflow.example
  (:import (java.time LocalDate)))

(defn build-local-date [{:keys [year month day]}]
  (LocalDate/of year month day))

(defn build-local-dates [xs]
  (into-array LocalDate (map build-local-date xs)))
Sign up to request clarification or add additional context in comments.

Comments

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.