views:

68

answers:

3

I am getting into Clojure and Grammatical Evolution at the same time and discovered GEVA, which is a GE tool written in Java. I have no background in Java. So I don't have to re-invent the wheel, how can I integrate GEVA into Clojure?

I can execute the default script from the CLI with: java -jar GEVA.jar -main_class Main.Run

The GEVA source directory has the following subdirectories with packages named after the directory: Algorithm com Exceptions FitnessEvaluation Fractal Individuals Main Mapper Operator Parameter UI Util

The Main subdirectory has the following files and tutorial subdir: AbstractRun.java Experiment.java Run.java State.java Tutorials

The following classes are in the Run.java file: public class Run extends AbstractRun public Run() public void experiment(String[] args) public void setup(String[] args) private void setSeed() public static void main(String[] args)

From what I can tell, the static method 'main' in class Main.Run is what I want to execute. However when I try to follow the Java interop instructions, I am getting errors.

clgeva.test=> (.Main.Run/main)
java.lang.Exception: No such namespace: .Main.Run (NO_SOURCE_FILE:5)
clgeva.test=> (.Main.Run/main "")
java.lang.Exception: No such namespace: .Main.Run (NO_SOURCE_FILE:6)

I'm obviously not importing the namespace correctly to run the main function.

user=> (import Main)
java.lang.ClassNotFoundException: Main (NO_SOURCE_FILE:1)
user=> (import Main.Run)
Main.Run
user=> (main)
java.lang.Exception: Unable to resolve symbol: main in this context (NO_SOURCE_FILE:3)
user=> (.Main.Run/main)
java.lang.Exception: No such namespace: .Main.Run (NO_SOURCE_FILE:4)

What the heck am I doing wrong? I am sure I'm just missing something obvious, but I've been banging my head on it for a little while and need some direction. Thanks.

+1  A: 

First, make sure you are loading the GEVA lib correctly - see http://clojure.org/libs I'm guessing, from the java.lang.ClassNotFoundException error, that GEVA is not on your classpath.

Then you want to look at the Clojure documentation for Java interop: http://clojure.org/java_interop

Joubert Nel
I've tried loading the classpath a couple of ways. The first way I ran was by copying the GEVA.jar file into the leiningen lib folder, then executing 'lein repl'. The other way was to manually execute 'java -cp clojure.jar:clojure-contrib.jar:GEVA.jar -jar clojure.main'.
Nick
Actually...I'm not in front of my machine...I don't think I had that -jar in the manual execution of the previous comment.
Nick
For leiningen, you want to specify GEVA as a dependency in your DEFPROJECT form in project.clj (see http://github.com/technomancy/leiningen/blob/master/project.clj for an example).
Joubert Nel
A: 

You have the right idea, but you do have some syntax errors.

clgeva.test=> (.Main.Run/main)

Should have a space between the dot operator and the Main.Run/main reference. As it is, it's trying to find something called ".Main.Run" which obviously doesn't exist. Do it like so:

clgeva.test=> (. Main.Run/main)

Assuming you have your classpath set up correctly, it should work.

Importing the class using (import ...) and calling (main) won't work because main is a static method.

levand
A: 

The syntax for calling a static method with no arguments (I'll use an example that everyone has access to) is:

=> (java.lang.System/currentTimeMillis)
1284574337322

The above form is preferred, but the following is also possible, and can be useful in macros:

=> (. java.lang.System currentTimeMillis)
1284574477369

In this case, "java.lang." may be omitted, but I'm including it to match your case more closely.

=> (System/currentTimeMillis)
1284574617771

Adding a dot to the first form will not work, whether with or without a space:

user=> (.System/currentTimeMillis) 
java.lang.Exception: No such namespace: .System (NO_SOURCE_FILE:44)
user=> (. System/currentTimeMillis)
java.lang.IllegalArgumentException: Malformed member expression, expecting (. target member ...) (NO_SOURCE_FILE:45)
dreish
This answer provided the closest hint to what I was doing wrong. I was correctly setting the class with the following:
Nick
This answer provided the closest hint to what I was doing wrong. I was correctly setting the class with the following from the lein repl when the jar was in the lib folder: (ns clgeva.test (:import Main.Run))When I searched through the results of (ns-imports *ns*), I found 'Run Main.Run' which indicated that the class was imported as Run.So when I ran (Run/main ""), I got a classCastException error which indicated that I was on the right path. Fixing that with the following (Run/main (into-array [""])) got the code to execute as expected.Thanks everyone for the help!
Nick