Search code examples
javaintersystems-cacheintersystemsobjectscriptintersystems-ensemble

Intersystems Caché Java Gateway


I need some help on development in Caché's Objectscript.

I've been working in this technology for some months and since some days, I'm trying to get the Java Gateway to work without success. It is supposed to allow me to run java .class et .jar code.
But even if it is explained in the documentation, there is no full example and I'm getting errors over and over. So, I was wondering if someone can provide a full example, correct me or explain what I'm doing wrong?

Here is what I have for now:

My simple java class - write date and time in a file

package packagename.packagename2;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;

public class entertest {

    public int enter() throws IOException
    {
         File file = new File("D:\\path\\filemane.txt");

         if (!file.exists()) {
              file.createNewFile();
         }

         BufferedWriter bf = new BufferedWriter(new FileWriter(file.getAbsoluteFile()));
         bf.write(LocalDateTime.now().toString());
         bf.close();

         return 1;
     }

}

My objectscript code - define my gateway and try to call the method

Class domain.java.TestJava Extends EnsLib.HL7.Service.TCPService
{

    Method OnProcessInput(pLine As Ens.StringContainer, Output pLineLeftOver As Ens.StringContainer) As %Status
    {
        Do ##super(pLine,pLineLeftOver)
        Set val = 0

        $$$TRACE(val)

        Set gateway = ##class(%Net.Remote.Gateway).%New()
        Do gateway.%Connect("127.0.0.1", 55553)
        Do gateway.%Import("D:\\path\\entertest.jar")

        Set javaObj = ##class(packagename.packagename2.entertest).%New(gateway)
        Set val = javaObj.enter()

        $$$TRACE(val)

        Quit $$$OK
    }
}

I get an error :

ERREUR <Ens>ErrException: <CLASS DOES NOT EXIST>zOnProcessInput+9^domain.java.TestJava.1 *packagename.packagename2.entertest 
    -- - connecté en tant que '-' numéro - @' Set javaObj = ##class(packagename.packagename2.entertest).%New(gateway)'

I used this post but I don't know how he got it working: Intersystems Caché with Java Gateway - Pass parameter as java.io.FileInputStream

I tried to add a service "JavaGatewayService" in the Ensemble production. Did not help...
I also tried to add an object gateway in

System Administration > Configuration > Connectivity > Object Gateways.

Did not help... And I don't know if it should help me...

I'm out of ideas/options.

Thank you in advance.


Solution

  • I finally managed to get a working solution so I'm adding this for sharing it to give a fully step by step guide.

    Here is what I needed to do:
    In Ensemble: I added a "JavaGateway" service of "EnsLib.JavaGateway.Service" configured with 127.0.0.1 as the address and 55555 as Port (these are default values I think). I also specified using "Java 1.8" in JDKVersion.

    I wrote this as Java code and exported it as a Jar archive:

    package packageName;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.time.LocalDateTime;
    
    public class EnterTestClass {
    
        public long enter() throws IOException {
    
            File file = new File("D:\\Path\\EnterTestClass.txt");
    
            if (!file.exists()) {
                file.createNewFile();
            }
    
            BufferedWriter bf = new BufferedWriter(new FileWriter(file.getAbsoluteFile()));
            bf.write(LocalDateTime.now().toString());
            bf.close();
    
            return 1;
        }
    }
    

    In Studio, I created a new class.
    Here is the code:

    Method OnProcessInput(pLine As Ens.StringContainer, Output pLineLeftOver As Ens.StringContainer) As %Status
    {
        Set val = 0
        $$$TRACE(val)
    
        Set gateway = ##class(%Net.Remote.Gateway).%New()
        Do gateway.%Connect("127.0.0.1", 55555)
    
        Set javaObj = ##class(packageName.EnterTestClass).%New(gateway)
        Set val = javaObj.enter()
    
        $$$TRACE(val)
        Quit $$$OK   
    }
    

    And I used the menu "Tools" -> "Extensions" -> "Java Gateway Assistant": I selected Jar File, gave the full path, the above values 127.0.0.1 and 555555, clicked on "Next", ckecked the class to import and clicked "Finish".

    On the right tree of Studio (in namespaces view), the imported class should be visible.

    It then worked when launching the OnProcessInput (by sending a tcp request in my case).

    Thank you DAiMor for your help with some of my errors and sorry for my english and if the menus don't have exactly the names I wrote (I'm belgian and working on a French version of Studio and Ensemble).