java.lang.UnsatisfiedLinkError: 'int org.gdal.gdalconst.gdalconstJNI.GDT_Int8_get()' 在 docker 中使用 org.gdal 和 osgeo/gdal 时

问题描述 投票:0回答:1

我想容器化一个 SpringBoot 应用程序并使用 gdal。 为此,我在我的 pom.xml

中使用
<dependency>
        <groupId>org.gdal</groupId>
        <artifactId>gdal</artifactId>
        <version>3.8.0</version>
</dependency>

FROM osgeo/gdal:ubuntu-full-3.6.3

Dockerfile中。

但是看起来 org.gdal 引用了一个不存在的常量。我稍后会描述它。但首先是源代码的关键部分:

Dockerfile

FROM maven:3.9.5-amazoncorretto-21 as build

WORKDIR /app
COPY target/converter-service-1.0.0-SNAPSHOT.jar app.jar

RUN mkdir -p target/extracted
RUN java -Djarmode=layertools -jar app.jar extract --destination target/extracted

FROM osgeo/gdal:ubuntu-full-3.6.3

ENV GDAL_DATA="/usr/share/gdal"
ENV GDAL_DRIVER_PATH="/usr/lib/x86_64-linux-gnu/gdalplugins"
ENV PROJ_LIB="/usr/share/proj"
ENV PATH="/usr/share/gdal:${PATH}"

WORKDIR app
RUN apt update && apt install -y openjdk-21-jre-headless
ARG EXTRACTED=/app/target/extracted
COPY --from=build ${EXTRACTED}/dependencies/ ./
COPY --from=build ${EXTRACTED}/spring-boot-loader/ ./
COPY --from=build ${EXTRACTED}/snapshot-dependencies/ ./
COPY --from=build ${EXTRACTED}/application/ ./
ENTRYPOINT ["java", "-Djava.library.path=/usr/share/java/", "org.springframework.boot.loader.launch.JarLauncher" ]

Java代码

package my;
import org.springframework.stereotype.Service;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
...

@Service
public class Grib2ToGeoTiffService {

    static {
        gdal.AllRegister();
    }

    @PostConstruct
    private void postConstruct() {
            convert(
                    ResourceUtils.getFile("classpath:file.grib2"),
                    new File("/tmp/output")
            );

        }

    public boolean convert(File gribFile, File geotiffOutputDir) throws Exception {
        if (!gribFile.exists()) {
            log.error("File does not exist: '{}'", gribFile.getAbsolutePath());
            return false;
        }

        var gribType = getGribType(gribFile.getName());
        log.info("Grib type '{}' for '{}'", gribType, gribFile.getName());

        Dataset dataset = gdal.Open(gribFile.getAbsolutePath(), gdalconstConstants.GA_ReadOnly);
        if (dataset == null) {
            log.warn("Unable to open file: " + gribFile.getAbsolutePath());
            return false;
        }

        int bandCount = dataset.getRasterCount();
        Map<String, Settings> settingsMap = getSettingsMap(gribType);

        for (int bandId = 1; bandId <= bandCount; bandId++) {
            if (settingsMap.containsKey(Integer.toString(bandId))) {
                processBand(dataset, bandId, geotiffOutputDir, gribType, settingsMap);
            }
        }

        dataset.delete();

        return true;
    }

}

应用程序在容器中运行后出现以下错误:

Caused by: java.lang.UnsatisfiedLinkError: 'int org.gdal.gdalconst.gdalconstJNI.GDT_Int8_get()'
        at org.gdal.gdalconst.gdalconstJNI.GDT_Int8_get(Native Method) ~[gdal-3.8.0.jar:na]
        at org.gdal.gdalconst.gdalconstConstants.<clinit>(gdalconstConstants.java:14) ~[gdal-3.8.0.jar:na]
        at my.service.Grib2ToGeoTiffService.convert(Grib2ToGeoTiffService.java:121) ~[classes/:1.0.0-SNAPSHOT]
...

代码中对应的行是:

Dataset dataset = gdal.Open(gribFile.getAbsolutePath(), gdalconstConstants.GA_ReadOnly);

我从正在运行的容器中导出了gdal.h,但找不到常量。 以下是该文件的摘录,其中定义了常量:

...
/*! Pixel data types */
typedef enum
{
    /*! Unknown or unspecified type */ GDT_Unknown = 0,
    /*! Eight bit unsigned integer */ GDT_Byte = 1,
    /*! Sixteen bit unsigned integer */ GDT_UInt16 = 2,
    /*! Sixteen bit signed integer */ GDT_Int16 = 3,
    /*! Thirty two bit unsigned integer */ GDT_UInt32 = 4,
    /*! Thirty two bit signed integer */ GDT_Int32 = 5,
    /*! 64 bit unsigned integer (GDAL >= 3.5)*/ GDT_UInt64 = 12,
    /*! 64 bit signed integer  (GDAL >= 3.5)*/ GDT_Int64 = 13,
    /*! Thirty two bit floating point */ GDT_Float32 = 6,
    /*! Sixty four bit floating point */ GDT_Float64 = 7,
    /*! Complex Int16 */ GDT_CInt16 = 8,
    /*! Complex Int32 */ GDT_CInt32 = 9,
    /* TODO?(#6879): GDT_CInt64 */
    /*! Complex Float32 */ GDT_CFloat32 = 10,
    /*! Complex Float64 */ GDT_CFloat64 = 11,
    GDT_TypeCount = 14 /* maximum type # + 1 */
} GDALDataType;
...

导致错误的原因是什么?也许

<dependency>
        <groupId>org.gdal</groupId>
        <artifactId>gdal</artifactId>
        <version>3.8.0</version>
</dependency>

FROM osgeo/gdal:ubuntu-full-3.6.3

不兼容还是我做错了什么?

java spring-boot dockerfile gdal
1个回答
0
投票

在互联网上进行一些研究后,我发现了讨论: https://openradar.discourse.group/t/attributeerror-module-osgeo-gdalconst-has-no-attribute-gdt-int8/333

该常量似乎出现在3.7版本中

所以我将 JNI 库降级为:

<dependency>
        <groupId>org.gdal</groupId>
        <artifactId>gdal</artifactId>
        <version>3.6.0</version>
</dependency>

有问题的java代码此后开始工作。

© www.soinside.com 2019 - 2024. All rights reserved.