Java 我需要log4j1.2和2.5在同一个webapp中共存

Java 我需要log4j1.2和2.5在同一个webapp中共存,java,crystal-reports,log4j,classloader,log4j2,Java,Crystal Reports,Log4j,Classloader,Log4j2,我有一个JavaWebApp,它使用Crystal的BusinessObjects运行时运行一个用该技术编码的报告。问题是Crystal的猴子直接引用了log4j 1.2类中的一个方法。此方法不是log4j 1.2到2.5桥接api的一部分。也不应该,因为克里斯托不应该直接呼叫它 我别无选择,只能使用Crystal,我们的组织已经锁定了它。我只能选择要么回滚整个应用程序,使其不像我们的所有其他应用程序那样使用log4j2.5,要么我需要找到它们共存的方式。当我将两个JAR都放在类路径中时,应用程

我有一个JavaWebApp,它使用Crystal的BusinessObjects运行时运行一个用该技术编码的报告。问题是Crystal的猴子直接引用了log4j 1.2类中的一个方法。此方法不是log4j 1.2到2.5桥接api的一部分。也不应该,因为克里斯托不应该直接呼叫它

我别无选择,只能使用Crystal,我们的组织已经锁定了它。我只能选择要么回滚整个应用程序,使其不像我们的所有其他应用程序那样使用log4j2.5,要么我需要找到它们共存的方式。当我将两个JAR都放在类路径中时,应用程序往往会对加载什么感到困惑,我们无法注销。移除那个罐子,日志记录会很好…但是水晶炸弹


我真的不想把所有内容都回滚到1.2。有没有办法让他们和谐共处?比如只在调用Crystal或其他东西时才在类加载器上提高1.2?有人知道一些可以帮助我的技巧吗?

代理对象

将Crystal jar及其所有依赖项放入文件夹(/path/to/crystalib/)

代码示例

从Crystal库创建任何类:

    File libDir = new File("/path/to/crystalLib/");

    ProxyCallerInterface caller = ObjectBuilder.builder()
            .setClassName("org.crystal.report")
            .setArtifact(DirArtifact.builder()
                    .withClazz(this.getClass())
                    .withVersionInfo(newVersionInfo(libDir))
                    .build())
            .build();
    String version = caller.call("crystalMethod").asString();

代理对象库将处理单独的类加载器混乱,您应该能够以这种方式加载任何冲突的依赖项。

您可以在同一JVM中使用不同版本的类,但随后需要多个类加载器。所以,这是可能的,但在非常高级的一端。也许,只是也许…得到你想要的整个Log4j版本的项目,然后修改名称,这样Crystal的Log4j方法就不会发生冲突。权衡的结果是,由于您将被锁定到您将要使用的Log4J的特定版本,因此您将有管理log4jjar文件的开销。另一种方法是将与Crystal相关的代码隔离为在另一个JVM(或至少在不同的web上下文中)中运行的服务。然后,你的应用程序,它没有直接的知识水晶或它的依赖关系,调用服务需要。还有,用Crystal开一张票。