【问题标题】:How to resolve LinkageError with JasperReports (6.*)?如何使用 JasperReports (6.*) 解决 LinkageError?
【发布时间】:2015-07-30 09:16:08
【问题描述】:

例如我们得到了:

net.sf.jasperreports.engine.JRException: ...
Caused by: net.sf.jasperreports.engine.fill.JRExpressionEvalException: 
  Error evaluating expression for source text: 
    $P{REPORT_SCRIPTLET}.setTestRaw_LogOn_TstMsgOn(true, true)
Caused by: java.lang.LinkageError: loader constraint violation: loader 
  (instance of java/net/FactoryURLClassLoader) previously initiated loading 
  for a different type with name "org/slf4j/Logger"

Eclipse (Kepler) Preview 中使用 JR 插件 v6.1.0 运行,但不能在另一个运行 5.5.1.final 的 Eclipse 中运行

显然我们正在使用一些构建路径引用的自定义报告脚本,它本身使用 slf4j api 进行日志记录。

它似乎与同一个类的另一个不同版本冲突(对于同一个底层类加载隔离)。

【问题讨论】:

    标签: eclipse jasper-reports slf4j


    【解决方案1】:

    我遇到了同样的问题,我通过在我的项目的构建路径中添加这些罐子来解决它:

    • slf4j-api-1.7.12.jar
    • slf4j-log4j12-1.7.12.jar
    • slf4j-simple-1.7.12.jar

    并将JasperReports LibraryJasperReports Library Dependencies 也添加到项目中

    通过这些步骤

    1. 在项目中右击
    2. 构建导管 > 配置构建路径
    3. 去图书馆并使用Add External JARs添加罐子
    4. 使用 Add Library 添加 JasperReport 库和 JasperReport 库依赖项
    5. 然后转到Order and Export 并检查新添加的库和罐子并单击确定

    你会得到这样的结果:

    【讨论】:

    • 酷。我现在无法重新评估,但我上面的解决方法并不像你的解决方案看起来那么好,所以我会在没有验证的情况下接受你的答案。谢谢你的好解决方案! :-)
    • JasperReports Library Dependencies 为我们解决了问题 :) 很酷
    • 但不幸的是我被另一个LinkageError卡住了:java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.LoggerFactory.getLogger(Ljava/lang/Class;)Lorg/slf4j/Logger;" the class loader (instance of java/net/FactoryURLClassLoader) of the current class, jr/utl/EnvScriptlet, and the class loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader) for the method's defining class, org/slf4j/LoggerFactory, have different Class objects for the type org/slf4j/Logger used in the signature ...正在调查(jr.utl.EnvScriptlet确实只使用slf4j)
    【解决方案2】:

    对我们来说最简单的解决方案(在对库和设置进行了一些摆弄之后)是切换回带有 Jasper 插件 v5.5.1.final 的 Eclipse 目录备份版本(我们仍然为所有开发人员提供一份副本)。

    很难通过 Eclipse 安装历史记录“还原”,因为我们的基础更新站点要么只指向最新的,要么可能根本没有 5.5.1.final 的旧更新站点。 (我们没有进一步调查)

    (顺便说一句:在 Eclipse 中禁用自动更新以避免此类意外可能是安全的)

    环境详情:

    (......对于那些可能找到其他可行解决方案的人的可能原因。)

    对我们来说这是 org.slf4j.Logger 的用法(具有 slf4j-api-1.7.5.jarslf4j-simple-1.7.5 .jar 在构建路径中或将两者都删除 - 没关系...只是在更改后关闭并重新打开所有报告而不重新启动 Eclipse)

    使用 eclipse.ini jvm 选项运行 Eclipse -verbose:class 表明冲突可能与这个其他加载的类有关(无论它在哪里加载(可能由 jasper 预览编辑器本身使用):@ 987654324@)

    假设 Jasper 从 v6 开始使用 SLF4J,并且不使用单独的类加载器将其报告特定类/库的类加载与它自己的类版本(或 Eclipse 安装提供的类加载器)隔离开),因此可能会导致此类链接错误(例如How to deal with LinkageErrors in Java?.)。

    6.0.4(我在其中添加了这些信息)已经有一个已知的已解决错误,但显然没有解决: http://community.jaspersoft.com/jaspersoft-studio/issues/3831#comment-818386

    【讨论】:

    • 我挣扎了好几天试图获得其他建议,包括选择的工作答案,但我做不到。您的回答迫使我退回到 6.0 之前的版本,但它确实有效。
    【解决方案3】:

    (哇……终于找到了一个可以接受的解决方法来解决这个明显的 groovy 类加载问题

    我们自己创建了一些非常简单的帮助报告hlprep.jrxml

    • 使用提到的 scriptlet

      • 或者会使用/调用任何其他你会遇到问题的 java 类
    • 设置为language=java

      • (其他站点建议从language=groovy 切换到java 以消除上述错误,但这通常不是一个选项)

    (现在它应该在Preview 中运行良好)

    每次遇到此错误时(这可能是随机的,因为类加载可能是正确的,这取决于您之前在 IDE 中所做的事情)我们现在可以执行以下操作:

    1. 打开hlprep.jrxml

      • 最好使用Open with ... JasperReports Preview(因此您不必在进一步的步骤中明确打开预览)
    2. 重启你的 Eclipse

      • 重启后它应该记住你打开的文件,否则你必须在重启后先打开助手报告
    3. 选择/预览hlprep.jrxml

      • 现在发生了正确的类加载(由“java”上下文触发)
    4. 选择/预览(已经打开的)其他失败的报告

    现在应该可以正常运行,即使在更改之后,但如果您再次打开/关闭新的,它可能会失败。 (因为这些类可能会被回收或 groovy 类加载器隔离魔法以不同方式加载它)

    我们的环境

    • 日食霓虹灯 3
      • 在内部使用 Groovy 2.4.5
      • JDK 1.8.0_121 开头
    • Jaspersoft Studio 6.3.2.final
      • 我们有一个 6.3.0 服务器,但在 6.3.1 中添加了完整的 Neon 支持,因此我们采用了 6.3.x 的最后一个补丁版本
      • 之前我们遇到过新的工作室版本无法与旧服务器一起使用的问题,因此我们在此处升级时会更加小心
    • 可能无关:
      • 仅依赖于pom.xml 中的 slf4j api(在我们的例子中为 1.7.12)就足够了
      • 我们都提供了添加到项目中的 jasper 库:Jaspersoft Server LibraryJasperReports Library Dependencies
      • 我们还依赖服务器功能,因此我们在 pom.xml 中也有 jasperreports-6.3.0.jar 和一些(不是通过一些可用的公共 Maven 存储库)服务器 jars 作为项目的 User Library(我们从服务器复制过来的)
      • pom.xml 中没有常规引用

    【讨论】:

      【解决方案4】:

      答:有时只需重新启动 Eclipse/Studio 就足够了。这可能与某些类加载器在执行某些操作或(间接)使用某些插件时加载类有关。

      B:尝试排除 (显式或隐式)添加到项目类路径、用户库、Eclipse 库或Mavens pom.xml 例如,如果项目本身在设计时不使用/不需要/引用它们。 这样,冲突就不会在设计时/在 Studio/Eclipse 中发生。
      也许人们必须记住,那些类/jars/libs 在运行时环境中可能是必需的或不同的,必须解决例如通过 Mavens 中的 scope pom.xml 或类似方式。

      【讨论】:

        猜你喜欢
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多