@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(classLoader)) { return method.invoke(userGroupProvider, args); } catch (final InvocationTargetException e) { // If the proxied instance throws an Exception, it'll be wrapped in an InvocationTargetException. We want // to instead re-throw what the proxied instance threw, so we pull it out of the InvocationTargetException. throw e.getCause(); } } }
/** * Sets the current thread context class loader to the provided class loader, and returns a NarCloseable that will * return the current thread context class loader to it's previous state. * * @param componentNarLoader the class loader to set as the current thread context class loader * * @return NarCloseable that will return the current thread context class loader to its previous state */ public static NarCloseable withComponentNarLoader(final ClassLoader componentNarLoader) { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(componentNarLoader); return new NarCloseable(current); }
@Override public void initialize(StateProviderInitializationContext context) throws IOException { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { stateProvider.initialize(context); } }
@Override public void run() { try (final NarCloseable narCloseable = NarCloseable.withFrameworkNar()) { if (heartbeatsSuspended.get()) { return; } final HeartbeatMessage message = createHeartbeatMessage(); if (message == null) { LOG.debug("No heartbeat to send"); return; } heartbeater.send(message); } catch (final UnknownServiceAddressException usae) { if (LOG.isDebugEnabled()) { LOG.debug(usae.getMessage()); } } catch (final Throwable ex) { LOG.warn("Failed to send heartbeat due to: " + ex); if (LOG.isDebugEnabled()) { LOG.warn("", ex); } } } }
@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(classLoader)) { if (getAccessPolicyProviderMethod.equals(method)) { final AccessPolicyProvider accessPolicyProvider = (AccessPolicyProvider) method.invoke(authorizer, args); if (accessPolicyProvider == null) { return accessPolicyProvider; } else { return AccessPolicyProviderFactory.withNarLoader(accessPolicyProvider, classLoader); } } else { return method.invoke(authorizer, args); } } catch (final InvocationTargetException e) { // If the proxied instance throws an Exception, it'll be wrapped in an InvocationTargetException. We want // to instead re-throw what the proxied instance threw, so we pull it out of the InvocationTargetException. throw e.getCause(); } } }
@Override public void shutdown() { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { stateProvider.shutdown(); } }
public static NarCloseable withNarLoader() { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); return new NarCloseable(current); }
@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(classLoader)) { if (getUserGroupProviderMethod.equals(method)) { final UserGroupProvider userGroupProvider = (UserGroupProvider) method.invoke(accessPolicyProvider, args); if (userGroupProvider == null) { return userGroupProvider; } else { return UserGroupProviderFactory.withNarLoader(userGroupProvider, classLoader); } } else { return method.invoke(accessPolicyProvider, args); } } catch (final InvocationTargetException e) { // If the proxied instance throws an Exception, it'll be wrapped in an InvocationTargetException. We want // to instead re-throw what the proxied instance threw, so we pull it out of the InvocationTargetException. throw e.getCause(); } } }
@Override public Scope[] getSupportedScopes() { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { return stateProvider.getSupportedScopes(); } }
/** * Sets the current thread context class loader to the specific appropriate class loader for the given * component. If the component requires per-instance class loading then the class loader will be the * specific class loader for instance with the given identifier, otherwise the class loader will be * the NARClassLoader. * * @param componentClass the component class * @param componentIdentifier the identifier of the component * @return NarCloseable with the current thread context classloader jailed to the Nar * or instance class loader of the component */ public static NarCloseable withComponentNarLoader(final ExtensionManager extensionManager, final Class componentClass, final String componentIdentifier) { final ClassLoader current = Thread.currentThread().getContextClassLoader(); ClassLoader componentClassLoader = extensionManager.getInstanceClassLoader(componentIdentifier); if (componentClassLoader == null) { componentClassLoader = componentClass.getClassLoader(); } Thread.currentThread().setContextClassLoader(componentClassLoader); return new NarCloseable(current); }
private static boolean checkControllerServiceReferenceEligibility(final ConfigurableComponent component, final ClassLoader classLoader) { // if the extension does not require instance classloading, its eligible final boolean requiresInstanceClassLoading = component.getClass().isAnnotationPresent(RequiresInstanceClassLoading.class); final Set<Class> cobundledApis = new HashSet<>(); try (final NarCloseable closeable = NarCloseable.withComponentNarLoader(component.getClass().getClassLoader())) { final List<PropertyDescriptor> descriptors = component.getPropertyDescriptors(); if (descriptors != null && !descriptors.isEmpty()) { for (final PropertyDescriptor descriptor : descriptors) { final Class<? extends ControllerService> serviceApi = descriptor.getControllerServiceDefinition(); if (serviceApi != null && classLoader.equals(serviceApi.getClassLoader())) { cobundledApis.add(serviceApi); } } } } if (!cobundledApis.isEmpty()) { logger.warn(String.format( "Component %s is bundled with its referenced Controller Service APIs %s. The service APIs should not be bundled with component implementations that reference it.", component.getClass().getName(), StringUtils.join(cobundledApis.stream().map(cls -> cls.getName()).collect(Collectors.toSet()), ", "))); } // the component is eligible when it does not require instance classloading or when the supporting APIs are bundled in a parent NAR return requiresInstanceClassLoading == false || cobundledApis.isEmpty(); }
@Override public Collection<ValidationResult> validate(ValidationContext context) { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { return stateProvider.validate(context); } }
/** * Creates a Closeable object that can be used to to switch to current class * loader to the framework class loader and will automatically set the * ClassLoader back to the previous class loader when closed * * @return a NarCloseable */ public static NarCloseable withFrameworkNar() { final ClassLoader frameworkClassLoader; try { frameworkClassLoader = NarClassLoadersHolder.getInstance().getFrameworkBundle().getClassLoader(); } catch (final Exception e) { // This should never happen in a running instance, but it will occur in unit tests logger.error("Unable to access Framework ClassLoader due to " + e + ". Will continue without changing ClassLoaders."); if (logger.isDebugEnabled()) { logger.error("", e); } return new NarCloseable(null); } final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(frameworkClassLoader); return new NarCloseable(current); }
@Override public String toString() { final Processor processor = processorRef.get().getProcessor(); try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(getExtensionManager(), processor.getClass(), processor.getIdentifier())) { return getProcessor().toString(); } }
@Override public void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { baseProvider.initialize(initializationContext); } }
/** * Sets the current thread context class loader to the provided class loader, and returns a NarCloseable that will * return the current thread context class loader to it's previous state. * * @param componentNarLoader the class loader to set as the current thread context class loader * * @return NarCloseable that will return the current thread context class loader to its previous state */ public static NarCloseable withComponentNarLoader(final ClassLoader componentNarLoader) { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(componentNarLoader); return new NarCloseable(current); }
/** * Find the bundle coordinates for any service APIs that are referenced by this component and not part of the same bundle. * * @param component the component being instantiated */ protected Set<BundleCoordinate> findReachableApiBundles(final ConfigurableComponent component) { final Set<BundleCoordinate> reachableApiBundles = new HashSet<>(); try (final NarCloseable closeable = NarCloseable.withComponentNarLoader(component.getClass().getClassLoader())) { final List<PropertyDescriptor> descriptors = component.getPropertyDescriptors(); if (descriptors != null && !descriptors.isEmpty()) { for (final PropertyDescriptor descriptor : descriptors) { final Class<? extends ControllerService> serviceApi = descriptor.getControllerServiceDefinition(); if (serviceApi != null && !component.getClass().getClassLoader().equals(serviceApi.getClassLoader())) { final Bundle apiBundle = classLoaderBundleLookup.get(serviceApi.getClassLoader()); reachableApiBundles.add(apiBundle.getBundleDetails().getCoordinate()); } } } } return reachableApiBundles; }
@Override public void onConfigured(LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { baseProvider.onConfigured(configurationContext); } }
/** * Sets the current thread context class loader to the provided class loader, and returns a NarCloseable that will * return the current thread context class loader to it's previous state. * * @param componentNarLoader the class loader to set as the current thread context class loader * * @return NarCloseable that will return the current thread context class loader to its previous state */ public static NarCloseable withComponentNarLoader(final ClassLoader componentNarLoader) { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(componentNarLoader); return new NarCloseable(current); }
@Override public Map<PropertyDescriptor, String> getProperties() { try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(extensionManager, getComponent().getClass(), getIdentifier())) { final List<PropertyDescriptor> supported = getComponent().getPropertyDescriptors(); if (supported == null || supported.isEmpty()) { return Collections.unmodifiableMap(properties); } else { final Map<PropertyDescriptor, String> props = new LinkedHashMap<>(); for (final PropertyDescriptor descriptor : supported) { props.put(descriptor, null); } props.putAll(properties); return props; } } }