2

I have a generic component (a simple java package). I convert it into a jar and give it to my clients.

My client can use this jar for any of his applications. Will it be possible to identify who calls my component. That's in my component, will I be able to identify who created an instance of me?

Sorry, If I put this is a vague manner. Given a object I could find the className associated to it using(getClass()) . But I am not sure, if my requirement is ever possible.

Maheswaran Ravisankar
  • 17,652
  • 6
  • 47
  • 69
  • 1
    You'd have to add some code to your class, e.g. a WhoCreatedme argument in the contructor... – Tony Hopkinson Jul 04 '14 at 15:00
  • What's the rationale behind the request? Could this possibly be an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? – Hovercraft Full Of Eels Jul 04 '14 at 15:00
  • What would you do with this information? – Jamie Cockburn Jul 04 '14 at 15:01
  • What useful information could you derive from that? If I write a factory class for the stuff in your package, where would that leave the code knowing its creator? – laune Jul 04 '14 at 15:03
  • My component is back-end component. Which is rapidly used by multiple clients. I would like to know, if we can audit the classes who instantiate me (At Java Layer) ! I have already created the audits in the Oracle layer, having implemented trace-ids from java to oracle – Maheswaran Ravisankar Jul 04 '14 at 15:05

2 Answers2

5

That's in my component, will I be able to identify who created an instance of me?

Not in general, no. You could try obtaining a stack trace in the constructor, but that's not necessarily reliable or helpful.

If you want some sort of identifier, I suggest you have that as a constructor parameter (or factory method parameter). In other words, get the caller to identify themselves.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Why would getting a stack trace not be reliable? – João Mendes Jul 04 '14 at 15:01
  • 1
    @JoãoMendes: JIT inlining, for example. It's possible that it would *actually* be okay with whatever JIT the OP is using, but it doesn't feel like a good idea to me. – Jon Skeet Jul 04 '14 at 15:05
  • @Jon Skeet: JIT inlining has no effect on the stack trace. That’s why creating a stack trace will kill performance for sure. On the other hand, using Reflection has an impact on the stack trace. – Holger Jul 04 '14 at 15:08
  • @Holger: What guarantee is there that JIT inlining will never affect the stack trace on any JIT? It may not on Hotspot, but that's not the same as it being guaranteed for all JITs. If a JIT simply inlines the call in the most obvious way, an inlined call wouldn't be in the stack trace. (This can *definitely* occur in the Microsoft .NET CLR, for example - so unless there's meant to be some guarantee that it never happens in a JVM, it seems like a reasonable possibility.) And yes, reflection is another issue. – Jon Skeet Jul 04 '14 at 15:11
  • @Holger: In fact, `Throwable.getStackTrace` explicitly mentions this: "Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace" – Jon Skeet Jul 04 '14 at 15:12
  • It would still *probably* give the OP some inkling as to what he wants, namely, what projects and libraries are using his component. It's ok if a few stack traces are missing. It's extremely improbable for the *whole* stack to be inlined... – João Mendes Jul 04 '14 at 15:15
  • @JonSkeet The constructor is what we decided, but there has to be some standards in naming the possible values, and the processes are all set for it. I am just over greedy, if I could ever get the reference of the object who called me..! – Maheswaran Ravisankar Jul 04 '14 at 15:16
  • @OracleUser there are no standards on this. The constructor way is the only possible reasonable way in Java. – Luiggi Mendoza Jul 04 '14 at 15:17
  • 1
    @JoãoMendes: I don't think we really have enough information about *exactly* what the OP is doing to know that the crucial stack element would be there, to be honest. (And in some cases, even the stack trace wouldn't show anything useful - it only shows the class containing the code that's executing, not the actual type of the object calling it. Imagine an abstract superclass of `Application` which initialized the OP's library - you'd be interested in which subclass of `Application` was involved.) – Jon Skeet Jul 04 '14 at 15:17
  • 1
    @OracleUser: No, there's simply no facility to do that. (And there may not even *be* an object - think about a static method...) – Jon Skeet Jul 04 '14 at 15:18
  • @JonSkeet Understood and +1'd. – João Mendes Jul 04 '14 at 15:23
  • @Jon Skeet: There *are* certain stack frames which Oracle’s JVM hides. But that has nothing to do with JIT inlining. I would just prefer existing issues for explaining the unreliability of stack traces over theoretical ones. In the end, a JVM is not required to provide stack traces at all. – Holger Jul 28 '14 at 08:19
3

You can get the stack trace of the current thread and parse the StackTraceElements in the return, to find out which methods are calling yours.

You can check out this question here in SO.

Community
  • 1
  • 1
João Mendes
  • 1,719
  • 15
  • 32