Scripting with Java
The purpose of this tutorial is to teach you about working with Java while scripting.
On completion, you will:
- know how to call Java code from scheme script
- be able to add Java libraries to models
- add Java implemented actions/events to classes
Key Concepts
Scripting can support invocation of Java Code. Java may be invoked in script or as an action for an event.
There are three ways that Java Code can be invoked from scheme:
- An instance of a built-in object that implements nexj.core.scripting. Function: This is the case for most (Java) presentation layer code. This is usually only used only by NexJ developers and is not discussed further here.
- Other built in libraries that don't implement nexj.core.scripting. Function: In this case the Java class is examined using Java reflection and all public methods and fields are available. As well the following Java-bean style transformations are performed on Java method names.
- getPropertyX() is accessible in script as (instance'propertyX)
- setPropertyX(Object value) is accessible in script as (instance'propertyX value)
- isPropertyX() is accessible in script as (instance'propertyX)
- isTLAPropertyX() is accessible in script as (instance'tlaPropertyX)
- getXWithArguments(Object, Object) is accessible in script as (instance'getXWithArguments a b) (no transformation)
- setXWithArguments(Object value, Object value2) is accessible in script as (instance'setXWithArguments value value2) (no transformation)
- To see a list of built-in Java libraries, type "nexj" or "java" in a script editor and press <CTRL><Space>.
- Import a class and then construct an instance or invoke it statically: Use the import function to make it accessible to the Scripting VM. Once imported you can refer to the variable of the same name as the fully qualified Java class name to affect static fields and methods (using the same rules as above). To invoke the constuctor use the 'new member. Note: this should never be done in client-side code as it will not work on most clients.
- For example: (import <fullyQualifiedJavaClass>)
- To import an inner class use "$" as the last seperator. For example (import 'nexj.core.persistence.sql.SQLSchemaManager$SQLConnectionAppender)
Using Pre-referenced Built-in Java Classes
Start the Scheme Console. In the Resources tab, create a new scratchpad called "Java". In your scratchpad, type "nexj" and <CTRL><Space>. You should see a list of built-in NexJ Java libraries.
Try the following static methods.
> (nexj.core.util.GUIDUtil'NULL_GUID)
; #z00000000000000000000000000000000
> (nexj.core.util.GUIDUtil'generateGUID)
; zB34BDA610D25444A89537A0AEA9B4981
> (nexj.core.util.Base64Util'encode (bytevector 0 -127 255 -1 -2))
; "AIH///4="
Try the following instance code:
> (define dte (java.util.Date'new "01/25/2011"))
; #<Tue Jan 25 00:00:00 EST 2011>
> (dte'toGMTString) ; notice that <CTRL><Space> knows what dte is
; "25 Jan 2011 05:00:00 GMT"
Importing Unreferenced Built-in Java Classes
Importing a Java class is done with the (import... command. This is evaluated at run time, so this function should typically be invoked at the global scope in libraries.
Try the following in your scratchpad and console.
> (import 'java.util.Random)
; 14:35:44,331 DEBUG [GlobalEnvironment] (NexJ-ContainedProcess) Importing class
java.util.Random
> (define rnd (java.util.Random'new))
; #<java.util.Random@59ab51b0>
> (rnd'nextInt)
; -2065740977
Importing Java Classes in Jars
This works fine for classes that are part of Java or the NexJ Framework.
For other libraries, such as your own custom encryption or integration classes, you need to add them to your model. To do this for externally built jars, follow these steps:
- In the Java Perspective of NexJ Studio, add a folder called lib at the top level i.e. the same level as the meta folder.
- Place the jar that contains your classes the lib folder.
- Restart your console and you may now reference classes from your jar with the import function.
Building Java Code in Your Model
If you have is Java code that you want to include and reference in your model, follow these steps:
If your project isn't already a Java Project, open the .project file and add the Java nature and builder sections.
XML<projectDescription> <name>core</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>org.eclipse.jdt.core.javabuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>com.nexjsystems.nexjstudio.NexJBuilder</name> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>org.eclipse.jdt.core.javanature</nature> </natures> </projectDescription>
- Create a new source folder in your project called src. i.e. In the Java Perspective go File/New/Source Folder...
- Create a new Class. Name the package scripting.demo and name the Type Hello.
Add a getHello method to your class along the following lines:
JAVApackage scripting.demo; public class Hello { private String m_hello = "Hello"; public String speak() { return m_hello; } }
- Save your file and clean/build your project. Project/Clean... Clean projects selected below (Select your project) and check start a build immediately with only your project selected.
- Your built file should show up in the bin folder.
Run the console and enter the following:
CODE> (import 'scripting.demo.Hello) ; 15:56:14,924 DEBUG [GlobalEnvironment] (NexJ-ContainedProcess) Importing class scripting.demo.Hello > (define demo (scripting.demo.Hello'new)) ; #<scripting.demo.Hello@1a03ff34> (demo'speak) ; "Hello"
Wrapping Java Classes with Business Classes
This needs documentation - See SysWorkflow.meta for an example.