In my current project I have 2 modules ModuleA and ModuleB, and inside ModuleA and ModuleB I have a class called 'Student' (same class name, same attributes, but for some purpose ModuleA must call ModuleB to do the actual task). They communicate to each other through Web Services. Now I want ModuleA web service to call ModuleB proxy to do the actual task.
In my ModuleA web service I have a method to create a record:
public void createStudent(ModuleA.Student student){
// Here will call ModuleB proxy to do the actual task which is create.
*moduleBFacade().createStudent( );*
}
In my ModuleB Proxy:
public void createStudent(ModuleB.Student student){}
So now the problem is, I cannot pass the moduleA object into the createStudent method as it only takes moduleB objects as arguments.
Any idea how to deal this problem? Please give me some suggestions.
As you are invoking with WS can you convert the moduleA.Student to xml and then change the namespace of the xml and then instantiate a moduleB.Student object from xml.
Something like:
String xmlA = moduleA.Student.toXml();
//Change namespace. Also, Compare the genrated xml of ModuleA and ModuleB.
ModuleB.BStudent studentB= StudentDocument.Factory.parse(xmlA, ..);//second argument can be diff namespace
*moduleBFacade().createStudent(studentB);
You cannot change the class of an object in Java. Also, you cannot "merge" two classes into one class. What you could do is to introduce a common interface, but for that you must own the sourcecode of both classes.
Given the constraint that you can change neither of the two classes, then manually converting ModuleA.Student to ModuleB.Student and back is the best option you get.
PS: as an alternative you can use reflection. Given that both classes have the same attribut names, then mapping from one class to the other should not be a problem.
public static <A,B> B convert(A instance, Class<B> targetClass) throws Exception {
B target = (B) targetClass.newInstance();
for (Field targetField: targetClass.getFields()) {
Field field = instance.getClass().getField(targetField.getName());
targetField.set(target, field.get(instance));
}
return target;
}
Usage:
StudentB studentB = convert(studentA, StudentB.class);
The example above assumed that all fields are private. If they are not, then the same can be can done with methods (module mapping setter names to getter names).
Circular dependency == bad design.
Redesign the modules to remove the circular dependency.
Might not sound right, but here:
Java code
supposing student object passed is of type ModuleAStudent
//create a new bStudent with main criteria
ModuleBStudent bStudent = new ModuleBStudent();
bStudent.setStudentId(student.getStudentId());
bStudent.setStudentNo(student.getStudentNo());
//finally
moduleBFacade().createStudent(bStudent);
UPDATE
Since your object is the same in the two packages and you are making a web service, i would suggest this Simple framework, yea its called Simple actually. Simple helps you serialize your object to XML and deserialize it back, pretty Simple.
You can use BeanUtils.copyProperties to copy to similar beans (note, this is a shallow copy)
Related
I am creating a game where characters can have modules attached to them which provide extra functionality, for example there could be a 'banker' module which listens for a click event and opens a menu for banking. Modules are user creatable by extending the Module class and registering an instance with a ModuleFactory. Modules are able to serialize themselves and load themselves from a serialized form (saving to XML) when is passed in the constructor.
The problem I am having is that when loading the modules I have the name and an instance of every module but I cannot make a new instance of each module.
Is it acceptable to make a newInstance() method inside of each module which returns an instance of the module?
I know it is possible to use reflection for this but most of the time I find reflection to be more trouble than the benefits I get from it.
It is possible to do something like this, since you said you already know the names of each Module (hopefully in some sort of list).
Class<?> temp = Class.forName("ModuleName");
Object obj = temp.newInstance();
This is actually reflection.
Originally I had this, but my above code is superior, because this will require you to have a method that creates a new instances inside each Module. It works, but it is messy. Think of it as this, an object that creates a clone of itself, that is just weird.
public static Module createInstance()
{
return new ThisModule();
}
If you want a new instance as a copy of the existing instance, you can use the clone method,
Otherwise create a factory method which creates instances for you,
public static Module createInstance(){
return new Module();
}
I m not sure if I completely understood what you want
Create a static method in each module to instantiate. This is static factory method. Effective java book says it is indeed good practice to create objects through static factory methods.
I think we can call static methods on objects( though not a good practice).
If i understand you right, you want to extend the behavior of an object and be able to send/serialize it via XML to a client and back (frontend <-> backend communication).
I think what you are looking for is something like a decoration for your Modules and Submodules. Maybe you should build them decoratable to each other, like an InputStream.
something like this:
MyBaseModule base = new MyBaseModule();
BankerModule banker = new BankerModule(base);
ExtendedBankerModuler extBanker = new ExtendedBankerModule(banker);
Maybe call extBanker.toXML() to get the XML to send it to the frontend.
You can wrap each module with the tags of the decorations ones...
<serialized>
<module>
<type>ExtendedBankerModule</type>
<description>extended banker module</description>
<decorates>
<module>
<type>BankerModule</type>
<description>banker module</description>
<decorates>
<module>
<type>MyBaseModule</type>
<description>basic module</description>
<decorates></decorates>
</module>
</decorates>
</module>
<decorates>
</module>
</serialized>
I want to conduct a chain of processing elements and wire them together via Guice. Let's assume the following path:
interface A implemented by class AImpl needs some input
interface B implemented by class BImpl needs A
interface C implemented by class CImpl needs B
interface D implemented by class DImpl needs C
The dependency of A can only be resolved at runtime and not at configuration time. The usual approach would be to use Assisted Injection in this case to create a factory, that takes the missing instances as parameters, just like this:
public interface AFactory {
public A createA(String input);
}
But what I actually want is something like this:
public interface DFactory {
public D createD(String inputForA);
}
I don't want to manually pass AImpl-specific dependencies through the whole hierarchy.
Is it possible to achieve this with Guice? If not, what's the best way to circumvent this problem elegantly while still retaining benefits of injection?
Cheating way: Stick input in a static variable or singleton ThreadLocal. Set it before your pipeline starts and clear it after it ends. Bind everything else through DI.
Fancy way: In A, refer to a #PipelineInput String inputString but don't bind it in your main injector. Otherwise, bind dependencies as you normally would, including referring to #PipelineInput in other pipeline-related classes. When you do need a D, get it from your implementation of a DFactory, which I'm calling PipelineRunner.
public class PipelineRunner {
#Inject Injector injector; // rarely a good idea, but necessary here
public D createD(final String inputForA) {
Module module = new AbstractModule() {
#Override public void configure() {
bindConstant(inputForA).annotatedWith(PipelineInput.class);
}
};
return injector.createChildInjector(new PipelineModule(), module)
.getInstance(D.class);
}
}
Naturally, binding attempts for A, B, C, and D will fail outside of PipelineRunner for lack of a #PipelineInput String--you'll get a CreationException when you create the injector with those unsatisfied dependencies, as you discovered--but those pipeline-based dependencies should be easy to separate into a Module that you install into the child injector.
If this feels too hacky, remember that PrivateModules are also "implemented using parent injectors", and that the whole point of dependency injection is to make a dependency like inputForA available to the whole object graph in a decoupled way.
I see three options. They depend on how often you change the input for A .
1) Bind input as a constant in your module. This works only, if you know that value before you create the Injector and never want to change the value. See bindConstant
2) Use a private submodule which binds either A or the value for input inside that module. Basically you can have two or three instance graphs with different value. See newPrivateBinder.
3) Use a Scope ala RequestScope, SessionScope, ... This way you can change the input often but you must enter/leave the scope at some point to be defined. See Custom Scopes for an example.
First off, I don't think this is necessarily a good idea, I'm just seeing if this is really possible. I could see some benefits, such as not having to explicitly convert to objects that we're sending to the client and using an interface to blacklist certain fields that are security concerns. I'm definitely not stuck on the idea, but I'd like to give it a try.
We're using Spring MVC + Jackson to generate JSON directly from objects. We have our domain object that contains necessary data to send to the client and we have a list of error strings that are added to every outgoing JSON request as needed.
So the return JSON might be something like
{ name: 'woohoo', location : 'wahoo', errors : ['foo'] }
Currently, we have a class that models what should be on the client side, but we always extend a common base class with the error methods.
So, we have:
interface NameAndLoc {
String getName();
String getLocation();
}
and
interface ResponseErrors {
List<String> getErrors();
void appendError(String);
}
We have two classes that implement these interfaces and would like to have CGLIB generate a new class the implements:
interface NameAndLocResponse extends NameAndLoc, ResponseErrors {}
Presently, with CGLIB mixins, I can generate an object with the following:
Object mish = Mixin.create(
new Class [] {NameAndLoc.class, ResponseErrors.class},
new Object [] { new NameAndLocImpl(), new ResponseErrorsImpl() } );
I could then cast the object to either NameAndLoc or ResponseErrors, however, what I would like to do is create an object that uses the same backing classes, but implements the NameAndLocResponse interface, without having to extend our common error handling class and then implement NameAndLoc.
If I attempt to cast with what I have, it errors out. I'm sure this is possible.
I think it is very similar to this, but not quite: http://www.jroller.com/melix/entry/alternative_to_delegate_pattern_with
Simply add the NameAndLocResponse interface to the Class array in the Mixin constructor as the last argument. The resulting object will implement it. You can find an example of this in this blog entry: http://mydailyjava.blogspot.no/2013/11/cglib-missing-manual.html
Background: I'm using Google Guice and so it's easier to pass through the configuration class but I think this is not the best way.
I have a configuration class which stores some paths:
class Configuration{
String getHomePath();
String getUserPath();
}
Also I have a class "a" which needs the "homepath" and a class "b" which needs the "userpath".
Is it better to pass the configuration class through the constructor of class a and b or only pass through the specific path?
If you're really using Guice correctly all your configuration like this should appear in modules' configure method. So:
Remove the configuration class.
Create annotation classes, probably called HomePath and UserPath.
Where class a uses getHomePath() replace that with a String field member named homePath.
Where class b uses getUserPath() replace that with a String field member named userPath.
Modify the class a and b constructors to be #Inject annotated (should already be) and take in a String parameter, respectively annotated with #HomePath and #UserPath and assign the String field member that injected value.
Create bindings in your module's configure method use .annotatedWith() which define correct values; if they're only available at run time, bind a provider.
E.G.
class a {
private String homePath;
#Inject
public a(#HomePath String homePath) {
this.homePath = homePath;
}
public String tellMeAboutHome() {
return "We live in a nice home called " + homePath;
}
}
class customModule extends AbstractModule {
public static final String userPath = "/home/rafael";
public void configure() {
bind(String.class).annotatedWith(HomePath.class).to("/home/");
bind(String.class).annotatedWith(UserPath.class).to(userPath);
}
}
If creating annotations is too much work for you, use the #Named annotation Guice ships with.
There's no single answer to your question, there are only options to choose from, based on your specific situation.
If you know your Configuration class is going to grow AND if it's likely for your A and B classes will use more from it, then pass the whole Configuration object to their constructors. NB: I know this is against the YAGNI principle but sometimes you may know you're gonna need it ;-)
Otherwise, you can consider using #Named injection of your paths so that you reduce A and B classes dependencies to their minimum, which is a good design practice.
The general rule is code to make the dependency graph (which classes know about or depend on other classes/ interfaces) as simple, regular and fixed as possible.
If not passing the Configuration class makes a or b have zero dependencies on on user-written classes, or is necessary to avoid a dependency loop, then use the individual path strings. Otherwise, if it makes more sense to say 'this class has access to configuration info, in a way that may change in the future', pass the class.
I'd avoid the singleton approach, especially if you already have Guice set up.
I have three Modules in Guice:
ReflectionsModule, for providing Metadata (via Reflections)
PersistenceModule, for Data Access Objects and Others
WebModule, for Web Stuff
Simply put, both PersistenceModule and WebModule will fetch a object which is made from Reflections Module. I can not find a very friendly way to do this in guice.
I think PrivateModules will be a suitable way around, but I am not sure how to implement that. Any ideas?
Thank you.
Some additional details
I am using Reflections. It is basically a wrapper to load persistence metadata from a static resource. So basically supposed a parsed XML file into a JavaBean. Thats the concern of the ReflectionsModule.
From this metadata into the javabean, I need to setup the persistence (its a Google App Engine App, using Objectify) and load additional classes and bind them while reading some annotations within. I do not want to load the resource, so I'd like to refer to the resource loaded from the first example.
For now, the ReflectionsModule also binds the two subsequent modules, which I get (correctly) and apply them to the createChildInjector which came when building with just the first module. As os now, it works. I just would like to know which way would be the best one.
Simply speaking, PrivateModules expose only bindings that are explicitly exposed using #Exposed annotation of the .expose() method. Therefore, if PersistenceModule and WebModule are both PrivateModules, you can do the following:
public class WebModule extends PrivateModule {
#Override
public void configure() {
install(new ReflectionsModule());
// do stuff...
expose(SomeClassFromWebModule.class);
}
}
public class PersistenceModule extends PrivateModule {
#Override
public void configure() {
install(new ReflectionsModule());
// do stuff...
expose(SomeClassFromPersitenceModule.class);
}
}
In this way, the bindings from ReflectionsModule will not be exposed further than the two PrivateModules and will therefore not run into each other.
It is generally a good practice to only expose classes that can only be provided by one Module.
EDIT: better answer found: https://stackoverflow.com/a/5504903/105741 - basically use #Provides annotation to get method parameters in your module injected with your dependencies from other modules. Works much nicer. I.e. for the binding that requires the DependencyClass, I move that code into a method, expose it with the #Provides annotation, and add the DependencyClass as a method parameter.
#dyross - I don't think that's what he's asking.
It's not a good idea to create the ReflectionModule more than once, and PrivateModules don't have anything to do with the problem - that of sharing bindings to children modules (if I understand him correctly). I have the same need, and have used the technique of passing in the required object to the children modules ie.
Injector parentInjector = Guice.createInjector(new ParentModule());
DependencyClass dep = parentInjector.getInstance(DependencyClass);
injector = parentInjector.createChildInjector(new ChildModule(dep));
i.e.
Injector reflectionsModule = Guice.createInjector(new ReflectionsModule());
DependencyClass dep = parentInjector.getInstance(DependencyClass);
injector = parentInjector.createChildInjector(
new PersistenceModule(dep),
new WebModule(dep));
Not ideal, but serves the purpose.
It also just occured to me that you could pass in the injector to the child modules too, and getInstance() from directly inside the child modules.