【问题标题】:Where to place slf4j api and implementation in a multi module Java EE project?在多模块 Java EE 项目中将 slf4j api 和实现放在哪里?
【发布时间】:2018-06-16 00:46:11
【问题描述】:

我知道由于 (Maven) 依赖管理而导致类路径上的 slf4j 实现丢失或重复的原因,并且知道如何通过排除来避免这种情况。

但是,如果我有一个多模块 Java 项目,其中包含一个包含 EJB 接口和实体的 JAR、一个 EJB 实现和一个打包为 EAR 的 WAR Web 前端,我找不到放置 slf4j API org.slf4j:slf4j-api:1.7.25 的方法,实现ch.qos.logback:logback-classic:1.2.3 和配置logback.xml,这样我就可以在JAR、EJB 和WEB 模块中进行日志记录,并且可以避免both

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/richter/zpool-tmp/jee-slf4j-logging/jee-slf4j-logging-ear/target/gfdeploy/jee-slf4j-logging-ear/jee-slf4j-logging-web-1.0-SNAPSHOT_war/WEB-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/richter/zpool-tmp/jee-slf4j-logging/jee-slf4j-logging-ear/target/gfdeploy/jee-slf4j-logging-ear/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/glassfish/web/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/glassfish/javaee/full/deployment/EarLibClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:418)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)

我在 https://gitlab.com/krichter/jee-slf4j-logging 提供 MCVE。

GlassFish 4, no logging framework dependencies is working in pom.xml 未涵盖 Java EE 方面。

【问题讨论】:

  • 请注意,日志记录直接访问文件系统,这在完全兼容的应用程序中是不允许的。你可以考虑使用 slf4j 去 java.util.logging 我知道的所有 servlet 容器集中捕获和记录
  • 最简单的方法是将所有内容都放在您的 WAR 文件中并进行部署。在正确的位置(甚至使用 Maven)构建正确的 EAR 文件和所有相关的 jar 文件是一件棘手的事情,需要一些时间来解释
  • @SteveC 我知道 WAR 相对于 EAR 打包的优势。我已经体验到能够为 Java EE 开发不同的 Web 客户端并尽可能实现最清晰的分离的优势。所以,我想保留多模块结构。
  • 可以尝试查看maven有效pom并搜索重复依赖。也许对你有帮助:stackoverflow.com/questions/15985337/…blog.jetbrains.com/idea/2010/05/maven-dependencies-diagram
  • 我在stackoverflow.com/questions/41306341/… 的回答将解释为什么必须将这些jar 放在EAR/lib 目录中。这也意味着您的配置必须在 EAR/lib 目录中的 jar 中或通过系统属性指定,例如 -Dlogback.configurationFile=/path/to/config.xml

标签: java maven jakarta-ee logback slf4j


【解决方案1】:

我最终做了以下事情:

  1. 直接在 EAR 文件夹下创建一个新文件夹。例如,创建 一个名为“conf”的新文件夹 --> EAR/conf

  2. 将您的 logback.xml 文件放在这个新文件夹中: EAR/conf/logback.xml

  3. 在 WAR/EJB/API 文件的 MANIFEST.MF 文件中,将此新文件夹添加到 类路径:

Class-Path: conf

如果您使用 maven 在 web、ejb 和 ejb 接口等模块中构建项目,请在提供的范围内向 slf4j-api 添加依赖项:

WEB, EJB, API modules
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>${slf4j.version}</version>
  <scope>provided</scope>
</dependency>

并在您的 EAR 模块中添加对 slf4j-api 和 logback-classic 和 logback-core 的依赖项:

EAR modeule
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>${slf4j.version}</version>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>${logback.version}</version>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>${logback.version}</version>
</dependency>

要将 conf 定义为模块中的 Class-Path,请在 maven-war-plugin、maven-jar-plugin 和 maven-ejb-plugin 中使用以下行

WEB, EJB, API modules
<configuration>
  <archive>
    <addMavenDescriptor>false</addMavenDescriptor>
    <manifest>
      <addClasspath>true</addClasspath>
    </manifest>
    <manifestEntries>
      <Class-Path>logback</Class-Path>
    </manifestEntries>
  </archive>
...

【讨论】:

    猜你喜欢
    • 2014-08-18
    • 2010-12-06
    • 2013-07-23
    • 2022-01-06
    • 2011-10-05
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多