Question
· May 19, 2020

JavaGateway exception: <UNDEFINED>zGetJavaVersion+22^%Net.Remote.Service.1 ‽‽

Hello,

 

We are trying to connect to a database through a JavaGateway.

 

We observe that the JavaGateway reports:

Failed to start the Java Gateway server: ERROR #5002: Error de cache: <UNDEFINED>zGetJavaVersion+22^%Net.Remote.Service.1 *versionWithPrefix

 

We have checked that we do have the Java Home set:

/usr/java/jdk1.8.0_65

 

And we have seen the java files in the server:

 

We have read the code where the exceptions being raised:

 

/// Returns the numeric part of the Java version string (e.g. 1.8.0.1)
/// Rules of how the complete version string is formatted can be found here:
/// http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
ClassMethod GetJavaVersion(javaHomeDir As %String = "", Output version As %String = "") As %Status
{
#dim tSC As %Status = $$$OK
#dim tCurrentDevice As %String = $IO Try {
// Build the java executable path
Set javaExecutable = "java"_$Select($$$isWINDOWS:".exe",$$$isVMS:".exe",1:"")
If (javaHomeDir'="") {
Set javaBinDir = ##class(%Library.File).SubDirectoryName(javaHomeDir,"bin")
Set javaBinDir = javaBinDir_$Select($$$isWINDOWS:"\",$$$isVMS:"",1:"/")
Set javaExecutable = ##class(%Library.File).NormalizeFilename(javaExecutable,javaBinDir)
}
Set tSC = ..GetJavaExecutableCommand(javaHomeDir,.javaExecutable)
Quit:$$$ISERR(tSC) // java -version prints to std err, not std out, so we need to redirect otherwise command pipe output will be empty
Set versionCmd = javaExecutable_" -version 2>&1"
Do ##class(%Net.Remote.Utility).RunCommandViaCPIPE(versionCmd,.pDevice,.pOutput) // Look for pattern : version "1.8.0.1
// where the double quote may optionally be replaced with a single quote or ommitted
Set regex = "version\s['""]?(\d+(\.\d+)+)"
Set pos = $Locate(pOutput,regex,1,,versionWithPrefix) // Get just the number from the previous pattern : 1.8.0.1
Set regex = "(\d+(\.\d+)+)"
Set pos = $Locate(versionWithPrefix,regex,1,,version)
Catch (ex) {
Set tSC = ex.AsStatus()
} // Close command pipe, restore original device
Close:($Get(pDevice)'="") pDevice:"I"
Use tCurrentDevice Quit tSC
}

 

The exception is being thrown at the line:

Set pos = $Locate(versionWithPrefix,regex,1,,version)

 

Because of versionWithPrefix is undefined

 

It makes us wonder, why the regex is not getting the java version?

However if we test the regular expression at: https://www.freeformatter.com/java-regex-tester.html#ad-output

It shows that it should get the java version installed in the server:

So we wonder, how do we know if ensemble has read/write/execution rights to execute the command, which is being seen in the line:

// java -version prints to std err, not std out, so we need to redirect otherwise command pipe output will be empty
Set versionCmd = javaExecutable_" -version 2>&1"
Do ##class(%Net.Remote.Utility).RunCommandViaCPIPE(versionCmd,.pDevice,.pOutput)

 

How could we investigate and solve this?

We have read:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

https://community.intersystems.com/post/execute-server-commands-cach%C3%...

Discussion (2)2
Log in or sign up to continue

What does

write $SYSTEM.Util.GetEnviron("JAVA_HOME")

return in the same process as JavaGateway?

If not /usr/java/jdk1.8.0_65 you might need to restart the InterSystems IRIS instance.

Your OS user can be determined by running:

write $system.Process.UserName()

again it's important to run this code in the same process as Java Gateway.

After you determined effective OS username you can check folder/executable permissions.

Finally, SELinux if enabled might require additional configuration.

What Caché version do you have?

On my 2018.1.3 instance code is following:

// Look for pattern : version "1.8.0.1
// where the double quote may optionally be replaced with a single quote or ommitted
Set regex = "version\s['""]?(\d+(\.\d+)+)"
Set pos = $Locate(pOutput,regex,1,,versionWithPrefix)

// Get just the number from the previous pattern : 1.8.0.1
Set regex = "(\d+(\.\d+)+)"
Set pos = $Locate($Get(versionWithPrefix),regex,1,,version)

Notice -- $Get around versionWithPrefix.

Most likely Caché cannot find java home dir. Specify Java Home Directory in JDBC Gateway Server settings.