java

2018-05-04T00:15:49.000267Z

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

2018-05-04T00:16:01.000045Z

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

2018-05-04T00:16:53.000074Z

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

2018-05-04T00:17:44.000107Z

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

2018-05-04T00:17:55.000050Z

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

2018-05-04T00:19:26.000045Z

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

2018-05-04T00:20:54.000235Z

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

2018-05-04T00:32:54.000007Z

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

2018-05-04T00:34:03.000294Z

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)

2018-05-04T00:37:28.000216Z

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

2018-05-04T00:41:48.000196Z

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

seancorfield 2018-05-04T01:33:46.000074Z

@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.

seancorfield 2018-05-04T01:37:10.000185Z

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").

2018-05-04T01:38:15.000060Z

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

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

2018-05-04T01:39:09.000086Z

how do i match the signature in my implementation?

seancorfield 2018-05-04T01:39:22.000159Z

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"

2018-05-04T01:40:18.000068Z

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

2018-05-04T01:40:56.000168Z

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

seancorfield 2018-05-04T01:41:18.000186Z

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

2018-05-04T01:43:41.000155Z

actually no i wasn’t

seancorfield 2018-05-04T01:44:18.000225Z

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?

2018-05-04T01:45:47.000114Z

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