The Artima Developer Community
Sponsored Link

Turn, and Face the Strange
Dependency Injection and Jini Configurations
by Calum Shaw-Mackay
August 23, 2005
Summary
Okay this came from a little idea I had last night for Neon, and from a bit of playing around with those ideas - dependency injection from Jini configuration files.

Advertisement

Dependency injection, for those few who haven't heard of it, is closely linked to moving the responsibilty for creation and retrieval of dependent objects, outside of your classes and modelling that responsibility within a framework environment, essentially the opposite of Service Locator.

DI is also closely linked (for better or worse) with XML configurations. One of the things that I've been considering in Neon, is whether Dependency Injection can work across an environment where mobile code is employed and objects can move around a network. As part of this, I've not really wanted to increase the number of things you have to deal with in Neon - you have to build an agent, and you can supply a Jini configuration file, but you can also supply a constraints file (a kind of simple set of QoS requirements) which can also be decribed in a Jini configuration file......so the next step when looking at Neon, was "Could I model DI in a Jini configuration?". This is a blog of my experiences so far.

Okay, a bit of background on Jini configuration files. Basically Jini allows you to specify deployment time considerations in a separate file, that can be read by your service at runtime, so for instance you may want to export your service in development with a simple non-secure exporter, however when you move into production, you can specify secure SSL exporters with JAAS, etc. without having to mess with your code. Here there is a similarity in what happens with DI.

However, DI also does the injection (hence the name) of field values (through either setter or constructor injection) from this configuration file, so that when you want to know the name of, say, the JDBC driver you will use, you don;t have to retrieve it yourself. With Jini you have to obtain this from a Configuration instance, using Configuration#getEntry(component,entry,typeclass). Jini Configuration files have a java like syntax and perform construction of objects when you ask for the entry. An example is given below

import net.jini.lookup.entry.*;
import net.jini.core.entry.*;

//Component Name
org.sample.myproduct{ 
	//entryName = entryValue
	simpleString = "abc"; 
	testString=simpleString;
	logLevel="FINEST";	
	groups=new String[]{"production"};
	initialLookupAttributes = new Entry[] {new Name("TestingConfigScan")};
}

So a Jini configuration provider will take care of creating your objects, and you can call static methods in a configuration file, but not methods on an instance so for instance I could call String.valueOf(...), but not simpleString.substring(...)

Now here's where a bit of magic comes in (but only a little), to do some form of Dependency Injection. If we assume certain things about the component name, and look for certain type of setter methods, we could do the following.

  1. Parse the configuration files (in some way)
  2. Use the component names as recognisers for classes passed to the injector
  3. For methods in the class passed that match set<entryname> for any given entryname in the Jini component, we get the value out of the Jini configuration and then call the method to set it.

I'll go through an example with some simple POJOs and a Jini configuration file.
import net.jini.lookup.entry.*;
import net.jini.core.entry.*;

import net.jini.jeri.*;
import net.jini.jeri.tcp.*;

org.jini.projects.neon.di.Simple{ // <= This refers to a class name
	SimpleString = "abc"; 
	testString=SimpleString;
	logLevel="FINEST";
	
	groups=new String[]{"production"};
	initialLookupAttributes = new Entry[] {new Name("TestingConfigScan")};
	myExporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory());	
	theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1");
}	
And a class definition (I've removed getters for brevity)
class Simple {
	private String testString;
	private Entry[] initialLookupAttributes;
	private Exporter myExporter;
	private Dependent theDependent;

	public void setTheDependent(Dependent theDependent) {
		this.theDependent = theDependent;
	}

	public void setTestString(String testString) {
		this.testString = testString;
	}

	public void setInitialLookupAttributes(Entry[] initialLookupAttributes) {
		this.initialLookupAttributes = initialLookupAttributes;
	}

	public void setMyExporter(Exporter myExporter) {
		this.myExporter = myExporter;
	}
}
You'll note that the configuration file contains this line:
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1");
This line refers to a dependent reference that also needs to be created, so we can add the following lines to the configuration file
org.jini.projects.neon.di.Dependent$Test1{
	myString="Hello";
}

org.jini.projects.neon.di.Dependent$Test2{
	myString="There";
}
And create another class:
class Dependent {
	private String myString;

	public String getMyString() {
		return myString;
	}

	public void setMyString(String myString) {
		this.myString = myString;
	}

	public String toString() {
		return myString;
	}
}
I can then change the reference in the org.jini.projects.neon.di.Simple component from
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1");
to
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test2");
And the injection that occurs will refer to a "differently set" instance of org.jini.projects.neon.di.Dependent.
So calling Dependent#toString() will now output "There" instead of "Hello"

Although, this is not anywhere near as complicated or powerful as say Spring's DI framework and configration files, it's not bad for a morning's work!

Talk Back!

Have an opinion? Be the first to post a comment about this weblog entry.

RSS Feed

If you'd like to be notified whenever Calum Shaw-Mackay adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Calum Shaw-Mackay is an architect on Java and Jini systems, working in the UK. His interests lie in distributed computing, adaptability, and abstraction. Calum has been using Jini for longer than he would care to mention. His main area for taking the blame (some people would call it 'expertise') is systems integration and distributed frameworks, and is an advocate of using Jini's unique strengths to build adaptable enterprise systems. His opinions are his own. He's tried to get other people to take his opinions off him, but they just won't.

This weblog entry is Copyright © 2005 Calum Shaw-Mackay. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use