I am using the Java API of Metashape, version 2.2.0. Everything is working fine on Windows, but when running on Linux, I am encountering something that seems like a native dependency issue. Here's a minimal code sample for demonstration (in Kotlin):
class LoadErrorDemo {
@Test
fun demo() {
// Make sure this is the first time we are loading the library
assertFalse(isMetashapeLoaded())
System.loadLibrary("metashape") // Copied from the sample file supplied with the library
// File contains camera data exported in the AgisoftXML format
val demoFile =
File("/home/six-tb-drive/Frederik/STREEM/PrismTests/V8/camera_export_from_agisoft_3_16_04_2024.xml")
val imageFolder = File("/home/six-tb-drive/Frederik/STREEM/PrismTests/V8/ExportForAgisoft")
val imageFiles: List<File> = imageFolder.listFiles()!!
.filter { it.extension.lowercase() in listOf("jpg", "jpeg", "png") }
val document = Document()
val chunk = document.addChunk()
chunk.addPhotos(imageFiles.map { it.absolutePath }.toTypedArray(), DummyProgress)
val importTask = ImportCameras()
importTask.path = demoFile.absolutePath
importTask.format = CamerasFormat.CamerasFormatXML
importTask.apply(chunk, ConsoleProgress(lineSeparator = "\n"))
// This is the part that fails
chunk.cameras.forEach { camera ->
println(camera.label)
}
}
object DummyProgress : Progress {
override fun progress(progress: Double) {
println("Progress: $progress")
}
override fun status(status: String?) {
println("Status: $status")
}
override fun aborted(): Boolean = false
}
}
The code is launched with the following environment variables:
LD_LIBRARY_PATH=/home/one-tb-drive/git/image-converter/metashape-java-api-2.2.0/jniLibs/linux64:$LD_LIBRARY_PATH
and the JVM is launched with the following VM parameters:
-ea -Djava.library.path="/home/one-tb-drive/git/image-converter/metashape-java-api-2.2.0/jniLibs/linux64"
The code fails when it tries to enumerate the cameras (chunk.cameras.forEach { camera -> }) with the following error:
/usr/lib/jvm/java-21-openjdk-amd64/bin/java: symbol lookup error: /home/one-tb-drive/git/image-converter/metashape-java-api-2.2.0/jniLibs/linux64/libmetashape.so: undefined symbol: _ZNK8JniUtils15createLongArrayERKSt6vectorIxSaIxEE
What I found out so far:
When unmangling the "undefined symbol", I found that the library fails to resolve JniUtils.createLongArray(). One assumption that I have is that the library is compiled with the JNI headers of Java 1.8 whereas I am using Java 21, which could cause discrepancies in the ABI. Unfortunately, I am heavily relying on newer Java features and am therefore unable to downgrade to Java 8.
My environment:
$ java -version
java -version
openjdk version "21.0.6" 2025-01-21
OpenJDK Runtime Environment (build 21.0.6+7-Ubuntu-124.04.1)
OpenJDK 64-Bit Server VM (build 21.0.6+7-Ubuntu-124.04.1, mixed mode, sharing)
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.2 LTS
Release: 24.04
Codename: noble
I'd like to hear if anyone else has faced this issue and what a potential fix could be. Thanks!