Using the Java code from OPL

Explains how to import Java classes and how to call Java from OPL.

Two IBM ILOG Script functions enable you to call Java external functions from OPL models in IBM ILOG Script statements.

The successive steps are:

  1. Importing Java classes

  2. Calling Java

Then, learn more about Translation of parameters and results and Creation of the Java Virtual Machine (JVM).

Importing Java classes

The function

IloOplImportJava(<directory or path to jar file>);

imports the classes into the given directory or JAR file in IBM ILOG Script, so that they can be called. The path can be either absolute or relative to the directory of the model file.

Calling Java

The function

<Script object or Java object>=IloOplCallJava(<class name> or <Java object>,<method name>,[<method signature> or ""],[<parameters>,...]);

enables you to call static methods, constructors, and instance methods.

The method signature is only needed when there is an ambiguity (method overloading), that is when several methods have the same name but different signatures. It is a string with the JNI signature, something like:

"(Lilog/opl/IloOplModel;ILjava/lang/String;)V"

for a method taking an IloOplModel instance and a String as parameters.

Therefore, you can call:


// static method:
var result=IloOplCallJava("mypackage.MyClass","myStaticMethod","",15);

// create instance:
var myObject=IloOplCallJava("mypackage.MyClass","<init>","","init param");

// call method on instance (two syntaxes are possible):
var mySubObject=IloOplCallJava(myObject,"getSubObject","");
or
var mySubObject=myObject.getSubObject();

The classes are looked for in the JAR files or on the paths specified by the IloOplImportJava instance (see the Importing Java classes section above).

Translation of parameters and results

Both the parameters and the results of the call are translated from IBM ILOG Script to Java (and conversely) as needed.

The rules are as follows:

  • Simple data types (numbers, strings, Booleans) are translated back and forth.

    • A Java method taking a string can be called with an IBM ILOG Script string.

    • A Java method returning a string appears as returning an IBM ILOG Script string.

  • Arrays are also translated back and forth between Java and IBM ILOG Script arrays.

  • Some known types that have representations in both IBM ILOG Script and Java are also translated back and forth, so that:

    • A Java method taking an IloOplModel object can be called with an IBM ILOG Script model such as thisOplModel.

    • A Java method returning a custom Java data source appears as returning an IBM ILOG Script data source, which enables you to add it to the model using regular script statements.

  • Unknown Java types (created by Java code) are represented as special JavaRef objects in IBM ILOG Script so that you can call any methods on them and pass them as parameters in subsequent calls.

    • A Java method returning a Java object of class MyClass appears as returning a special JavaRef object from IBM ILOG Script.

    • You can call methods on that JavaRef object (syntax: myObject.myMethod()), or pass it as a parameter to other Java calls (which will see a normal Java object of class MyClass).

Creation of the Java Virtual Machine (JVM)

When the calls are executed:

  • Either there is a JVM running: this is the case for IBM Decision Optimization Center 3.9.1 and earlier applications, the IDE in Decision Optimization Center mode, custom Java applications. Then, the call is performed within the current JVM.

  • Or there is no JVM running: this is the case for the IDE in pure OPL mode and for oplrun. Then, a new JVM is created.

The JVM is initialized at the first call. To create the JVM, the runtime process must find both the Java home and the OPL home to access the OPL .jar file. If Decision Optimization Center is installed, the process must also find the Decision Optimization Center home to access the Decision Optimization Center .jar files, so that the Decision Optimization Center scripting works. These environment variables are detected automatically. See the Java API Reference Manual for details.

If a new JVM is created, it receives the value of the environment variable ODMS_JAVA_ARGS as parameter, if this variable is defined. This variable is also already taken into account if the JVM is started by the IDE (IDE in Decision Optimization Center mode) or in a Decision Optimization Center application. This enables you to customize the way in which the JVM is created, for example by adding more virtual memory, customizing the default classpath, and so on.

Deploying OPL models with external Java function calls on Linux

When deploying OPL models that make external Java function on Linux platforms, the following information might be useful:

  1. The environment variable JAVA_HOME need to be defined. OPL will load a JVM from JAVA_HOME for the external Java function calls. When the models are solved by a Java Application, the JVM for the Java application and the JVM for the external Java functions calls must be the same version.

  2. A JVM might have multiple modes, such as client, server, etc. When the models are solved by a Java Application, the JVM for the Java application and the JVM for the external Java functions calls must also be in the same mode. The default mode of JVM OPL chooses to load for external Java function calls will be printed to standard output when a model with external Java function calls is solved by oplrun (OPL 5.x) or oplrunjava (OPL 6.x).

  3. If you want to use a different mode of JVM other than the default mode, you will need to use the environment variable ODMS_JVM_LIBRARY_OVERRIDE to override the default selection. The value of ODMS_JVM_LIBRARY_OVERRIDE should be the relative path of libjvm.so from the JRE root path. For example, defining ODMS_JVM_LIBRARY_OVERRIDE as /lib/i386/server/libjvm.so will cause OPL to load a 32-bit server JVM.