The configuration file format is documented in the javadoc for
‘net.jini.config.ConfigurationFile’.
In concept, the Configuration file is somewhat similar to (although it
pre-dates) a Spring configuration file (e.g. spring-beans.xml). The
definitions that look like an assignment are actually telling the configuration
system how to create or retrieve an instance of an object that is looked up by
name within a Jini-using program (for instance ServiceStarter).
Consider the following:
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;
com.sun.jini.reggie {
initialLookupGroups = new String[] {$discoveryGroup};
initialMemberGroups = new String[] {$discoveryGroup};
serverExporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
new BasicILFactory());
}
Also, if you have a look at the javadoc for the interface
‘net.jini.config.Configuration’, you’ll see that it contains a method:
public Object getEntry(String component,
String name,
Class type)
throws ConfigurationException
When reggie starts up, it goes to its configuration object (which implements
Configuration, and is probably, but not necessarily, an instance of
ConfigurationFile) and requests the value of ‘initialLookupGroups’ for the
component identified by ‘com.sun.reggie’. Based on the file, ConfigurationFile
creates a new string array containing the value of a ‘special’ variable,
‘$discoveryGroup’ that is supplied when the config instance gets created. In
the case of river-container, that’s a global workgroup name that is supplied to
every application, so you can set it once in the container configuration.
Expressions could also refer to values that are defined in other expressions,
so for instance, you could have:
nGroups=initialGroups.length;
‘static’ means to evaluate the expression to create the value only once for the
given component. ‘private’ means the value is only available inside the
component definition, and not to other components.
One thing that’s a little confusing is that although the configuration looks a
bit like Java, it isn’t. In particular, the order that expressions appear has
no bearing on the order in which they are evaluated. Each expression,
‘a=<expr>;’ is stand-alone.
Hope this helps,
Greg Trasuk.
On Jul 23, 2014, at 11:58 PM, Gus Heck <[email protected]> wrote:
> 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