2

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

3 Answers 3

4

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

Sign up to request clarification or add additional context in comments.

2 Comments

Clojure automatically downgrades longs to ints if necessary when using reflection to look for a match, so that's not going to make a difference. He's probably pointing at some different version of the class, which has no integral-argument constructor.
@amalloy - yeah, that would be my only other guess.
0

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

Comments

-1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.