Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSGi bundles and proxy identity - allow more than once service proxy to utilise a specific bundle version? #150

Open
pfirmstone opened this issue Feb 16, 2022 · 4 comments

Comments

@pfirmstone
Copy link
Owner

Describe the bug
Currently ProxyBundleProvider doesn't allow more than one services to use a specific proxy bundle version, currently this represents a major restriction placed on the use of OSGi services.

The reason this occurs is a mismatch between OSGi bundle loading and service proxy identity.

There is a many to one relationship between proxy identity and bundles. OSGi doesn't allow loading duplicate bundles.

Options and thoughts on how to handle this, all suggestions are welcome:

  1. Allow different services to share the same classes, consequences; loss of service proxy identity, unwanted permissions granted to less trusted services.
  2. Encapsulate the service proxy with another proxy, unfortunately this wont work with RemoteMethodControl, which would return a new instance.
  3. Create a shim InvocationHandler, who's class is loaded directly by BundleDelegatingClassLoader, so that whenever remote method calls are made, the permissions granted are granted to this particular ClassLoader and ProtectionDomain. Then only one bundle would need to be loaded, but the presence of the InvocationHandler on the call stack would reduce permission to the intersection of the sets of permissions on the call stack. We would need to make BundleDelegatingClassLoader override preferred ClassLoader and prefer the class of the InvocationHandler. It would be best if the InvocationHander is in its own package, in the JERI bundle. During marshalling this InvocationHandler would need to replace itself with the encapsulated InvocationHandler, however that may create problems with equality, with the CodebaseAccessor InvocationHandler. Since we know the InvocationHandler will be an instance of AtoimcInvocationHandler, we can extend it instead, with a stateless child class that only has an @AtomicSerial constructor and replaces itself with the superclass when serialized. This class wouldn't be exported from the package, and CodeSource could be used to find the URL of the bundle.
@pfirmstone
Copy link
Owner Author

pfirmstone commented Feb 16, 2022

Item 3.

I think it would be easiest to use preferred class loading to load AtoimcInvocationHandler into the BundleDelegatingClassLoader. However this presents a problem with BasicJeriTrustVerifier.

Perhaps we should inject a token into AtomicInvocationHandler instead, that is loaded by the BundleDelegationClassLoader, to ensure that a ProtectionDomain representing the service is present on the call stack, then we need to invoke a method on the token every time that InvocationHandler::invoke is called. This could of course be in-lined as a no-op, this needs further investigation.

The problem with the token approach is that permissions are granted by the client during proxy preparation to the ClassLoader of the smart proxy. The BundleDelegatingClassLoader, although the ClassLoader of the Endpoint, is not the actual ClassLoader used to load Bundle classes. Further complicating the situation, any dependencies that are resolved for the proxy, may not have required permissions.

Should we consider allowing smart proxies to share Bundles?

What are the consequences?

@pfirmstone pfirmstone changed the title OSGi bundles and proxy identity - maintain independant identity for services that use identical bundles, and allow more than once service to utilise a specific bundle. OSGi bundles and proxy identity - allow more than once service proxy to utilise a specific bundle version? Feb 16, 2022
@pfirmstone
Copy link
Owner Author

@pfirmstone
Copy link
Owner Author

pfirmstone commented Feb 17, 2022

Is this an option?

  • Load the proxy bundle, this resolves all OSGi dependencies.
  • Load the bundle again into a PreferredClassLoader, which has the bundle BundleDelegationClassLoader as its parent.
  • Each proxy and all its classes with unique identity are then loaded by a unique ClassLoader, with the bundle as its parent to resolve all dependencies.
  • No classes in the bundle are used by proxy code.
  • No classes in the proxy are exported into the OSGi environment. All interactions are by commonly resolved service api classes and classes visible from the bundle.

In an answer no, while it would work, it's a hack.

@pfirmstone
Copy link
Owner Author

pfirmstone commented Feb 17, 2022

Investigate OSGi subsystems or OSGi Framework Bundle Collision Hook Service.

My current thinking is we need to consider Apache Aries OSGi subsystems.

pfirmstone added a commit that referenced this issue Feb 18, 2022
pfirmstone added a commit that referenced this issue Feb 18, 2022
 OSGi bundles and proxy identity - allow more than once service proxy to utilise a specific bundle version? #150
pfirmstone added a commit that referenced this issue Feb 18, 2022
pfirmstone added a commit that referenced this issue Feb 18, 2022
pfirmstone added a commit that referenced this issue Feb 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant