Closed timob closed 5 years ago
Best way to do this is to look for java command in PATH and find relative path to this that contains libjvm.so. (this is what Eclipse does). see http://git.eclipse.org/c/equinox/rt.equinox.framework.git/tree/features/org.eclipse.equinox.executable.feature/library/eclipseNix.c
Any progress on this? I'm trying to use this library in AWS lambda and it is not able to find libjvm.so
.
I was able to get it working by doing a really dumb filetree walk in linux.go
func init() {
libJVMLoc := ""
if err := filepath.Walk("/usr/lib/jvm", func(path string, f os.FileInfo, err error) error {
if err != nil {
panic(err)
}
if strings.HasSuffix(path, "libjvm.so") && strings.Contains(path, "java-1.8") {
libJVMLoc = path
}
return nil
}); err != nil {
panic(err)
}
cs := cString(libJVMLoc)
log.Infof("using libjvm: %s", libJVMLoc)
defer free(cs)
libHandle := uintptr(C.dlopen((*C.char)(cs), C.RTLD_NOW|C.RTLD_GLOBAL))
if libHandle == 0 {
panic(errors.Errorf("could not dynamically load libjvm.so: %s", libJVMLoc))
}
...
Glad you got it working. I think this code does a bit too much to find the path, and hard codes /usr/lib/jvm
and java-1.8
.
I think it should be:
java
executable in $PATH
, following symlinks if encounteredjava
path plus relative dir contains libjvm.so
So for my ubuntu:
java
is in: /usr/lib/jvm/java-8-openjdk-amd64/jre/bin
relative path of containing libjvm.so
: ../lib/amd64/server/
Also now we need to do this for darwin as well to find libjvm.dylib
.
This is how I modified linux.go, to use an env LIBJVM (you are not taking pull requests?):
` . . . import ( "os" "unsafe" )
const LIBJVM = "LIBJVM"
func jni_GetDefaultJavaVMInitArgs(args unsafe.Pointer) jint { return jint(C.dyn_JNI_GetDefaultJavaVMInitArgs((unsafe.Pointer)(args))) }
func jni_CreateJavaVM(pvm unsafe.Pointer, penv unsafe.Pointer, args unsafe.Pointer) jint { return jint(C.dyn_JNI_CreateJavaVM((*C.JavaVM)(pvm), (unsafe.Pointer)(penv), (unsafe.Pointer)(args))) }
func init() { libjvm := os.Getenv(LIBJVM) if libjvm == "" { libjvm = "/usr/lib/jvm/default-java/jre/lib/amd64/server/libjvm.so" } cs := cString(libjvm) defer free(cs) libHandle := uintptr(C.dlopen((*C.char)(cs), C.RTLD_NOW|C.RTLD_GLOBAL)) if libHandle == 0 { panic("could not dyanmically load libjvm.so") } . . .
I think we can use JAVA_HOME
environment variable for all operating systems.
I agree. I think it would also be safe to panic if the variable is not set instead of attempting to load a hard-coded path i.e., https://github.com/timob/jnigi/blob/master/darwin.go#L63
@hscells Ok i've made that change.
This commit uses JAVA_HOME
to find path:
https://github.com/timob/jnigi/commit/4a6d12459ba7cd175426a185b96cb357338cfe3b
Currently libjvm.so is dynamically loaded on Linux but the path currently is hard coded in linux.go. Need to dynamically determine this.