Вопрос или проблема
Я сталкиваюсь с проблемой, когда пытаюсь запустить функциональные макеты (FMU) на моем сервере Ubuntu 22.04, используя обертку JavaFmi в контейнере Docker на основе образа Wine (версии 9.0), потому что у меня есть некоторые FMU (.dll) и другие (.so).
Ошибка:
Пытаюсь (через loadLibrary) jnidispatch
Нашел jnidispatch в системном пути
2024-10-09T14:57:33.937Z ОШИБКА 1 --- [simulation-win-ms] [nio-8066-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() для сервлета [dispatcherServlet] в контексте с путем [] выбросил исключение [Ошибка обработчика: java.lang.UnsatisfiedLinkError: Не удалось загрузить библиотеку '/tmp/fmu_58a0f513_0f68_4f3e_b420_04f673a1754dtest_FMU/binaries/win64/test_FMU.dll': Нативная библиотека (tmp/fmu_58a0f513_0f68_4f3e_b420_04f673a1754dtest_FMU/binaries/win64/test_FMU.dll) не найдена в ресурсах ([])] с корневой причиной
java.lang.UnsatisfiedLinkError: Не удалось загрузить библиотеку '/tmp/fmu_58a0f513_0f68_4f3e_b420_04f673a1754dtest_FMU/binaries/win64/test_FMU.dll': Нативная библиотека (tmp/fmu_58a0f513_0f68_4f3e_b420_04f673a1754dtest_FMU/binaries/win64/test_FMU.dll) не найдена в ресурсах ([])
Я получаю это сообщение об ошибке, указывающее на то, что нативная библиотека (DLL) не может быть найдена, хотя я могу получить доступ к файлам FMU внутри контейнера Docker, используя docker exec -it
. Я уже пытался явно установить путь к библиотеке JNA, но проблема сохраняется. Кроме того, я не могу установить фиксированный путь для файлов FMU, потому что их имена содержат автоматически сгенерированные UUID при каждом выполнении.
А вот мой wine dockerfile :
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y --no-install-recommends \
wget \
gnupg2 \
software-properties-common \
curl \
file \
xvfb \
&& wget -nc https://dl.winehq.org/wine-builds/winehq.key && \
apt-key add winehq.key && \
add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ jammy main' && \
apt-get update && \
apt-get install -y --install-recommends \
winehq-stable \
openjdk-18-jdk \
cabextract \
p7zip-full \
unzip \
wine32 \
wine64 \
winbind \
&& apt-get clean && \
rm -rf /var/lib/apt/lists/*
ENV WINEDEBUG=-all
ENV WINEPREFIX=/root/.wine
ENV WINEARCH=win64
RUN wget -O /usr/bin/winetricks https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks && \
chmod +x /usr/bin/winetricks
RUN winetricks --self-update
RUN winecfg
ENV JAVA_HOME=/usr/lib/jvm/java-18-openjdk-amd64
ENV PATH=$JAVA_HOME/bin:$PATH
ENV JNA_LIBRARY_PATH="/tmp"
А затем мой dockerfile микросервиса на основе этого собранного образа Wine :
FROM docker24/wine:latest
WORKDIR /
COPY /target/simulation_win_microservice-1.0-SNAPSHOT.jar /app.jar
COPY src/main/resources/win32-x86-64/libjnidispatch.so /tmp
RUN cd /tmp && ls
RUN chmod -R 777 /tmp
RUN cd /tmp && ls -al
ENV JNA_LIBRARY_PATH="/tmp"
ENTRYPOINT ["java","-Djava.library.path=/tmp:/usr/lib:/lib:/usr/lib:/lib:/usr/lib/jvm/java-18-openjdk-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ,"-Djna.library.path=/tmp:/tmp/fmu_*/binaries/win64/*.dll" ,"-jar", "/app.jar"]
Использую ли я подходящую конфигурацию Wine для своего приложения? Есть ли какие-либо конкретные конфигурации или настройки Wine, которые могут влиять на загрузку нативных библиотек? Возможно ли динамически загружать FMU DLL на основе автоматически сгенерированного UUID?
Ответ или решение
Решение проблемы с загрузкой нативных библиотек (DLL) в контейнере Wine на Ubuntu 22.04
Введение
Вы столкнулись с задачей выполнения функциональных моделирующих единиц (FMU) в среде Ubuntu 22.04, используя обертку JavaFmi внутри Docker-контейнера на основе образа Wine. Ошибка, с которой вы сталкиваетесь, указывает на невозможность загрузки библиотеки DLL, что может быть связано как с конфигурацией контейнера, так и с неправильной настройкой путей к библиотекам.
Анализ проблемы
Ошибка java.lang.UnsatisfiedLinkError
говорит о том, что JVM не может найти указанную библиотеку DLL. Это может происходить по нескольким причинам:
- Неверные пути к библиотекам. Путь к библиотеке может быть не корректным в момент исполнения, особенно если имена содержат динамически сгенерированные UUID.
- Проблемы с правами. Убедитесь, что контейнер имеет разрешение на доступ к библиотекам.
- Неправильная конфигурация Wine. Разные версии Wine могут отличаться в поддержке функций и загрузке библиотек.
Рекомендации по решению проблемы
-
Проверка путей к библиотекам:
- Убедитесь, что путь к библиотеке верный. Для этого попробуйте запустить следующий код прямо в контейнере:
ls /tmp/fmu_58a0f513_0f68_4f3e_b420_04f673a1754d/test_FMU/binaries/win64/
- Проверьте, действительно ли ваша библиотека
test_FMU.dll
находится в указанной директории.
- Убедитесь, что путь к библиотеке верный. Для этого попробуйте запустить следующий код прямо в контейнере:
-
Динамическая загрузка с использованием JNA:
- Вам нужно будет динамически формировать путь к DLL, периодически обновляя переменную окружения или параметр запуска.
- Рассмотрите возможность использования wildcards в команде запуска Java для более точного указания пути, например:
-Djna.library.path="/tmp/fmu_*/binaries/win64/"
- Убедитесь, что переменные окружения
JNA_LIBRARY_PATH
заданы корректно и имеют доступ к библиотекам.
-
Настройки Dockerfile:
- В вашем
Dockerfile
вы добавили права для/tmp
, однако в некоторых случаях это может не сработать. Попробуйте более жестко ограничить права на уровне запусков Java. - Также проверьте, корректно ли открываются необходимые порты и службы, использующие DLL.
- В вашем
-
Конфигурация Wine:
- Убедитесь, что вы настроили Wine для работы с 32- или 64-битными библиотеками в зависимости от вашего случая. Попробуйте установить
WINEARCH=win32
и протестировать работу. - Выполните полную конфигурацию Wine:
run winecfg
- Обратите внимание на дополнительные настройки, которые могут быть нужны для работы с конкретными типами библиотек.
- Убедитесь, что вы настроили Wine для работы с 32- или 64-битными библиотеками в зависимости от вашего случая. Попробуйте установить
-
Логи и отладка:
- Включите подробное логирование Wine, установив переменную окружения
WINEDEBUG=+all
для получения более информативных сообщений об ошибках. - Это может предоставить больше информации по поводу загрузки библиотеки и возможных конфликтов.
- Включите подробное логирование Wine, установив переменную окружения
Заключение
С учетом вышесказанного, рекомендуется протестировать каждую из рекомендаций по отдельности, чтобы определить истинную причину проблемы. Надеюсь, предложенные советы помогут вам решить проблему с загрузкой нативных библиотек в вашем проекте. Не забывайте также следить за обновлениями как Wine, так и Java, которые могут содержать исправления и улучшения для вашей среды выполнения.