java - Azure 应用服务中的错误 : java. lang.UnsatisfiedLinkError: failed to load the required native library

标签 java linux spring maven ssl

我有一个 Spring Boot 应用程序,我想将其作为 war 部署到 Azure 应用程序服务。
Spring Boot 应用程序具有 REST API。应用服务配置如下:

  • 操作系统:Linux
  • 发布:代码
  • 运行时堆栈:Tomcat 9

  • 我的 pom.xml 看起来像这样:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>sdk-hlf</groupId>
        <artifactId>sdk-hlf-1.4.4</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <tomcat.version>9.0.20</tomcat.version>
            <start-class>com.example.app.MainClass</start-class> <!-- edited for security reasons -->
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>org.hyperledger.fabric</groupId>
                <artifactId>fabric-gateway-java</artifactId>
                <version>1.4.4</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>demo</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>repackage</id>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                            <configuration>
                                <finalName>demo</finalName>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    
    当我在笔记本电脑上运行该应用程序时,它运行良好。
    但是在将应用程序部署到 Azure 后会出现问题。它已成功部署,但是当我点击我的应用程序的 API 时,我收到以下错误:
    {
        "timestamp": "2020-09-12T15:06:06.732+00:00",
        "status": 500,
        "error": "Internal Server Error",
        "message": "",
        "path": "/api/get" //edited for security reasons
    }
    
    以下是部分日志:
    2020-09-12T15:35:31.508024047Z: [INFO]
    2020-09-12T15:35:31.508053247Z: [INFO]  java.lang.UnsatisfiedLinkError: failed to load the required native library
    2020-09-12T15:35:31.508057547Z: [INFO]          at io.netty.handler.ssl.OpenSsl.ensureAvailability(OpenSsl.java:474) ~[netty-handler-4.1.49
    .Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508080348Z: [INFO]          at io.netty.handler.ssl.ReferenceCountedOpenSslContext.<init>(ReferenceCountedOpenSslContex
    t.java:196) ~[netty-handler-4.1.49.Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508084948Z: [INFO]          at io.netty.handler.ssl.ReferenceCountedOpenSslContext.<init>(ReferenceCountedOpenSslContex
    t.java:185) ~[netty-handler-4.1.49.Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508089148Z: [INFO]          at io.netty.handler.ssl.OpenSslContext.<init>(OpenSslContext.java:34) ~[netty-handler-4.1.4
    9.Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508093148Z: [INFO]          at io.netty.handler.ssl.OpenSslClientContext.<init>(OpenSslClientContext.java:189) ~[netty-
    handler-4.1.49.Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508097248Z: [INFO]          at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:827) ~[netty-ha
    ndler-4.1.49.Final.jar:4.1.49.Final]
    2020-09-12T15:35:31.508101248Z: [INFO]          at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:576) ~[netty-handler
    -4.1.49.Final.jar:4.1.49.Final]
    
    我不知道这里有什么问题?

    最佳答案

    我发现了这个问题,“fabric gateway”取决于“无聊的 ssl”,而“无聊的 ssl”取决于 Windows 的 DLL 文件和 Linux 的 SO 文件。在我的依赖项列表中,我看到 SO 和 DLL 文件都打包在“netty-tcnative-boringssl-static-2.0.26.Final.jar\META-INF\native”文件夹中。该文件夹有以下文件。

    libnetty_tcnative_linux_x86_64.so libnetty_tcnative_osx_x86_64.jnilib netty_tcnative_windows_x86_64.dll


    JVM 应该从 META-INF/native 文件夹中选择必要的 native 文件(DLL 或基于主机操作系统的 SO 文件),但仅在 Windows 的情况下选择,而不是在 linux 的情况下选择。因此,为此,我从 jar 中提取了 SO 文件,将其放在 Linux 机器上的一个文件夹中,并使用 System.load 如下所示“加载”了 SO 文件。这已经解决了这个问题。
    static{
        try{
            String path="/apps/config/libnetty_tcnative_linux_x86_64.so";
            Path path = Paths.get(path);
    
            if (Files.exists(path)) {
                System.load(path);
                System.out.println("Native library loaded successfully");
            }
        }catch (Throwable e){
            System.out.println("Native library load failed");
            e.printStackTrace();
        }
    }
    
    加载类时首先加载静态 block ,因此,我在“入口点”Java 类中包含了上面的静态 block ,以确保在加载任何 Java 类之前加载 SO 文件。
    现在,应该包含的“无聊的 ssl jar”基于您的主机操作系统,请阅读以下文档,了解如何在 pom.xml 中指定内容以包含适当的 JAR。如果相应的 JAR 的本地库(SO 或 DLL)未加载并导致链接错误,则如上所述“加载”。
    https://netty.io/wiki/forked-tomcat-native.html

    关于java - Azure 应用服务中的错误 : java. lang.UnsatisfiedLinkError: failed to load the required native library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63862083/

    相关文章:

    java - 如何捕获异常并在 Java 中继续处理

    java - 结束Java Socket的客户端连接

    java - Spring - 使用属性占位符加载位于 war 文件或类路径之外但位于文件系统中的属性文件

    java - 如何添加额外的自定义 header ,同时抛出异常以将消息存储在 kafka 上的 dlq 中?

    java - 如何保存位图并从缓存中共享?

    linux - grep 或 awk 切割 2 条不同的线

    无法为 enp4s0 上的套接字设置 SO_BINDTODEVICE

    python - 如何在 Linux 启动时自动运行 python 脚本

    java - 使用 Spring 在 weblogic 中的服务器启动时启动线程

    java - 处理 JAR 和开发中的资源文件路径