Welcome! Please see the About page for a little more info on how this works.

+5 votes
in Compiler by
retagged by

When using gen-class, the generated .class doesn't have the default methods from java interfaces.

I created this repro, you can confirm a exception is throw when trying to call the method from the generated class from gen-class:

  • clj -T:build jar to generate the classes at target/classes
  • java -cp clj -Spath client/main/Main.java

A exception is throw:

Exception in thread "main" java.lang.UnsupportedOperationException: otherthing (clojure-sample.foo/-otherthing not defined?)
    at clojure_sample.Foo.otherthing(Unknown Source)
    at client.main.Main.main(Main.java:9)

The not ideal workaround is to add the default method in the namespace implementing what is done in the default method inside the java interface.

1 Answer

0 votes
selected by
Best answer

That repro doesn't run for me (from the linked branch), I get "Namespace could not be loaded: lint".

I think the actual problem is the reverse of the title - the whole point of default methods is that the implementing class doesn't have to implement the interface's default method. What's actually happening though is that the genclass is generating a method implementation of the default method otherthing that calls through to the Clojure var -otherthing (which is how genclass works but retains the dynamic nature of Clojure).

You can infer this from the error message: "UnsupportedOperationException: otherthing (clojure-sample.foo/-otherthing not defined?)". In "otherthing", it's trying to call "-otherthing".

Logged as https://clojure.atlassian.net/browse/CLJ-2794

Ah that makes sense, I thought in the end clojure compiler needed to implement the default method and do the same but that doesn't make sense indeed, it just need to not implement the method at all, right?

Thanks for the help!