首页 文章

在阴影jar中使用log4j的问题

提问于
浏览
5

我的项目中有以下情况:

  • 一个具有自己的依赖关系的大模块(称为转换器)正在被集成到主应用程序中(由不同的人单独开发并具有自己的,部分重叠的依赖关系);

  • 最初这个转换器模块可以从命令行调用为可执行jar,因此它有自己的入口点(定义了main()方法的runnable类);这个可执行的jar总是通过maven shade插件创建为超级jar;

  • 现在这个转换器模块必须可以从主应用程序中另外调用(为此,我现在在形成命令行参数后直接调用入口点类的main()) . 主应用程序也被创建为超级jar,并计划继续以这种方式创建 .

在这种情况下,我将使用shade插件实现依赖关系的正确分离,为此,我已将以下重定位规范添加到转换器模块的pom.xml中:

<relocations>
<relocation>
<pattern>com</pattern>
  <shadedPattern>quase.com</shadedPattern>
</relocation>
<!-- ... other top-level patterns for converter dependencies -->
<relocation>
  <pattern>org</pattern>
  <shadedPattern>quase.org</shadedPattern>
  <excludes>
    <exclude>org.aau.**</exclude> <!-- my own code for converter is not shaded -->
  </excludes>
</relocation>
</relocations>

因此,转换器模块的所有依赖关系都被加上阴影(对它们进行预先设定),同时组合到主应用程序的超级jar中 .

此配置的问题是应用程序和转换器都使用日志记录(slf4j和log4j),并且从应用程序代码调用转换器方法并开始使用日志记录后,会发生以下错误:

log4j:ERROR A "org.apache.log4j.FileAppender" object is not assignable to a "quase.org.apache.log4j.Appender" variable.
log4j:ERROR The class "quase.org.apache.log4j.Appender" was loaded by
log4j:ERROR [sun.misc.Launcher$AppClassLoader@55f96302] whereas object of type
log4j:ERROR "org.apache.log4j.FileAppender" was loaded by [sun.misc.Launcher$AppClassLoader@55f96302].
log4j:ERROR Could not instantiate appender named "file1".
log4j:ERROR A "org.apache.log4j.FileAppender" object is not assignable to a "quase.org.apache.log4j.Appender" variable.
log4j:ERROR The class "quase.org.apache.log4j.Appender" was loaded by
log4j:ERROR [sun.misc.Launcher$AppClassLoader@55f96302] whereas object of type
log4j:ERROR "org.apache.log4j.FileAppender" was loaded by [sun.misc.Launcher$AppClassLoader@55f96302].
log4j:ERROR Could not instantiate appender named "file2".
log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "quase.org.apache.log4j.Appender" variable.
log4j:ERROR The class "quase.org.apache.log4j.Appender" was loaded by
log4j:ERROR [sun.misc.Launcher$AppClassLoader@55f96302] whereas object of type
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [sun.misc.Launcher$AppClassLoader@55f96302].
log4j:ERROR Could not instantiate appender named "console".
log4j:WARN No appenders could be found for logger (org.aau.quase.quontology.builder.QuLogHandler).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

因此在我看来,从转换器模块调用的着色日志记录代码获取对已在主应用程序中初始化的非着色日志记录代码的引用,并且因为它需要着色代码而失败(请参阅无法将非着色 org.apache.log4j.FileAppender 分配给着色 quase.org.apache.log4j.Appender ) .

我试图在转换器的pom.xml中从着色中排除日志记录依赖项:

<excludes>
    <exclude>org.aau.**</exclude>
    <exclude>org.apache.log4j.**</exclude>
    <exclude>org.slf4j.**</exclude>
</excludes>

但这导致了进一步的问题:整个应用程序失败如下:

Exception in thread "main" java.lang.NoClassDefFoundError
        at org.apache.log4j.Category.class$(Category.java:118)
        at org.apache.log4j.Category.<clinit>(Category.java:118)
        at org.apache.log4j.LogManager.<clinit>(LogManager.java:82)
        at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:66)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:277)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:288)
        at org.aau.quase.application.LoggingProtocolHandler.<clinit>(LoggingProtocolHandler.java:16)
        at org.aau.quase.application.QuASEApplication$1.<init>(QuASEApplication.java:71)
        at org.aau.quase.application.QuASEApplication.<init>(QuASEApplication.java:65)
        at org.aau.quase.application.util.QuASERunner.main(QuASERunner.java:8)
Caused by: java.lang.ClassNotFoundException: quase/org.apache.log4j.Category
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        ... 10 more

看起来转换器代码仍然需要阴影版本,因为它无法找到 quase/org.apache.log4j.Category 并且quase是着色前缀 .

我究竟做错了什么?任何帮助是极大的赞赏 .

1 回答

  • 0

    我们遇到了同样的问题,我们通过从根本身排除log4j而不是重新定位它来修复它 .

    <configuration>
                                    <filters>
                                        <filter>
                                            <artifact>groupId:artifactId:*</artifact>
                                            <excludes><exclude>org/apache/log4j/**</exclude></excludes>
                                        </filter>
                                    </filters>
    
                                    <relocations>
                                        <relocation>
                                            <pattern>com</pattern>
                                            <shadedPattern>xyz.shaded.com</shadedPattern>
                                        </relocation>
                                    </relocations>
                                </configuration>
    

相关问题