Search code examples
clojure

Can not access to static methods in Clojure


I have a problem when trying to access a static method of some class. Here is the code and the error message:

(ns demo.app
  (:import 
     [java.nio.file Paths]
     [java.util List])

=> (Paths/get "a" "B" "c")
CompilerException java.lang.IllegalArgumentException: No matching method: get, compiling:(*cider-repl clj-demo*:68:16) 

=> (java.nio.file.Paths/get ".")
ClassCastException java.lang.String cannot be cast to java.net.URI  clj-demo.ch08/eval11327 (form-init3786136217280477578.clj:76)

=> (java.nio.file.Paths/get "." "finally.txt")
ClassCastException java.lang.String cannot be cast to [Ljava.lang.String;  clj-demo.ch08/eval11329 (form-init3786136217280477578.clj:78)

The java doc follows: https://docs.oracle.com/javase/10/docs/api/java/nio/file/Paths.html#get(java.lang.String,java.lang.String...)

I've found on https://clojure.org/reference/java_interop , it writes:

(Classname/staticMethod args*)

I also tried these:

=> (System/getProperty "java.vm.version")
"25.102-b14"

=> (clojure-version)
"1.8.0"

No problem. So:

Why does Paths/get not work in REPL?

Why does java.nio.file.Paths/get not work, either?

Why does Paths/get and java.nio.file.Paths/get get different error messages?

I've also tried

(List/of 0) ;; => [0]
(List/of 1 2 3) ;; => Method
   java.util.List.of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
   must be InterfaceMethodref constant
(List/of (Integer. 1)) ;; =>  Method java.util.List.of(Ljava/lang/Object;)Ljava/util/List; must
   be InterfaceMethodref constant
(List/of "s") ;; =>    Method java.util.List.of(Ljava/lang/Object;)Ljava/util/List; must
   be InterfaceMethodref constant

Solution

  • Paths.get(String, String...) takes two arguments - a string and an array of strings. Java creates the array automatically for you, but in clojure you need to construct the array yourself e.g.

    (Paths/get "a" (into-array String ["b" "c"]))
    

    Calling

    (java.nio.file.Paths/get ".")
    

    fails because the only overload of get which takes a single argument requires it to be a URI not a String.