Вызов ColdFusion 2016 для Java TensorFlow API не может инициализировать класс

Я пытаюсь вызвать TensorFlow Java API из версии для разработчиков ColdFusion 2016 в Windows 10 Home.

Я взял свои реплики из TensorFlow Readme.md Он использует специфичную для платформы dll JNI в дополнение к банке, поэтому я настроил свой тест следующим образом: <cfscript> CreateObject("java","java.lang.System").load("C:\\absolutepath\\tensorflow_jni.dll"); variables.tensorflow = CreateObject("Java","org.tensorflow.TensorFlow"); WriteDump(variables.tensorflow); WriteOutput("I'm running TensorFlow version: " & variables.tensorflow.version()); </cfscript>

Я подумал, что это будет легко, когда увидел WriteDump объекта:введите здесь описание изображения

но вызов version() просто заставляет браузер вращаться.

Журнал приложений показывает следующую ошибку: Could not initialize class org.tensorflow.TensorFlow The specific sequence of files included or processed is: C:\ColdFusionBuilder2016\ColdFusion\cfusion\wwwroot\CF_TensorFlow\index.cfm, line: 5

Кажется, что JNI загружается... Когда это не так, сообщение об ошибке очень ясное: "Не удается найти собственную библиотеку TensorFlow для ОС: окна..."

Я не совсем уверен, что делать в этот момент. Есть ли что-то, что мне нужно сделать с исходным кодом Java, чтобы он хорошо работал с CF?


person Brien Malone    schedule 30.04.2017    source источник
comment
Не уверен, можно ли/как его загрузить во время выполнения. Что определенно сработает, так это либо а) добавление пути dll к java.library.path, либо б) копирование файла dll в jre\bin. Потом перезапуск.   -  person Leigh    schedule 30.04.2017
comment
Ах, похоже, его можно загрузить во время выполнения, связав dll внутри jar. Смотрите мой ответ ниже.   -  person Leigh    schedule 30.04.2017


Ответы (1)


Как вы, наверное, поняли, библиотека сначала ищет DLL в стандартных местах. Таким образом, добавление пути или файла в одно из этих мест (затем перезапуск CF) определенно сработает:

  • Добавьте путь DLL к java.library.path
  • Скопируйте файл DLL в каталог jre\bin

Просмотр источника и комментарии, по-видимому, DLL также может быть объединена внутри самой банки TensorFlow. Точный путь зависит от операционной системы:

private static String makeResourceName() {
    return "org/tensorflow/native/"
        + String.format("%s-%s/", os(), architecture())
        + System.mapLibraryName(LIBNAME);
}

Поэтому вместо использования System.load() откройте банку и скопируйте DLL в соответствующую папку. Для 64-разрядной версии Windows ожидаемый путь — org/tensorflow/native/windows-x86_64/tensorflow_jni.dll.

libtensorflow-1.1.0-rc2-with-dll.jar 

  |-- META-INF
  |-- org    
      |-- tensorflow    
          |-- TensorFlow.class
          |-- ... 
          |-- native 
              |-- windows-x86_64
                  |-- tensorflow_jni.dll
person Leigh    schedule 30.04.2017
comment
Спасибо за усердие, Ли. Я попробую это, когда вернусь на свою рабочую станцию, и отчитаюсь. - person Brien Malone; 30.04.2017
comment
Потрясающий!! Спасибо. Это было так же просто, как связать. Оглядываясь назад, я упустил несколько моментов, которые должны были бросаться мне в глаза. Когда я попытался связать его в первый раз, я поместил его в папку с буквальным названием native/OS-ARCH вместо native/windows-x86_64. Мне не повезло с путями, которые вы упомянули. Я думал, что JNI работает нормально, потому что я перестал видеть ошибку «Не удается найти собственную библиотеку TensorFlow», как только я поместил JAR и DLL в папку WEB-INF\lib, но он все еще выдавал ошибку «не удалось инициализировать класс». Однако комплектация работала отлично. - person Brien Malone; 01.05.2017
comment
Хех, я тоже сделал ошибку ос-арх. В любом случае рад, что помогло. RE: не повезло с путями, которые вы упомянули Хм... странно. Вы перезапустили потом? Требуется. Копирование DLL в jre\bin сработало для меня. Я не пробовал java.library.path, но предполагаю, что он работает, поскольку переменная среды Windows PATH довольно стандартна. Хотя объединение его с банкой, вероятно, в любом случае лучший метод, поскольку он более динамичен. - person Leigh; 01.05.2017
comment
Я перезапустил, да. Вы просто помещаете оба прямо в эту папку, а не в подпапки, верно? - person Brien Malone; 01.05.2017
comment
(Редактировать) Да, никаких подпапок, а только файл DLL. .jar, который я, как обычно, загрузил с помощью this.javaSettings. - person Leigh; 01.05.2017