MCPcopy Create free account
hub / github.com/java-native-access/jna / getCallingClass

Method getCallingClass

src/com/sun/jna/Native.java:1596–1648  ·  view source on GitHub ↗

Try to determine the class context in which a #register(String) call was made.

()

Source from the content-addressed store, hash-verified

1594 was made.
1595 */
1596 static Class<?> getCallingClass() {
1597 // This method makes the assumption that it is only called from register
1598 // and unregister methods of this class. It is further assumed, that
1599 // these two methods are called from a static initialized block or from
1600 // a method of the class to be registered.
1601 //
1602 // There are two approaches taken to find the right stack frame:
1603 // - on modern VMs the StackWalker API is used and the first two entries
1604 // are skipped. The stack at the time of calling is:
1605 // 0. Stackframe: #getCallingClass
1606 // 1. Stackframe: #register or #unregister
1607 // 2. Stackframe: method of outer caller
1608 // the last element is the right one
1609 //
1610 // - on VMs not supporting the StackWalker, the SecurityManager is used
1611 // to fetch the classes of the stack. The SecurityManager has
1612 // getClassContext which returns the classes of the callers. It is
1613 // protected though and needs to be exposed first. For this the stack
1614 // trace is:
1615 // 0. Stackframe: SecurityManagerExposer#getClassContext
1616 // 1. Stackframe: #getCallingClass
1617 // 2. Stackframe: #register or #unregister
1618 // 3. Stackframe: method of outer caller
1619 if (stackWalkerGetInstance != null) {
1620 try {
1621 Object walker = stackWalkerGetInstance.invoke(null, stackWalkerRetainClassReference);
1622 Class<?> caller = (Class<?>) stackWalkerWalk.invoke(walker, stackWalkerFilter);
1623 return caller;
1624 } catch (Throwable ex) {
1625 LOG.log(Level.WARNING, "Failed to invoke StackWalker#getInstance or StackWalker#walk", ex);
1626 }
1627 }
1628
1629 if (securityManagerExposerConstructor != null) {
1630 Class<?>[] context = null;
1631 try {
1632 Object securityManagerExposer = securityManagerExposerConstructor.newInstance();
1633 context = (Class<?>[]) securityManagerGetClassContext.invoke(securityManagerExposer);
1634 } catch (Throwable ex) {
1635 LOG.log(Level.WARNING, "Failed to invoke SecurityManagerExposer#<init> or SecurityManagerExposer#getClassContext", ex);
1636 }
1637
1638 if (context == null) {
1639 throw new IllegalStateException("The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register");
1640 }
1641 if (context.length < 4) {
1642 throw new IllegalStateException("This method must be called from the static initializer of a class");
1643 }
1644 return context[3];
1645 }
1646
1647 throw new IllegalStateException("Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register");
1648 }
1649
1650 /**
1651 * Set a thread initializer for the given callback.

Callers 4

returnCallingClassMethod · 0.95
registerMethod · 0.95
unregisterMethod · 0.95

Calls 3

invokeMethod · 0.65
logMethod · 0.45
newInstanceMethod · 0.45

Tested by 2

returnCallingClassMethod · 0.76