当前位置: 首页 > 知识库问答 >
问题:

Micronaut DI不适用于Maven内置的Graal Native Image

谢英光
2023-03-14

我在Micronaut上有一个最小的应用程序,它看起来像这样:

@Introspected
public class BookRequestHandler extends MicronautRequestHandler<Book, BookSaved> {

    @Inject
    private BookService service;

    @Override
    public BookSaved execute(Book input) {
        return service.process(input);
    }

}

@Singleton
@Introspected
public class BookService {

  public BookSaved process(Book input) {
    BookSaved bookSaved = new BookSaved();
    bookSaved.setName(input.getName());
    bookSaved.setIsbn(UUID.randomUUID().toString());
    return bookSaved;
  }

}
  • 运行时和DTO类。

我的项目使用Micronaut-的插件在Graal Native Image上成功构建并运行/mvnm

但我试图通过Docker容器直接使用本机映像进行构建。图像正在消失!但如果我尝试调用lambda,我会得到一个错误,即找不到依赖项注入字段:(此文件是从Micronaut的Gradle版本重新制作的:

# STEP 1: Packaging project .jar in Docker image 'builder'
FROM maven:3.6.3-jdk-8 as build

COPY . /home/application
WORKDIR /home/application

RUN mvn clean package

# STEP 2: Downloading Graal and C libraries in Docker image 'graalvm'
FROM amazonlinux:2018.03 as graal

ENV LANG en_US.UTF-8
ENV JDK_VERSION java8
ENV GRAAL_VERSION 21.0.0.2
ENV GRAAL_FILENAME graalvm-ce-${JDK_VERSION}-linux-amd64-${GRAAL_VERSION}.tar.gz

RUN yum install -y gcc gcc-c++ libc6-dev zlib1g-dev curl bash zlib zlib-devel zip
RUN curl -4 -L https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${GRAAL_VERSION}/${GRAAL_FILENAME} -o /tmp/${GRAAL_FILENAME}
RUN tar -zxvf /tmp/${GRAAL_FILENAME} -C /tmp
RUN mv /tmp/graalvm-ce-${JDK_VERSION}-${GRAAL_VERSION} /usr/lib/graalvm
RUN rm -rf /tmp/*

CMD ["/usr/lib/graalvm/bin/native-image"]

# STEP 3: Building and zipping a Native Image with bootstrap file
FROM graal

COPY --from=build /home/application/ /home/application/
WORKDIR /home/application

RUN /usr/lib/graalvm/bin/gu install native-image
RUN /usr/lib/graalvm/bin/native-image --no-fallback --no-server -jar target/MicronautGraal-0.1.jar -H:Name=micronaut-graal -H:Class=com.example.BookLambdaRuntime
RUN chmod 777 bootstrap
RUN chmod 777 micronaut-graal
RUN zip -j micronaut-graal.zip bootstrap micronaut-graal

EXPOSE 8080
ENTRYPOINT ["/home/application/complete"]

错误本身:

io.micronaut.context.exceptions.DependencyInjectionException: Failed to inject value for field [service] of class: com.example.BookRequestHandler
Message: Error setting field value: No field 'service' found for type: com.example.BookRequestHandler

我确信问题不在代码中,因为它将在整个过程中运行和工作/mvnm插件。我是不是在应用程序构建中遗漏了什么?我通过插件获得的图像比直接通过本机图像获得的图像多500kb。

我真的很感激任何帮助。谢谢

共有3个答案

安承教
2023-03-14

使用应该考虑通过构造函数进行注入,这是GraalVM本地应用程序推荐的方式。

@Introspected
public class BookRequestHandler extends MicronautRequestHandler<Book, BookSaved> {

    private final BookService service;

    @Inject
    public BookRequestHandler(BookService service) {
      this.service = service;
    }

    @Override
    public BookSaved execute(Book input) {
        return service.process(input);
    }
}
阮才俊
2023-03-14

在添加注释处理器路径-graal并在继承器中显式声明验证和注入后,问题消失了:

<annotationProcessorPaths>
  <path>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-graal</artifactId>
    <version>${micronaut.version}</version>
  </path>
  <path>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-inject-java</artifactId>
    <version>${micronaut.version}</version>
  </path>
  <path>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-validation</artifactId>
    <version>${micronaut.version}</version>
  </path>
</annotationProcessorPaths>
孟花蜂
2023-03-14

JVM的一个限制是,我们不能在不使用反射的情况下注入私有字段。

你有两个选择:

  1. 将字段包设置为私有而不是私有
 类似资料:
  • 当我运行mvn pmd:check并将JAVA_HOME设置为jdk 1.8时,这运行平稳。当我将jdk切换到1.7时,我得到以下异常。PMD支持1.7,所以不确定为什么我得到这个错误。 原因:org.apache.maven.plugin.PluginContainerException:执行org.apache.maven.plugins时遇到API不兼容:maven-pmd-plugin:

  • 在我的项目中添加kongchen swagger-maven-plugin(版本3.1.0)后,log4j停止工作。我们正在使用Spring(版本4.1.5)和slf4j(版本1.7.5)如果我在pom.xml中注释掉kongchen插件依赖,log4j再次开始工作。你能帮忙吗?谢谢! 这是我的pom的内容。xml `http://maven.apache.org/maven-v4_0_0.xsd

  • 问题内容: 嗨,我只是简单地尝试在www.example.com上获取h1标签,该标签显示为“ Example Domain”。该代码适用于http://www.example.com,但不适用于https://www.exmaple.com。我该如何解决这个问题?谢谢 问题答案: PhantomJSDriver不支持(所有)DesiredCapabilities。 你会需要: 记录在这里:htt

  • 所以我使用这种方法写入文件,它在windows上运行完全正常,但在mac上运行时,它会创建文件,但它们是空的。 我知道数据是正确的,因为它打印正确。感谢您的任何帮助,这真的让我绊倒了。

  • 我试图初始化log4j记录器使用SpringIOC和使用财产onfigurator.configure配置记录器,但财产onfigurator.configure不工作。 我的问题是如何将配置(log4j.properties)传递给Logger类? 波姆。xml 混淆班 log4j。性质

  • 问题内容: 我想在单词中镜像字母,所以我使用了CSS变换属性,但是如果我将文本包裹在一个范围内则无法使用,但是如果我选择了ass或 那么转换不适用于内联元素吗? 示例1(转换失败) 示例2(Works,如果使用OR) 问题答案: 在官方W3规范中,在可转换元素下回答: 一个元素,其布局由CSS框模型控制,该CSS框模型可以是 块级 或 原子内联级元素 ,或者其“ display”属性可以计算为“