Anton Harald
Anton Harald

Reputation: 5924

clojure - java interop (No matching ctor found)

Consider the following lines of Java code:

final WebClient webClient = new WebClient()
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");

(taken from the 'Getting Started' Example of the the HTML Unit Project)

How would that be adopted to Clojure?

After adding the needed dependencies, I tried the following:

(import '[com.gargoylesoftware.htmlunit.html HtmlPage])
(import '[com.gargoylesoftware.htmlunit WebClient])

(let [wc (WebClient.)
      hp (HtmlPage. (.getPage wc "http://www.something.."))]
   ;;...)

but I get this error:

CompilerException java.lang.IllegalArgumentException: No matching ctor found f\
or class com.gargoylesoftware.htmlunit.html.HtmlPage, compiling:(*cider-repl l\
ocalhost*:30:16) 

Anybody knows why?


EDIT:

As noted in a comment, calling the constructor of HtmlPage might not be necessary. However the following code yields an error as well, though another one:

    (.getPage (WebClient.) "http://htmlunit.sourceforge.net")

IllegalArgumentException Cannot locate declared field class org.apache.http.im\
pl.client.HttpClientBuilder.dnsResolver  org.apache.commons.lang3.Validate.isT\
rue (Validate.java:155) 

Upvotes: 3

Views: 5437

Answers (2)

Christopher Pagan
Christopher Pagan

Reputation: 53

I want to add to Sam's answer that the real issue is that the way your Clojure code is written doesn't define your constructors in a way that would match your Java code.

(ClassA.)

is equivalent to

new ClassA();

Any parameters are in the same order

(ClassA. param1 param2)

is equivalent to

new ClassA(param1, param2);

The dot (.) after the class name creates a new object and a dot before a name calls a method. You need the object calling the method too. Say for example that classA is an object of ClassA and has methods callMethodNoParams() and callMethod(ClassB param1, ClassC param2).

(.callMethodNoParams classA)

is equivalent in Java to

classA.callMethodNoParams();

Another example:

(.callMethod classA param1 param2)

is equivalent in Java to

 classA.callMethod(param1, param2);

Another example that creates an object while calling a method:

classA.callMethod(param1, new ClassC(someParam));

is equivalent in Java to

(.callMethod classA param1 (ClassC. someParam))

Upvotes: 2

Sam Estep
Sam Estep

Reputation: 13294

This:

(HtmlPage. (.getPage wc "http://www.something.."))

is equivalent to this:

(new HtmlPage (. wc getPage "http://www.something.."))

which is equivalent to this Java code:

new HtmlPage(wc.getPage("http://www.something.."))

Just leave out the extra constructor call:

(.getPage wc "http://www.something..")

Upvotes: 6

Related Questions