B4J Question Creating an instance of a Clojure class

B4JExplorer

Active Member
Licensed User
Been trying to get through this, for about 3 1/2 hours, and can't seem to get a handle on it.

I've included the Clojure jar

#AdditionalJar: clojure-1.6.0


, and am trying to reproduce the code at the bottom, but can't even get past the first InitializeNewInstance.


Some of my code is as follows.

B4X:
'...
'...
	Dim oClojure As JavaObject
'...
'...

' This keeps generating a classnotfound exception.  Since the jar is in the classpath and compiles ok, 
'  I don't know why it's not finding it.
oClojure.InitializeNewInstance( "clojure.java.api.Clojure",	Null )

Naturally, I can't get to the point of getting to the next assignment, which I think would be

B4X:
oIFn = oClojure.RunMethodJO( "clojure.core", Array As Object( "var" ) )
, or any further.



Here's the Java code I'm trying to reproduce, in B4J, from the bottom of http://clojure.org/java_interop:



The public Java API for Clojure consists of the following classes and interfaces:
clojure.java.api.Clojure
clojure.lang.IFn

All other Java classes should be treated as implementation details, and applications should avoid relying on them.

To lookup and call a Clojure function:
IFn plus = Clojure.var("clojure.core", "+");
plus.invoke(1, 2);



Can anyone offer some tips?
 

B4JExplorer

Active Member
Licensed User
That's actually where I started,

B4X:
oClojure.InitializeStatic( "clojure.java.api.Clojure" )
, and that line ran without an error. But everything else bombed out. Been at this for a while, tried lots of permutations.

B4X:
	oIFn = oClojure.RunMethodJO( "clojure.core", Array As Object( "var" ) )

The second line is wrong, because clojure.core is not a method. But I've been trying random assignments, after all of the attempts that made logical sense, didn't work.

If possible, I'd like to avoid doing any kind of nested calls, in order to trace through each assignment.
 

B4JExplorer

Active Member
Licensed User
Got it.


B4X:
	Dim oClojure As JavaObject
	Dim oIFn As JavaObject

	oClojure.InitializeStatic( "clojure.java.api.Clojure" )
	
	oIFn =  oClojure.RunMethodJO( "var", Array As Object( "clojure.core", "+" ) )

	sResult =  oIFn.RunMethodJO( "invoke", Array As Object( 1, 2 ) )			'// Returns 3
Problem solved, thanks.
 

rwblinn

Well-Known Member
Licensed User
Or use:
'From http://clojure.org/java_interop
'To lookup AND call a Clojure function:
'IFn plus = Clojure.var("clojure.core", "+");
'plus.invoke(1, 2);
'Result is 3 in the log
B4X:
Sub TestPlusInvoke
   Dim joIFn As JavaObject
   joIFn.InitializeNewInstance("clojure.core$_PLUS_", Null)
   Log(joIFn.RunMethod("invoke", Array(1,2)))
End Sub
 

B4JExplorer

Active Member
Licensed User
Or use:
'From http://clojure.org/java_interop
'To lookup AND call a Clojure function:
'IFn plus = Clojure.var("clojure.core", "+");
'plus.invoke(1, 2);
'Result is 3 in the log
B4X:
Sub TestPlusInvoke
   Dim joIFn As JavaObject
   joIFn.InitializeNewInstance("clojure.core$_PLUS_", Null)
   Log(joIFn.RunMethod("invoke", Array(1,2)))
End Sub
Interesting, I had looked at some of your JavaObjects tips, and couldn't figure this out.

Where does the $_PLUS_ come from?
 

rwblinn

Well-Known Member
Licensed User
Welcome. There is a good class reference - your way has been the offcial way - I looked up at the jar file.

Additional hint = replace RunMethodJO by RunMethod:
B4X:
Dim oClojure As JavaObject
Dim oIFn As JavaObject
oClojure.InitializeStatic( "clojure.java.api.Clojure" )
oIFn =  oClojure.RunMethod( "var", Array As Object( "clojure.core", "+" ) )
Dim x As Long = oIFn.RunMethod( "invoke", Array As Object( 1, 2 ) )
Log(x)
 
Top