The Artima Developer Community
Sponsored Link

Weblogs Forum
Dependency Injection and Jini Configurations

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Calum Shaw-Mackay

Posts: 58
Nickname: calum
Registered: Mar, 2004

Dependency Injection and Jini Configurations (View in Weblogs)
Posted: Aug 23, 2005 9:03 AM
Reply to this message Reply
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!

Topic: OOP Case Study: The Bank Account Class Previous Topic   Next Topic Topic: For Now, Virtual Methods Are a Better Default


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us