在OSGi开发中,我们常用的getBundleContext().getServiceReferences(String, String)调用,偶尔会出现访问失败,返回null的问题。这是因为OSGi在若干关键的方法中,基于java.security.*类,实现了代码层次的访问权限控制。
在org.eclipse.osgi.framework.internal.core.Framework.getServiceReferences(String, String, BundleContextImpl, boolean)方法中,我们看到有个checkGetServicePermission(String serviceName)方法,其实现如下:
protected void checkGetServicePermission(String serviceName)
{
SecurityManager localSecurityManager = System.getSecurityManager();
if (localSecurityManager != null)
localSecurityManager.checkPermission(new ServicePermission(serviceName, "get"));
}
其中比较重要的类有:
java.security.AccessController
java.lang.SecurityManager
所有的权限判断,最终会在java.security.AccessController.checkPermission(Permission)方法中处理,在此方法中:
1. 调用native方法,获取 java.security.ProtectionDomain[] array。此方法由jvm自己native方法实现,主要实现了从当前调用堆栈上的jars中,解析ProtectionDomain类型。
2. 迭代调用java.security.ProtectionDomain.implies(Permission)方法,一旦某给ProtectionDomain判断失败,则会抛出AccessControlException,此次访问被拒绝。
在IBM Domino8