3

Invoking a static Java method in Clojure is smooth; no problem. But when I invoke a non-static method, it throws an error, although I have tried several variations for dot (.) notation, as explained in Clojure Interop documentation.

The Java class:

public class CljHelper {

  public void test(String text) {
    System.out.println(text);
  }

}

The Clojure code:

(ns com.acme.clojure.Play
  (:import [com.acme.helpers CljHelper]))

(. CljHelper test "This is a test")  

The error:

java.lang.IllegalArgumentException: No matching method: test

This is another attempt, which makes the Java method to be executed but throws an error right after:

(defn add-Id
  [x]
  (let [c (CljHelper.)]
    ((.test c x))))        ;;; java.lang.NullPointerException: null in this line

(add-Id "id42")

The error:

java.lang.NullPointerException: null
2
  • Remove the outer parens ((.test c x)) - you are calling the result of test, which is nil - parens always have meaning and can not be added to make things more clear like in curly-brace-langs. Commented Jun 11, 2020 at 10:33
  • yes, you're right; there was an extra set of parens. Commented Jun 11, 2020 at 11:14

2 Answers 2

6

You have two different issues here. In the first example you're trying to invoke a method on the class CljHelper. You should be calling it on the instance, not the class.

(.test (CljHelper.) "This is a test")

For the second example, you have an extra set of parentheses. So, you're correctly calling the method test, but then you are taking the result, which is null, and attempting to call that as a function. So just remove the parentheses.

(defn add-id
  [x]
  (let [c (CljHelper.)]
    (.test c x)))
Sign up to request clarification or add additional context in comments.

1 Comment

Yep, suggested solutions for both issues work. Thanks
4

Here is the easiest way to do it. Make a java class Calc:

package demo;

public class Calc {
  public int answer() {
    return 42;
  } 
}

and call it from Clojure:

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:import [demo Calc]))

(let [c (Calc.)]                   ; construct an instance of Calc
  (println :answer (.answer c)))   ; call the instance method

with result:

:answer 42

You can clone a template Clojure project to get started.

3 Comments

Thanks Alan. I have implemented your solution. The Java method is executed but it immediately throws a java.lang.NullPointerException: null.
Add your current code to the question. You probably forgot to add the text after c
I have removed the extra set of parentheses, as commented in above answer, and it works now.

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.