Quarkus - uber jar 中不包含依赖项 - JVM 模式

Quarkus - Dependencies not included in uber jar - JVM mode

我有一个使用“amazon-lambda、resteasy、jackson. 和 gson”库创建的 quarkus 项目。我有一个实现 RequestStreamHandler 的 StreamLambdaHandler。我是运行JVM模式下的应用

我在 application.properties 中添加了以下 属性:

quarkus.package.uber-jar=true

我正在使用名为 code-with-quarkus-1-runner.jar 的薄 jar

从 API 网关发送 JSON POST 请求给出以下异常。请让我知道可能是什么问题。

Error loading class org.test.StreamLambdaHandler: com/google/gson/JsonElement:
java.lang.NoClassDefFoundError
java.lang.NoClassDefFoundError: com/google/gson/JsonElement
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.google.gson.JsonElement. Current
classpath: file:/var/task/

预期行为 gson 库应该已经复制到 uber jar 中并且不应该抛出任何异常

实际行为: 从 API 网关发送 JSON POST 请求会出现以下异常。请让我知道可能是什么问题。

Error loading class org.test.StreamLambdaHandler: com/google/gson/JsonElement:
java.lang.NoClassDefFoundError
java.lang.NoClassDefFoundError: com/google/gson/JsonElement
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.google.gson.JsonElement
Current classpath: file:/var/task/

下面是我的 pom.xml 文件:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.acme</groupId>
  <artifactId>code-with-quarkus</artifactId>
  <version>1</version>
  <properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>2.0.2.Final</quarkus.platform.version>
    <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
    <quarkus.package.type>uber-jar</quarkus.package.type>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-amazon-lambda</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <parameters>${maven.compiler.parameters}</parameters>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemPropertyVariables>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemPropertyVariables>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <maven.home>${maven.home}</maven.home>
                  </systemPropertyVariables>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
      </properties>
    </profile>
  </profiles>
</project>

此外,请在下面找到 RequestStreamHandler class 代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.google.gson.JsonObject;

public class StreamLambdaHandler implements RequestStreamHandler {
    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        JsonObject responseJson = new JsonObject();
        JsonObject responseBody = new JsonObject();
        responseBody.addProperty("message", "New item created");
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
        writer.write(responseJson.toString());
        writer.close();
    }
}

我不确定你的项目设置,但你是否像这样引用了所有资源:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/application.properties</include>
        </includes>
    </resource>
</resources>

如果您有其他资源,您将添加额外的 资源

假设您正在尝试 运行 原生图像,似乎在构建时删除了 gson 依赖项。

负责 quarkus 本机的 GraalVM 在构建时构建 运行 应用程序并删除它认为在代码中未使用的所有内容。这样生成的图像在大小和启动时间上都可以更轻。

这样做的缺点是 'weeds out' 整个库甚至 类 中的方法似乎都没有被使用。不包含 jandex 索引的第三方库通常就是这种情况。

many ways to overcome this个。但最好的方法是使用库的 quarkus 风格版本(如果可用)。

貌似Quarkus项目偏向Jackson和JsonB,不过Gson有个quarkus-camel版本。尝试用这个替换你的 gson 依赖: https://camel.apache.org/camel-quarkus/latest/reference/extensions/gson.html

<dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-gson</artifactId>
</dependency>

问题出在添加 quarkus-amazon-lambda 依赖项时 Quarkus 构建 fat/uber jar 的方式。添加此依赖项后,即使我们明确要求它使用应用程序属性 (quarkus.package.type=uber-jar) 并使用 ./mvnw package -Dquarkus.package.type=uber-jar 命令创建,也不会创建 fat jar .

在这些情况下创建 lambda 函数的唯一方法似乎是上传 function.zip 在构建过程中创建的文件或使用本机图像。没有 fat jar 选项。

我不确定这是否是一个错误,我会在 Quarkus github 社区中提出它。

Zip 文件添加了所有需要的依赖项,但比我预期的要大得多。