【问题标题】:Ignoring JARS the ugly way via classloader通过类加载器以丑陋的方式忽略 JARS
【发布时间】:2014-11-26 06:21:21
【问题描述】:

所以,我在这里尝试做一些丑陋的事情,假设这是一个绝望的措施,因为我无法控制运行时环境。

话虽如此,我在无法控制类路径的环境中运行一些代码(坏事)......更糟糕的是类路径有两个 jar,比如说 productV1.jar 和 productV2.jar两者完全相同,但版本不同,因此它们具有相同的类。

由于某种原因,在大多数环境中,productV2.jar 被加载,productV1.jar 被忽略,但在其他一些环境中,productV1.jar 被调用,导致程序崩溃。

作为一种解决方法,我想要做的是弄乱类加载器以明确忽略“productV1.jar”。理想情况下,通过覆盖一些类加载器功能。我已经使用其他资源(例如来自 Hibernate 的 persistence.xml 文件)完成了此操作,但我不想根据包含的类进行过滤,而是根据 jar 文件进行过滤。有什么办法吗?

这只是在我可以进行谈判以摆脱有问题的罐子之前起作用...

编辑:如果有一些有趣的黑客攻击,我会留下这个问题。但是,问题在于 classpth 中的所有内容都由系统类加载器加载,并且尝试在运行时切换它并不是一件容易的事(或者可能根本不可能?)。我看到的唯一方法是使用自定义类加载器开始该过程,这不是我想要的。

【问题讨论】:

  • 我认为即使有充分的理由也应该避免这样做,但从“理论上什么是可能的?”的角度来看,这个问题很有趣
  • 您真正的问题不是技术问题,而是您的环境。您不能与控制设置类路径的人交谈以解决问题吗?像这样的解决方法只会让问题变得更糟。
  • 其实我是在爱护环境,但因为需要时间,我觉得找个短期的hack会很有趣……但我发现它不会放轻松...

标签: java jar classloader


【解决方案1】:

您是否尝试使用URLClassLoader 并手动将 jars 添加到类路径中?在 URLClassLoader 的构造函数中,您传递一个指向要加载的 jar 的 URL 数组。

您可以进行以下实验:创建一个 URLClassLoader 子类,其中仅包含您想要的 jars(即使用适当的 URL 数组调用超级构造函数)然后使用以下属性调用您的 java:

-Djava.system.class.loader=test.CustomJarsClassloader

将您的类加载器设置为默认类。

类加载器可能如下所示:

public class CustomJarsClassLoader extends URLClassLoader{
  public CustomJarsClassLoader(){
    super(new URL[]{ /*List of URLs to jars... */});
  }
}

更新:

好的,如果您无法将此参数添加到命令行,请尝试另一种方法:

  1. 在您的 main() 函数中创建一个新线程
  2. 将我上面提到的类加载器设置为这个线程的上下文类加载器(参见:javadocs
  3. 在此线程中运行所有应用程序的代码。您的类加载器应该用于加载类。

【讨论】:

  • 如果他不能更改类路径,他有什么机会可以添加任何额外的参数来调用 java 运行时?
  • 正是...我希望能够在运行时做一些事情。这更像是一个黑客的希望,但我什至尝试使用反射(有效)更改系统类加载器的类路径,但它似乎在我弄乱它之前加载类...... :)
  • @Martin 好的,我用另一种方法更新了我的帖子。也许会有所帮助?
  • @PiotrSobczyk,我想避免这种情况,但由于我可以从系统类加载器中提取完整的类路径,我可以过滤它,然后根据正确的列表创建一个新的。问题是它将用于单元测试,所以我可能需要创建一个新的测试运行程序,看看我是否可以让它工作而不会弄乱测试代码......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 2018-06-11
  • 2011-08-11
  • 1970-01-01
  • 2011-05-19
  • 2019-08-18
相关资源
最近更新 更多