Finally getting back to this, I tracked down service starter in the
examples. I eventually figured out is contained in start.jar referenced by
the scripts. The problem I have now however is that it seems that start.jar
is generic and it's behavior is controlled by a configuration file with a
weird syntax that looks something like java but clearly isn't quite. Is the
format/options etc for this configuration file documented anywhere?
I found the package documentation where a bunch of examples of the
configuation can be found, but it's entirely unclear what the role of
things like "private static" are in those examples, and given the existance
of
private static fiddler_classpath = "*install_dir*/lib/fiddler.jar";
private static fiddler_config =
"*config_dir*/transient-fiddler.config
<https://river.apache.org/doc/api/com/sun/jini/start/package-summary.html#transient_fiddler_config>";
and
private static mahalo_classpath = "*install_dir*/lib/mahalo.jar";
private static mahalo_config =
"*config_dir*/transient-mahalo.config
<https://river.apache.org/doc/api/com/sun/jini/start/package-summary.html#transient_mahalo_config>";
as peers, it looks almost like the _ character is a namespacing operator
rather than part of an identifier? Is that correct? How do these configs
work?
I looked briefly at the other two containers you mentioned, and both seem
to be pretty heavily tied to maven... (but maybe that's just the bias of
thier docs/examples?) is there another option that doesn't require maven? I
want to build something that's easy to deploy and having to run a maven
build to deploy stuff into a container is not exactly user friendly for a
final product. Never mind that I don't normally use maven for development
either...
-Gus
On Tue, Jul 8, 2014 at 12:46 PM, Greg Trasuk <[email protected]> wrote:
>
> Hi Gus:
>
> Sorry for the delayed reply - I’m on vacation and my internet access is a
> little spotty.
>
> PreferredClassLoader is important in the long run, but you probably won’t
> notice the lack of it until you get to some more complicated service
> scenarios. In the short term, you could probably do without, however It
> might be a little complicated to get rid of.
>
> Unfortunately, to explain further, we need some more background info.
> Bear with me for a few minutes, we’ll come back to the problem, I promise….
>
> Jini is a “mobile-code” style of network architecture, although that may
> not be entirely obvious. When you pass arguments to a service call, or
> receive return values, what’s actually being passed is a serialized, or
> “marshalled” version of the object as it exists inside the virtual machine
> (VM). This includes “looking up a service” - what you’re receiving is a
> marshalled version of the proxy to the that service.
>
> Serialization is typically performed by ‘net.jini.io.MarshallInputStream’
> and ‘net.jini.io.MarshallOutputStream’. These classes extend
> ObjectInputStream and ObjectOutputStream, respectively. The marshalled
> form includes a copy of all the data inside the instance, plus the name of
> the class, and a “codebase annotation” that provides a url that points to
> where the class can be downloaded from (hence mobile code).
>
> When a marshalled object is loaded into a local virtual machine, the
> MarshallInputStream needs to create an instance of the object’s class, and
> then put the instance data into it. It will create a new class loader that
> loads bytecode from the “codebase annotation url”, and then use that class
> loader to create the local instance of the marshalled object.
>
> Keep in mind that “Foo” loaded by class loader CL-B can implement an
> interface “Bar”, or extend a class “Bas” that is loaded by class loader
> CL-A. So it’s entirely possible that the user of “Foo” has no knowledge
> of, or access to the actual implementation class (e.g. by declaring a
> reference to “Bar” or “Bas” and then storing a reference to “Foo” in it).
> Also, this applies to fields of an instance as well.
>
> But what happens if the same class name exists in the local VM’s class
> path? In most cases, we’d rather use the locally-defined byte code.
> Partly for efficiency reasons (avoid downloading the jar file) but also
> because if we want to “use” the class locally, it needs to come from the
> same class loader (in other words, “Foo” loaded by class loader CL-A is
> actually a different class than “Foo” loaded by class loader CL-B, even if
> the actual byte code is the same). So the default behaviour is to use a
> locally-available class if there is one, and only use a different class
> loader if the required class is not available locally.
>
> If we load a marshalled object, and we already have the same class
> available locally, what happens to the codebase annotation that was on the
> marshalled object? It’s gone, since the codebase annotation goes with the
> codebase, which clearly is associated with the class loader. Usually
> that’s OK, but what if the service really wants to use the code that it’s
> providing remotely? That’s where PreferredClassLoader comes in.
>
> PreferredClassLoader takes a look at a file in the first “jar” file in the
> codebase annotation (META-INF/Prefered.list), and treats it as a list of
> “Preferred” classes. These are classes where the downloaded code is
> “Preferred” to the locally-available class. That way the codebase
> annotation sticks, not to mention that the service provides the byte code
> that it’s expecting.
>
> That’s not a really common use case, so as I say, you might not notice the
> lack of PreferredClassLoader. It’s plugged in using an SPI provider
> (META-INF.services/java.rmi.server.RMIClassLoaderSpi) file that’s in
> jsk-resources.jar. So to remove PreferredClassLoader properly, you need to
> put a different version of jsk-resources.jar into your class path.
>
> There’s another possible problem, although I can’t prove it - just a bad
> feeling that I get. Having read through all the above, you might notice
> that there’s a lot of class loader hocus-pocus going on. Remote code, and
> by extension, Jini, is pretty fussy about class loading, and class loader
> hierarchy. In addition to on-demand loading (mobile code), the library
> uses things like the Preferred list, and Spi configuration files, that are
> also loaded through the class loaders. Although there’s nothing illegal,
> it’s an advanced use of the class loading mechanism, so it wouldn’t shock
> me if the class loader used in your “one-jar” implementation isn’t complete
> enough to support it. I’ve come across other class loader implementations
> (e.g. Apache Virtual File System) that didn’t work properly, and you
> mentioned that your ‘one-jar’ loader has a known bug around loading classes
> by name (which, if you think about it, is what needs to happen for just
> about all the remote class loading). Also, you need to be able to set the
> codebase annotation on a given class loader.
>
> A “one-jar” library is really a custom class loader that gets it’s byte
> code from files that are inside the jar file. So, it’s plausible that any
> given “one-jar” approach could cause problems.
>
> That’s why a container approach is usually better. There’s a rudimentary
> container provided with River, ‘com.sun.jini.start.ServiceStarter' which is
> unfortunately not used in the “getting started” doc (not sure who wrote it,
> but I’m afraid that I personally don’t have time to re-write it just now).
> You can see an example of its use in the service registrar startup that’s
> mentioned in that doc. More advanced containers are available in the
> River-Container project (https://github.com/trasukg/river-container) or
> the Rio project (http://rio-project.org).
>
> Essentially, Jini needs class loaders that are designed for Jini.
> (Really, it’s not Jini - mobile code needs mobile-code-aware class
> loaders). My experience has been that it’s possible to put simple service
> consumers into non-Jini-aware class loaders (e.g. web application
> containers like Tomcat, or command-line class paths) with a few
> limitations. Hosting service implementations without ServiceStarter,
> River-Container, Rio, or some other Jini-aware environment will be a
> complete exercise in frustration.
>
> So, have a look at the way the JavaSpaces implementation gets started up
> (it’s the closes to a plain service implementation) and copy that. Or have
> a look at River-Container.
>
> And I suppose we ought to renovate the “getting started” page. You might
> also want to have a look at the “hello” example, as mentioned in
> http://river.apache.org/doc/info-index.html#example.
>
> Cheers,
>
> Greg.
>
>
--
http://www.the111shift.com