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

GraalVM本机映像生成找不到log4j appender类

微生博简
2023-03-14

我正在尝试将我的. jar项目转换为本地映像,因为我需要在不支持Java的设备中运行它。为此,我安装了GraalVM和所有必需的依赖项,本地映像构建工作完美(或者至少看起来是这样,因为它在过程中不会产生任何错误)。

我用于构建的命令是:

/usr/lib/jvm/graalvm/bin/native image-jar-MyApp。jar MyApp——启用http——启用https——无回退——H:ReportExceptionStackTraces

问题是,当我试图运行本机文件时,我得到一个异常,说找不到log4j类,因此我在执行过程中没有应用程序日志:

log4j:ERROR Could not instantiate class [org.apache.log4j.RollingFileAppender].
java.lang.ClassNotFoundException: org.apache.log4j.RollingFileAppender
        at java.lang.Class.forName(DynamicHub.java:1338)
        at java.lang.Class.forName(DynamicHub.java:1313)
        at org.apache.log4j.helpers.Loader.loadClass(Loader.java:198)
        at org.apache.log4j.helpers.OptionConverter.instantiateByClassName(OptionConverter.java:327)
        at org.apache.log4j.helpers.OptionConverter.instantiateByKey(OptionConverter.java:124)
        at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:785)
        at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:768)
        at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:648)
        at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:514)
        at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:580)
        at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:526)
        at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)
        at org.slf4j.impl.Log4jLoggerFactory.<init>(Log4jLoggerFactory.java:66)
        at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
        at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
        at com.test.MyApp.<clinit>(MyApp.java:40)
log4j:ERROR Could not instantiate appender named "file".
log4j:WARN No appenders could be found for logger (com.test.MyApp).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

当我运行程序时。jar通过java-jar,它工作得很好。提取jar后,我可以看到其中的所有log4j文件,包括给出错误的RollingFileAppender类(这是一个着色jar)。问题不仅在于RollingFileAppender,如果我尝试使用另一个不同的appender,另一个类仍然会出现相同的错误。所以我就是搞不清楚这个版本到底出了什么问题。

以下是我的pom.xml文件中的所有依赖项:

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>       
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.0.19.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
            <version>3.0.19.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-client</artifactId>
            <version>3.0.19.Final</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        (These last 2 were not in the original project, I tried adding them to see if it'd help but nothing changed, still get the same error)
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>apache-log4j-extras</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

以及我的maven shade插件配置:

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.4</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
              </execution>
            </executions>
          </plugin>

任何关于这件事的线索都会非常感激,我已经努力解决这个问题好几天了,但没有运气。

提前谢谢!

共有1个答案

葛念
2023-03-14

有趣的是,在发布这个问题后不久,我找到了答案。这与GraalVM的反射配置有关。修复实际上很简单:

首先,使用特殊的GraalVM选项运行jar:

<GRAALVM_HOME>/bin/java -agentlib:native-image-agent=config-output-dir=<DIRECTORY_YOU_WANT_THE_FILES_TO_BE_GERERATED_AT> -jar <JAR_FILE>.jar

这将产生一系列的影响。有助于配置GraalVM本机映像构建的json文件:

jni-config.json
predefined-classes-config.json
proxy-config.json
reflect-config.json
resource-config.json
serialization-config.json

一旦有了这些文件,就可以执行生成,并将其作为参数传递:

<GRAALVM_HOME>/bin/native-image -jar <JAR_FILE>.jar <NATIVE_IMAGE_NAME> -H:ConfigurationFileDirectories=<DIRECTORY_WHERE_YOUR_JSON_FILES_ARE_AT>

就这样!一旦构建完成,本机映像就可以完美地运行,没有任何问题,所有日志都按预期工作。

如果需要,还可以添加。json文件到META-INF/本机映像目录,可从类路径访问,例如在src/main/resources目录中。这样,在调用本机映像构建时,不需要将目录作为参数传递。

所有这些有用信息的来源是:https://simply-how.com/fix-graalvm-native-image-compilation-issues

我希望这能帮助其他人解决同样的问题:)

 类似资料:
  • 失败:生成失败,出现异常。 错误:执行任务“:QuarkusBuild”失败。Io.Quarkus.Builder.BuildException:生成失败:由于错误导致生成失败[error]:生成步骤Io.Quarkus.Deployment.Pkg.Steps.NativeImageBuildStep#Build引发异常:java.lang.RuntimeException:未能在io.Quar

  • 我有一些Java应用程序和一个客户,他们有一些UWP应用程序,用C#实现,通过Windows商店等分发,他们想使用我的应用程序的一些部分。这些部分完全独立于操作系统,只解析一些特殊的二进制文件格式,应用一些使用YAML文件和东西配置的业务逻辑。没有网络、GUI,只有一些文件访问等。 我们目前使用IKVM使C#可以使用感兴趣的代码,但已经遇到了不同的问题。有些支持.NET核心,有些与发行版中的本机工

  • 我正在尝试用GraalVM创建一个本地映像,我的代码是: 然后我把代码本身称为: 当我运行IDE或java-jar时,它可以正常工作,但当我尝试编译为本机映像时,会抛出一个错误。下面是用于编译本机映像的命令行。 错误: TypeError:invokeMember(打印)在JavaObject[com.compiler.commons.log]上。Console@113a2d320(com.com

  • 我无法在Catalina 10.15.2中运行命令: 它向我返回以下消息: 我试过跑步 哪里 没有运气。我无法运行该命令,因此无法成功运行该命令 mvn安装-Pnative。 [pastebin][1] 我已经读过这个[帖子][2],对我来说不起作用。 救命啊求你了 更新 好的,我已经应用了建议,现在我可以创建native-image,但是当我尝试运行mvn install-P本国时,我遇到了一个

  • 我正在尝试用Dockers创建一个GraalVM本地映像。我已经创建了一个Micronaut项目,并成功创建了jar应用程序,并在docker中运行;此外,我已经用这个jar文件创建了一个GraalVM本机映像,现在可以运行这个应用程序,但我需要在docker中运行一个GraalVM本机映像,在论坛中寻找答案。我发现有必要在docker中构建本机映像。因此我尝试了这个docker文件: 它不会抛出

  • 我在这里将Micronaut应用程序作为Graalvm本地映像进行试用。