rzv
rzv

Reputation: 2022

Clojure Java Interop Error: Illegal Argument Exception: NO MATCHING CONSTRUCTOR FOUND

I found this related question on Stack Overflow, but it didn't really answer my question.

I have a Java application that I've packaged as a JAR file. I also have a Clojure application that I've packaged as a JAR file. I'm now writing another Clojure application that uses the first two as libraries.

Here's the Java code that seems to be the source of my error:

public class ServerBuilder {
  private HashMap<String, ResponseObject> routes = new HashMap<String, ResponseObject>();
  public int limit;
  public ServerSocket serverSocket;
  private ThreadBuilder threadBuilder;
  public int count;

  public ServerBuilder(int limit) {
    this.limit = limit;
  }

  public void begin() throws IOException {
    if(getServerSocket() == null) {
      this.serverSocket = new ServerSocket(4444);
    }
    int count = 0;
    while(count < limit) {
        createThreadBuilder(serverSocket);
        new Thread(threadBuilder).start();
        count = count + 1;
        this.count = count;
    }
  }

Then in my Clojure code, I'm accessing my Java code like this:

(ns browser_tic_tac_toe.core
  (:import (server ServerBuilder)))

(defn -main []
  (let [server-builder (ServerBuilder. 100)]   ; the error points me to this line
    (doto
      server-builder (.begin))))

The error I get is:

Exception in thread "main" java.lang.IllegalArgumentException: No matching ctor found for class server.ServerBuilder

I've Googled this and haven't found much. The error apparently means "no matching constructor found for this class", but it appears to me that the constructor does match. That's why I'm confused.

EDIT

I tried changing the type I'm passing (from long to int):

(defn -main []
  (let [limit (int 100)
        server-builder (ServerBuilder. limit)]
    (doto
      server-builder (.begin))))

Upvotes: 2

Views: 2560

Answers (3)

Tom Carchrae
Tom Carchrae

Reputation: 6486

Have you tried the other constructor syntax: (new ServerBuilder 100)

Otherwise, perhaps the java code is not in the build path - or perhaps the java class package name is not server as indicated by your compiler error: server.ServerBuilder

Upvotes: 0

Tom Carchrae
Tom Carchrae

Reputation: 6486

Not sure about how you invoke a Java constructor in Clojure, but try making a default constructor in Java:

public ServerBuilder()  {
    this.limit = 100;  //some default
}

And yes, this clearly won't work if you want to pass an argument to the constructor.

Based on the other answer by @jtahlborn you can cast the long to an int using

(ServerBuilder. (int 100))

from http://clojure.org/java_interop#Java Interop-Some optimization tips

Upvotes: -1

jtahlborn
jtahlborn

Reputation: 53694

Contrary to Java, i believe that primitive literals in clojure are longs, not ints, and clojure cannot find the constructor ServerBuilder(long).

Upvotes: 4

Related Questions