Class SikuliNativeLibraryStager

java.lang.Object
com.shaft.sikulix.internal.SikuliNativeLibraryStager

public final class SikuliNativeLibraryStager extends Object
Stages the native OpenCV matcher library into SikuliX's own "libs folder" (%APPDATA%/Sikulix/SikulixLibs on Windows, ~/Library/Application Support/Sikulix/SikulixLibs on macOS, ~/.Sikulix/SikulixLibs on Linux -- see Commons.getAppDataPath()) before any SikuliX class touches native loading.

SikuliX 2.0.5 resolves its native OpenCV binary via org.sikuli.script.support.RunTime#libsLoad, which only ever looks inside that folder for a file named after the OpenCV build actually on the classpath (Core.NATIVE_LIBRARY_NAME plus the platform extension). SikuliX populates the folder itself, on first use, from a manifest bundled in its own jar (sikulixlibs/<os>/libs64/sikulixcontent) -- but that manifest still names opencv_java430.dll (OpenCV 4.3.0), stale since shaft-sikulix/pom.xml pinned org.openpnp:opencv:4.9.0-0 directly (PR #3408) to fix an unrelated NoClassDefFoundError. That jar only contains opencv_java490.dll, so SikuliX's own extraction step always fails, deletes the whole folder it just created, and every later native-lib lookup throws SikuliXception: loadlib: opencv_java490.dll not in any libs folder (issue #3805; confirmed via RunTime:libsExport: opencv_java430.dll: failed in the Windows_SikuliX_Local nightly log).

Rather than relying on SikuliX's stale manifest, this pre-stages the native that is actually on the classpath (bundled as a resource inside org.openpnp:opencv) directly under the exact file name SikuliX's loader will ask for, and marks the folder as already prepared via Commons.makeVersionFile(File) so SikuliX's own (otherwise-failing) extraction step is skipped rather than re-run on top of it.

  • Method Details

    • ensureOpenCvNativeStaged

      public static void ensureOpenCvNativeStaged()
      Ensures the OpenCV native SikuliX will look for is present in its libs folder. Safe to call repeatedly -- a no-op once already staged for the running SikuliX build -- and a best-effort no-op if the target location cannot be determined or written, in which case SikuliX's own loader still surfaces its usual SikuliXception, unchanged from today's behavior.