paulrutter commented on PR #552:
URL: https://github.com/apache/felix-dev/pull/552#issuecomment-5500355448

   Thanks — the Apache-2.0 headers unblocked this, and `apache-rat` is happy 
now. I've pushed a substantial rework, and I have one design question at the 
end I'd value your view on.
   
   Both of your review points were real defects, not just omissions:
   
   - **`Plurl.install(..)` was never called.** Since the static `Plurl.add(..)` 
helpers operate through a `plurl:` URL, without installing the router first 
they fail with *unknown protocol: plurl*. Nothing in the prototype exercised 
the adapter, so it compiled and the tests passed while being dead code.
   - **`shouldHandle` was too loose.** It only checked that a class came from 
*some* Felix bundle class loader, so with two frameworks in one JVM either 
could answer for the other's bundles. It now also requires the owning framework 
to match, as your `EquinoxBundle`/container check does.
   
   Beyond that, plurl is now the mechanism rather than something bolted 
alongside, following Equinox:
   
   - `URLHandlers` no longer swaps the `java.net.URL`/`URLConnection` static 
fields, and its singleton is not constructed. I had considered keeping that as 
a fallback, but your `catch` in `SystemBundleActivator` convinced me otherwise 
— a fallback keeps the `sun.misc.Unsafe` path alive, which is the thing we're 
trying to delete.
   - Removing the swap turned out to be *necessary*, not just tidy: with 
`URLHandlers` taking the singletons first, plurl found them occupied and 
required `--add-opens java.base/java.net=ALL-UNNAMED`. Installing into a clean 
JVM uses the supported API and needs no flag.
   - `URLHandlersBundleStreamHandler` and `URLHandlersStreamHandlerProxy` now 
extend `PlurlStreamHandlerBase`, mirroring your changes to 
`BundleResourceHandler` and `URLStreamHandlerProxy`.
   - The router is installed once per JVM and reference counted — uninstalling 
per framework tore it down while another framework was still registered.
   - `new PlurlImpl()` as you suggested, rather than the `ServiceLoader`.
   
   The framework suite on JDK 25 is at 121 tests, 9 failures, 8 of which are 
pre-existing platform-specific ones unrelated to this. There is one left, and 
it's a design question rather than a bug:
   
   ### Routing a URL re-parsed outside any bundle
   
   `URLHandlersTest.urlHandlersWithClassLoaderIsolation` loads a second copy of 
the whole framework (and therefore of the vendored plurl classes) in a separate 
class loader, and each copy starts its own framework. The test then does the 
equivalent of:
   
   ```java
   URL url = bundle.getEntry("...");
   new URL(url.toExternalForm()).openStream();   // called from a plain test 
class
   ```
   
   That second `new URL(..)` is re-parsed **without** an explicit handler, from 
a class that is not loaded by any bundle. So `shouldHandle` cannot attribute it 
to a framework and plurl has nothing to route on.
   
   Falling through, the `bundle:` handler has to resolve the framework itself 
from the UUID in the URL's host. It can only see its own copy's frameworks, so 
when the URL belongs to the framework in the other class loader the lookup 
fails. Previously `URLHandlers` bridged this: a second copy reflectively called 
`registerFrameworkListsForContextSearch` on whichever copy owned the JVM 
factory, so a UUID could be resolved across class loaders. With plurl there is 
no "root `URLHandlers`" to find, so that rendezvous is gone.
   
   Note I deliberately do **not** bind the `bundle:` handler to one framework 
the way you bind yours to the container: the JVM caches one handler per 
protocol, so a pinned handler also gets used for another framework's `bundle:` 
URLs and then fails to resolve. That's what forced the UUID lookup.
   
   So: **how should a URL re-parsed from outside any bundle be routed to the 
owning framework, when several copies of plurl are live in different class 
loaders?** Options I can see:
   
   1. plurl gains a way to route a *URL* (not just a calling class), or to 
enumerate registered factories, so the owning factory can be found.
   2. Felix keeps its own cross-copy UUID registry — but that reintroduces 
reflection into the mechanism plurl is meant to replace.
   3. It's accepted as out of scope, and the test's expectation changes.
   
   Does Equinox have an equivalent case? I suspect it doesn't hit this because 
its callers are bundle classes that plurl can attribute, so the question may 
not have come up. If you think (1) is reasonable I'm happy to raise it upstream 
with a concrete API suggestion.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to