【问题标题】:How to know which is the caller party in case of loading jar在加载jar的情况下如何知道哪个是调用方
【发布时间】:2012-12-24 23:35:52
【问题描述】:

考虑存在三个应用程序的场景。 A、B、C

A 由 B 使用 Class.LoadFrom 加载。 A 也可以从 C 加载 A 也可以作为独立应用程序启动

问题是,A 能找到是谁加载了 A 还是它自己启动的。

我试图找到进程名称,但这没有帮助。 试图找到使用类加载器是否可以告诉我。也没有帮助。 尝试使用我想避免的 StackTraces,但这根本不是一个好习惯。 我想避免设置属性文件,因为它需要一些手动操作。

在 .Net/C# 中这很容易:(

编辑:

看看这个,这在Java中可以吗?

System.Reflection.Assembly.GetEntryAssembly

【问题讨论】:

  • 是 A、B、C 类吗?并且您想知道,在该实例中如何/谁创建了 A 的实例?
  • 那些是罐子......不是创建,找到谁访问了A
  • This 似乎是一个非常相似的问题。
  • 考虑到当前的答案,并不完全相似,但足够接近。谢谢:)

标签: java classloader


【解决方案1】:

Thread.getAllStackTraces() 可能有效。 - 或者从ThreadGroup hierarchy 向上走到顶部并从根ThreadGroup (getParent() == null) 获取所有线程。

然后检查 main() 方法的堆栈跟踪并找出它的包/类名称可能会对您有所帮助。

检测“独立”模式很容易:当您的 main() 方法在您的其他代码之前运行时,您就是独立的。

public class MyMainClass {

  private static boolean standalone = false;

  public static boolean isStandalone() {
    return standalone;
  }

  public static void main(String[] args) {
    standalone = true;

    // Run as usual...

  }

}

然后您的任何代码都可以调用MyMainClass.isStandalone() 来确定它是否独立运行。

确定哪个应用程序正在运行您的代码,当它不处于独立模式时,有点困难,并且可能无法在没有堆栈跟踪的情况下完成,这并不总是完全可靠,而是某种启发式。

如果您知道应用程序 B 中存在哪些类但 C 中不存在,反之亦然,您也可以尝试通过 Class.forName() 找到其中一个;如果调用失败并返回 ClassNotFoundException,您就知道该类在当前运行时环境中可用,并且可能能够推断出哪个应用程序正在运行。

为每个应用程序定义某种应用程序全局属性肯定是一个更好的主意,然后您的代码可以对其进行评估。

【讨论】:

  • 猜猜这是Java中的问题:(
  • 我想知道您的用例是什么。你能提供一些细节吗?
  • 嗯,我的一个 QA 朋友正在开发一个可以自行运行的应用程序,它还包含用于被其他正在测试的应用程序加载的已实现接口。我对他的意思是让他们分开,但他坚持要这样。此外,由于许多 QA engg 将使用它。他还试图避免对任何属性文件进行任何手动输入。希望你明白我的意思:)
  • 我并不完全清楚备用接口是如何使用的,但听起来每种加载方式都有不同的入口点。如果是这样的话,你不能简单地添加一个基于枚举的静态类变量并根据入口点设置它吗?
【解决方案2】:

您可以使用线程名称来识别哪个类启动进程,这里是一个示例。它拥有自己的访问权限的票务系统。

public class TicketingSystem {

    public TicketingSystem() {
        System.out.println("Accessing by : " + Thread.currentThread().getName());
    }
    public void bookATicket() {
        // some process
    }
    public static void main(String[] args) {
        Thread.currentThread().setName("T.System");
        TicketingSystem ticketingSystem = new TicketingSystem();
    }
}

一个代理访问TicketingSystem

   public class TicketAgent {
      public static void main(String[] args) {
          Thread.currentThread().setName("Agent");
          TicketingSystem ts = new TicketingSystem();
          ts.bookATicket();
      }
   }

一位客户访问TicketingSystem

 public class Customer {
        public static void main(String[] args) {
            Thread.currentThread().setName("Customer");
            TicketingSystem ts = new  TicketingSystem();
            ts.bookATicket();
        }
}

希望这个答案对你有所帮助。

【讨论】:

  • 谢谢你的回答,是的,这是一种方法,但可能不是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2011-07-23
  • 2016-10-01
  • 2011-12-31
  • 1970-01-01
相关资源
最近更新 更多