2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面,了解更多关于此如何工作的信息。

0
Leiningen

大家好!

我在使用lein创建jar文件时遇到了一个奇怪的问题。我向项目中添加了一个新的log4j-layout-template-json,并使用org.clojure/tools.logging添加了一个用于记录的JSON模板。当我本地运行时一切正常,但当我尝试从jar文件运行项目时,我不断地收到这个错误。

ERROR StatusConsoleListener Unable to locate plugin type for JsonTemplateLayout
ERROR StatusConsoleListener Unable to locate plugin for JsonTemplateLayout
ERROR StatusConsoleListener Could not create plugin of type class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console: java.lang.NullPointerException: Cannot invoke "org.apache.logging.log4j.core.config.plugins.util.PluginType.getElementName()" because "childType" is null
 java.lang.NullPointerException: Cannot invoke "org.apache.logging.log4j.core.config.plugins.util.PluginType.getElementName()" because "childType" is null
    at org.apache.logging.log4j.core.config.plugins.visitors.PluginElementVisitor.findNamedNode(PluginElementVisitor.java:104)

所以项目无法看到log4j-layout-template-json,我能通过替换/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat文件来制作一个可工作的jar文件,这个文件来自插件本身,所以看起来这个文件被覆盖了,lein无法理解这种Java插件模式。
问题是,有没有一种方法可以用Lein来自动化此过程,或者迁移到deps能否解决问题,谢谢!
project.clj文件

(defproject aa "aa"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.11.3"]
                 [org.clojure/tools.logging "1.2.4"]
                 [org.clojure/tools.cli "0.3.1"]
                 [org.clojure/core.async "1.3.610"]
                 [clj-commons/clj-yaml "1.0.26"]
                 [com.google.guava/guava "31.1-jre"]    
                 [io.netty/netty-all "4.1.107.Final"]
                 [org.clojure/core.match "1.0.1"]
                 [com.github.ben-manes.caffeine/caffeine "3.1.8"]
                 ;;;; Logging
                 [org.apache.logging.log4j/log4j-slf4j-impl "2.20.0"] ;; libraries using SLF4J won't complain
                 [org.apache.logging.log4j/log4j-api "2.20.0"]
                 [org.apache.logging.log4j/log4j-core "2.20.0"]
                 [org.apache.logging.log4j/log4j-layout-template-json "2.20.0"]]

  :jvm-opts ["-Dlog4j2.configurationFile=resources/log4j2.properties"
             "-Dlog4j2.garbagefreeThreadContextMap=true"
             "-Dclojure.tools.logging.factory=clojure.tools.logging.impl/log4j2-factory"]

  :test-selectors {:default (complement :integration)
                   :integration :integration}

  :main ^:skip-aot aa.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})

使用这个https://github.com/arctype-co/log4j2-plugins-cache插件暂时解决了问题,但我想知道是否有不包含新插件的解决方案。

1 个答案

0

如果你依赖于多个库,每个库都有自己的插件缓存(.dat文件),你需要在构建过程中合并这些文件——这正是log4j2-plugins-cache插件的作用,与Leiningen一起使用。

在log4j 3.x版本中,他们计划取消这个缓存文件,并使用一种更适合构建工具、不需要这种自定义合并的方法。

我不得不为tools.build / build.clj编写一些类似的东西,以便结合Clojure CLI使用:[https://github.com/seancorfield/build-uber-log4j2-handler](https://github.com/seancorfield/build-uber-log4j2-handler)

...