1. When a service's classloader is created that exports http:// based URLs, the JVM uses sun.net.www.http.HttpClient which keeps a static reference to a keep-alive cache which is loaded using the ServiceClassLoader as it's context classloader
2. The RMIClassLoaderSPI maintains strong references to the ServiceClassLoader. This seems (somewhat directly) related to the above.
What I'm planning on doing is introducing a new way to address the jar(s) that a service offers up as exports. The approach I'm planning on taking is to introduce a new protocol:
artifact:groupId/artifactId/version[/type][;repository]
The protocol handler will use the Rio resolver to resolve the artifact (and it's dependencies), provisioning the jars locally, and instead of creating a classloader (via the RMICLassLoaderSPI) that uses http:// based URLs (forcing the static reference in the un.net.www.http.HttpClient keep-alive cache), a file:/ based URL is used [1].
This approach still maintains the capability of dynamically loaded code, we just install the code from a trusted repository to the local machine first, then load it locally. The issue here of course is that the protocol handler must be installed before any connection is made by using the following code:
Either
URL.setURLStreamHandlerFactory(new ArtifactURLStreamHandlerFactory());
or must be set via a JVM property such as:
-Djava.protocol.handler.pkgs=org.rioproject.url
The rio script will do the latter.
Using this approach has also led me to start adopting the conventions that I have recommended for service development in Rio (about time I started eating my own dog food right?).
What I'll be going is going through the project and remove all use of the classdepandjar packaging type. The will break out the rio, cybernode, monitor module(s). Part of this will also result in refactoring of classes into different packages.
There also needs to be a change in the Jini provided poms, they have been created with the 'old' approach of using the 'dl' classifier for the -dl jars. These poms need to be re-done, so reggie-dl.jar and outrigger-dl.jar are artifacts in their own right, and depend on jsk-dl.jar. I will most likely create an additional artifact that includes the Rio lookup attributes for outrigger, allowing a provisioned JavaSpace to have as part of it's attribute collection set things like an OperationalSting entry.
I had planned on doing some of this work and releasing 4.3, but with the substantial changes at play I am going to move for the next release to be 5.0. I hope to have a 5.0-SNAPSHOT up soon, and welcome feedback.
Regards
Dennis
[1] There are other leaks thats have been identified, but this seems to be the most egregious
Sounds like good activity! I've had a chance to play with the Aether
resolver stuff a bit and hope to do some more soon.
I wanted to let you know that I took some ideas from your work and
applied it to another problem I have--running simple Java
applications--and created my own open-source project, Kenya:
https://github.com/jramsdale/kenya
I'm still working on the code and it's alpha quality, but it did give
me some insight into Aether and the dark world of Plexus, etc. Since
Aether itself uses ClassWorlds to create classloaders I used it in
Kenya to isolate my application code from the Kenya "container". As
well, I build a classpath from artifacts resolved via Aether to my
local Maven repo. Is it possible that approach would work for Rio?
I've refactored the code beyond what I've got posted on GitHub but it
doesn't yet work 100%. Hope to post a new and improved version soon.
I'm heading out east for a week of vacation and may or may not have
time to hack. Hope to at least answer e-mail, though.
-jeff