Fork me on GitHub
#java
<
2018-05-04
>
dhruv100:05:49

i have a question regarding implementing java public interfaces in clojure here is an example of my interface `

dhruv100:05:01

public interface SomePublicInterface {
                                       void aMethod(Enum arg1, String... arg2),
                                       void aMethod (Enum arg1, AClass arg2, String... arg3)
                                       }

dhruv100:05:53

Here is how i’m implementing it:

(defrecord SomeRecord [field1 name]
  SomePublicInterface
  (aMethod [this enum msg] (str "ENUM is " enum)))

(defn some-record
  [name]
  (->SomeRecord (.getTheThing (TheThingFactory/getInstance) "NamedThing") name))

(def test (some-record "testing-some-record-method")) 

dhruv100:05:44

i am not able to understand why this isn’t working.

dhruv100:05:55

(aMethod test "ENUM" "MY TEST") ;;doesn't work
Unable to resolve symbol: aMethod in this context

(.aMethod test "ENUM" "MY TEST")
ClassCastException Cannot cast java.lang.String to java.lang.Enum  java.lang.Class.cast (Class.java:3369) 

dhruv100:05:26

it defaults to the types of the actual java Interace. it doesn’t call the aMethod i implemented.

dhruv100:05:54

I would like to call aMethod on my record (type) with strings and i want it to print “ENUM is: MY TEST”

hiredman00:05:54

how do you know it doesn't call the method you implemented?

hiredman00:05:03

if I had to guess, from the exception, the interface you implemented requires it to return an Enum and you are returning a string (which doesn't match the example interface, but given the exception that is my guess)

dhruv100:05:28

to be honest i don’t know much about java. i have to use a class that’s implementing the Interface SomePublicInterface I just thought it would return back a string because that’s what i’m asking for. the return type on aMethod in the interface is void

dhruv100:05:48

I’m importing the Interface like this: (import '[this.is.my.package SomePublicInterface])

seancorfield01:05:46

@dhruv1 aMethod is expecting an Enum and an array of String (the varargs part) or an Enum, an AClass (whatever that is), and an array of String. Your implementation must match the signatures -- otherwise it isn't implementing the interface.

seancorfield01:05:10

A string is not an Enum, but if you have a specific enumeration class, you can construct an Enum type from that class and the name used for one of the enumeration class members via (Enum/valueOf TheClass "name").

dhruv101:05:15

hey there. I am using a proxy to create an ENUM

(defn ->enum
  [^String enum]
  (proxy [Enum] [enum 1])) 

dhruv101:05:09

how do i match the signature in my implementation?

seancorfield01:05:22

In the code above you were trying to pass a string to the Enum argument and, quite correctly, got the exception "ClassCastException Cannot cast java.lang.String to java.lang.Enum"

dhruv101:05:18

right, so i was able to get past that by using a proxy and (into-array java.lang.String ["MY TEST"]

dhruv101:05:56

i am still at a loss here because of my lack of knowledge in Java and somewhat clojure

seancorfield01:05:18

Were you then able to call (.aMethod test (->enum "ENUM") (into-array String ["MY TEST"])) ?

dhruv101:05:41

actually no i wasn’t

seancorfield01:05:18

That Java interface looks like you made up the names rather than show us what the real code is -- are you working with a publicly available Java library? Or are you writing Java code yourself and compiling it and bringing it into your Clojure code?

dhruv101:05:47

at work we have a java library that i’m trying to use in clojure. it’s not public