See also:
NEURON + Java Interface programmer reference
which is the javadoc generated information from the neuron.* classes
that implement the java to neuron interface.
Early development notes are
now mostly obsolete except for the important acknowlegement of
Fred Howell's original work on the interface.
load_java("java.lang.String") load_java("java.lang.String", "JString")This function registers a Java class with the Hoc interpreter. In hoc the class is called java_lang_String or JString respectively. The load_java function returns 1 if the class can be found and registered, 2 if the name is already in use (hopefully because the same class was previously loaded with that name), and 0 (along with an error message, probably ClassNotFoundException).
The same java classes may be loaded more than once with different hoc names.
Java classes are looked for first in the current working directory, then the list of directories or jar files specified in the ${CLASSPATH} environment variable, then the jar files in the ${NEURONHOME}/classes directory, and finally in the directories (or jar files) dynamically added to the neuron/NrnClassLoader.
It should be noted that the java virtual machine's system class loader starts with a java.class.path variable which contains only the ${NEURONHOME}/classes/nrnclsld.jar so that only the basic java classes and the neuron.NrnClassLoader are loaded with the system loader. All other classes are loaded with the neuron.NrnClassLoader which has a dynamically configurable list of directories and jar files which are looked in for classes. This means that if a class is loaded which fails due because it needs a package not in the current classpath, that one can load that prerequisite package and then attempt to reload the dependent class.
For example
load_java("Notepad", "Notepad")returns 0 and prints the "java.lang.ClassNotFoundException: Notepad" message. Re-executing with a third argument that specifies the path to the class gives
load_java("Notepad", "Notepad", "file:/usr/j2sdk1_3_1/demo/jfc/Notepad/Notepad.jar")succeeds.
load_java("java.util.Vector", "JVector") objref jv jv = new JVector() print jv // prints JVector[0]If there is more than one class constructor with args, better performance is obtained using the no arg constructor (if it exists) since that avoids a dynamic lookup of the proper constructor on the basis of the specific hoc argument list used. Also, with overloaded constructors, argument types double, int, and boolean cannot be distinguished and all objects are of type object at the time the constructor selection is made. In practice this is only rarely a problem. e.g.
load_java("java.lang.String", "JString") objref s s = new String() // no problem s = new String("Hello") // no problem s = new String(s) // have to use s = new String(s.toCharArray) /home/hines/nrn5/sparc/bin/nrniv: Expecting string argument near line 19 s = new String(s) ^ String[2].init(String[1])
load_java("java.lang.Math", "JMath") objref jm jm = new JMath() jm.ceil(4.3) // prints 5If such methods are overloaded at the hoc level then the correct method name in hoc is the method name followed by the number of arguments followed by a signature string consisting of the letters 'd', 'i', 'b', 's', or 'o' in the order of the arguments.
load_java("java.lang.Math", "JMath") objref jm jm = new JMath() jm.min2ii(4.1, 3.1) // prints 3 jm.min2dd(4.1, 3.1) // prints 3.1Attempting to use the overloaded name will print a list of possible disambiguated method names as in:
oc>jm.min(4.1, 3.1) JMath[0].min Overloaded. Use one of: min2ii min2dd /home/hines/nrn5/sparc/bin/nrniv: min Overloaded. Disambiguate using a more specific method. near line 10 jm.min(4.1, 3.1) ^ JMath[0].min(4.1, 3.1) oc>Notice that even pure static classes need an object instance in hoc before one can call the static method.
load_java("java.util.Vector", "JVector") objref jv, o jv = new JVector() o = jv.toString // but the java String is unregistered oc>print o JavaObject[0] oc> o.name // prints the underlying classname of the java object class java.lang.String jv.add1o(o) // now put that object into jv print jv.get(0) // still a JavaObject but not the same hoc version of it. jv.get(0).equals(o) // but they really are the same load_java("java.lang.String", "JString") print jv.get(0).toCharArray // Now it comes back as the proper JString!
load_java("java.util.Vector", "JVector") objref jv jv = new JVector() jv.add1o(new Graph()) print jv.get(0) //prints Graph[0] (if it was the first vector created) jv.get(0).size(-100,100,-200,200)
load_java("java.util.Vector", "JV") objref jv1, jv2 jv1 = new JV() jv1.add1o(new Vector()) jv1.add1o(jv1) jv2 = jv1.get(1) jv1 // prints JV[0] jv2 // prints JV[1] jv1 == jv2 /// they are different hoc objects jv1.equals(jv2) // but they are the same java objectIf this causes too much trouble in the future, then the jv1 == jv2 semantics can be changed.