# 16. Runtime Hosting

Chapter Contents | Prev | Next
Keyword Search:
www.openlinksw.com
docs.openlinksw.com
Book Home
Contents
Preface
Runtime Hosting
Runtime Environments
CLR, .Net & ASPX Host
CLR & Mono
Embedded Java VM API
Correspondence Between Virtuoso & Java VM Threads Virtuoso/PL <-> Java VM Type Mapping Schema References to Java VM Class Instances in Virtuoso/PL Specifying the Correct Java Type When Passing Values from Virtuoso/PL Virtuoso Java PL API VSEs Java Security
Virtuoso Server Extension Interface (VSEI) (C Interface)
VSEI Plugins

## 16.4. Embedded Java VM API

The Java VM is an embedded system within Virtuoso that allows the calling of class Java methods and getting class properties. It uses the JAVA JNI API to interact with the JAVA VM.

### 16.4.1. Correspondence Between Virtuoso & Java VM Threads

At maximum one Java VM will be started on demand. If a function from the Java VM API is called and no JVM is running, one will be started, as required. Since Virtuoso is multithreaded it requires JDK version 1.3 or above in order to make better use of it's multithreading support. If the Java VM is already running the API VSEs attaches the current Virtuoso working thread, if not already attached, as a Java VM thread to the running VM. The Virtuoso worker thread does not automatically detached itself from the Java VM after use, therefore, in order to prevent leaving redundant Virtuoso worker threads being left attached to the Java VM the java_vm_detach() VSE should be used.

The following require access to the Java VM:

- all Virtuoso JAVA PL API (JVM VSEs)
- allocating/deallocating/copying of the Virtuoso/PL Java VM class reference values.

If no subsequent JVM VSEs are called after calling java_vm_detach(), the worker thread can still attach to the VM in order to deallocate or copy Java VM class reference values. In order to ensure that the worker thread is properly detached it is advisable to set all the variables that may hold Java VM class reference values to NULL, which deallocates their current value, before calling the java_vm_detach() JVM VSE.

Attaching and detaching Virtuoso worker threads is marked as a debug level message in the Virtuoso Event log, so that these messages can be used to debug the process.

### 16.4.2. Virtuoso/PL <-> Java VM Type Mapping Schema

Since the Java language uses a different set of data types than Virtuoso a type mapping system has been established to allow the passage of data to and from Java. All Java simple types are mapped to a corresponding Virtuoso type as follows:

Table: 16.4.2.1. Java - Virtuoso Data Type Mapping
Java Type/Class | Virtuoso Internal Type
--- | ---
boolean | smallint
char | smallint
double | double precision
float | real
int | integer
short | integer
long | integer
boolean | smallint
java.lang.String | NVARCHAR
java.util.Date | DATETIME

All other Java objects are represented as a special Virtuoso value, which contains a reference to the Java object in the VM memory space. When such a value is returned as a Virtuoso/PL return value or as a result set column, it calls the java.lang.Object.toString() method for the Java VM object it refers to and that result is returned to the calling client.

Arrays are mapped to a Virtuoso vector of their elements. The array handling routines are recursive, so each element may be a Java array or a scalar type.

The above mappings are applied when converting Virtuoso/PL data to Java data as follows:

- method parameter values in java_call_method VSE
- method parameter values in java_new_object VSE
- property values in java_set_property VSE
- the instance parameters in java_call_method/java_get_property/java_set_property VSEs

The above mappings are applied in the opposite direction (Java Data -> Virtuoso/PL data) as follows:

- method return values in java_call_method VSE
- return value of the java_new_object VSE
- property values returned from java_get_property VSE

### 16.4.3. References to Java VM Class Instances in Virtuoso/PL

Java Class instances are represented as a Virtuoso/PL variable values using a Java VM Global Reference. Each time such a Virtuoso/PL variable value is created or copied, it adds a Java VM Global Reference. When it is freed, it removes the Java VM global reference, allowing the Java Garbage collector (GC) to free it. Each of the API VSEs create a Java VM local frame upon it's start, and frees it upon exit. This allows for fast deallocation of the local objects created by mapping Virtuoso/PL native values to Java objects.

### 16.4.4. Specifying the Correct Java Type When Passing Values from Virtuoso/PL

Each method parameter in the java_new_object()/java_call_method() can be either the value itself or a two-element vector. When it is a two-element vector it's first element is the JNI type signature string, e.g.: for integer - I, for array of integers - [I], for java.lang.String - Ljava/lang/String. The signature is important because the Java VM JNI API needs it in order to find the appropriate constructor/method/property.

### 16.4.5. Virtuoso Java PL API VSEs

The API consists of the following VSEs:

- java_call_method()
- java_set_property()
- java_get_property()
- java_load_class()
- java_new_object()
- java_vm_attach()
- java_vm_detach()

### 16.4.6. Java Security

Java classes are hosted in one of two modes:

- Restricted
- Unrestricted

Java class Permissions are managed by security classes that fall into categories as follows listed with it managing class:

- File - java.io.FilePermission
- Socket - java.net.SocketPermission
- Net - java.net.NetPermission
- Security - java.security.SecurityPermission
- Runtime - java.lang.RuntimePermission
- Property - java.util.PropertyPermission
- AWT - java.awt.AWTPermission
- Reflect - java.lang.reflect.ReflectPermission
- Serializable - java.io.SerializablePermission

Restricted classes are not allowed any of the above priviledges. Virtuoso returns errors that are returned by the security manager if breaches in security are attempted by a hosted Java class.

By default all Java classes are imported/created/hosted in restricted mode. To create Java class based user defined types that are unrestricted you need to use create type syntax with UNRESTRICTED keyword. The import_jar() funtion can also be used to import classes, its third optional parameter can be used to define the security mode.

Note:

New behavior since Virtuoso 3.2 provides these two security modes defaulting to restricted. Prior to this Java classes were hosted in unrestricted mode.

Java Security

The class Write_file, shown below, will attempt to write to a file on the file system. This class will be used to create a user defined type first in unrestricted mode and then in restricted mode to demonstrate how security exceptions are returned.

Source of Write_file.java:

    import java.io.*;

    public class Write_file
    {
      public String write ()
        {
          String myFile = "foo";
          File f = new File(myFile);
          DataOutputStream dos;

          try
    	{
    	  dos = new DataOutputStream (new BufferedOutputStream(new FileOutputStream (myFile),128));
    	  dos.writeBytes("ABC\n");
    	  dos.flush();
    	  dos.close();
    	}

          catch (IOException ioe)
    	{
    	  System.out.println("writeFile: caught i/o exception");
    	}

          return "OK";
        }
    }

Create the unrestricted type:

    create type "Write_file" language JAVA external name 'Write_file'
      unrestricted METHOD "write" ()
      returns nvarchar external type 'Ljava/lang/String;' external name 'write';

Test calling the method:

    SQL> select new Write_file().write();
    callret
    NVARCHAR
    _________________________________________

    OK

Now we want to recreate the type in restricted mode, remembering to drop it first:

    drop type DB.DBA.write_file;

    create type "Write_file" language JAVA external name 'Write_file'
      METHOD "write" ()
      returns nvarchar external type 'Ljava/lang/String;' external name 'write';

Test calling the method:

    SQL> select new Write_file().write();

    *** Error 42000: [Virtuoso Driver][Virtuoso Server]JV001: Java exception
    occurred : java.security.AccessControlException : access denied
    (java.io.FilePermission foo write)
    in  __udt_method_call:(BIF),
    <Top Level>
    at line 1 of Top-Level:
    select new Write_file().write()

Another way to import the above class is by use the import_jar() such as:

    import_jar (NULL, 'Write_file', 1) - will import java classes in unrestricted mode.
    import_jar (NULL, 'Write_file') - will import java classes in restricted mode.

Previous CLR & Mono | Chapter Contents | Next Virtuoso Server Extension Interface (VSEI) (C Interface)