Guice with parents - java

What do I do with Guice when I need to call a parent constructor that is also injectable? e.g. I have an abstract parent class that has a constructor that is injected with an object shared by all derived children and each child also has an injectable constructor.
Calling super() wont work because Java wants me to pass in the object as a paremeter rather than have Guice inject.
Thanks
EDIT: I am wondering if maybe I need to use method injection instead?

You'd need to do the exact same thing you do if you weren't using Guice... declare any parameters the parent constructor requires as parameters to each child's constructor as well, and pass those to super.
So if your abstract parent class's constructor takes a Foo, a child class's constructor needs to look like:
#Inject public ChildClass(Foo foo, Bar bar) {
super(foo);
this.bar = bar;
...
}

Buried in the Minimize Mutability section of the Guice Best Practices, you'll find this guideline:
Subclasses must call super() with all dependencies. This makes
constructor injection cumbersome, especially as the injected base
class changes.
In practice, here's how to do it using constructor injection:
public class TestInheritanceBinding {
static class Book {
final String title;
#Inject Book(#Named("GeneralTitle") String title) {
this.title = title;
}
}
static class ChildrensBook extends Book {
#Inject ChildrensBook(#Named("ChildrensTitle") String title) {
super(title);
}
}
static class ScienceBook extends Book {
#Inject ScienceBook(#Named("ScienceTitle") String title) {
super(title);
}
}
#Test
public void bindingWorked() {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override protected void configure() {
bind(String.class).
annotatedWith(Names.named("GeneralTitle")).
toInstance("To Kill a Mockingbird");
bind(String.class).
annotatedWith(Names.named("ChildrensTitle")).
toInstance("Alice in Wonderland");
bind(String.class).
annotatedWith(Names.named("ScienceTitle")).
toInstance("On the Origin of Species");
}
});
Book generalBook = injector.getInstance(Book.class);
assertEquals("To Kill a Mockingbird", generalBook.title);
ChildrensBook childrensBook = injector.getInstance(ChildrensBook.class);
assertEquals("Alice in Wonderland", childrensBook.title);
ScienceBook scienceBook = injector.getInstance(ScienceBook.class);
assertEquals("On the Origin of Species", scienceBook.title);
}
}

A better alternative is to use something similar to the strategy pattern to encapsulate all the fields the superclass wants to inject, and then the subclass can inject that. For example:
public abstract class Animal {
/**
* All injectable fields of the Animal class, collected together
* for convenience.
*/
protected static final class AnimalFields {
#Inject private Foo foo;
#Inject private Bar bar;
}
private final AnimalFields fields;
/** Protected constructor, invoked by subclasses. */
protected Animal(AnimalFields fields) {
this.fields = fields;
}
public Foo getFoo() {
// Within Animal, we just use fields of the AnimalFields class directly
// rather than having those fields as local fields of Animal.
return fields.foo;
}
public Bar getBar() {
return fields.bar;
}
}
public final class Cat extends Animal {
private final Whiskers whiskers;
// Cat's constructor needs to inject AnimalFields to pass to its superclass,
// but it can also inject whatever additional things it needs.
#Inject
Cat(AnimalFields fields, Whiskers whiskers) {
super(fields);
this.whiskers = whiskers;
}
...
}

Related

How to move an anonymous Provider that references fields in the module into a separate class?

Toy example:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new Provider<Bar>() {
#Override public Bar get() {
return foo.getBar();
}
});
}
}
This lets me lazily invoke the .getBar() method of a user-provided Foo instance stored in a field of MyModule. However now the provider has its own dependencies - hence I need to define a non-anonymous class I specify an #Inject constructor on. Something like:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(BarProvider.class);
}
BarProvider implements Provider<Bar> {
private Baz baz;
#Inject BarProvider(Baz baz) {
this.baz = baz;
}
#Override public Bar get() {
return foo.getBar(baz);
}
}
}
Perfect! Except Guice doesn't like this...
Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Injecting into inner classes is not supported. Please use a 'static' class (top-level or nested) instead of com.example.MyModule$BarProvider.
So, I'm in a bind. I need to access both a field on the module and an injected type from a Provider class at the same time. Is there any way to do this?
Note: this toy example excludes some of the actual complexity - in particular the bind() statement is more involved, which is why I can't simply define an #Provides method.
In part, injecting into an inner class is impossible because Guice can't reflectively create an inner instance without an outer parent instance (the equivalent of the arcane outerInstance.new InnerInstance() syntax).
Some options:
Make Foo injectable through your graph, possibly hidden in a PrivateModule so it's not exposed to your entire graph (if that's important to you).
Use an anonymous inner Provider (or an extracted equivalent), and get a Provider<Baz> from AbstractModule's getProvider(Class<T>) method. You'll get an exception if you try to call that before the Injector is created, but for creating a Provider the way you're doing, that's probably not a problem.
Post your bind outside of a toy problem, to see whether #Provides is possible with some cleverness.
Related: Accessing Guice injector in its Module?
I realize I was getting hung up on having Guice construct my Provider for me, which I don't actually need to do. Despite the example in Guice's documentation passing in a DatabaseTransactionLogProvider.class a better parallel to the first snippet would be to construct an instance of my Provider manually, and pass in both the Foo instance and a Provider<Baz> instance (provided by the module).
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new BarProvider(foo, getProvider(Baz.class));
}
static BarProvider implements Provider<Bar> {
private final Foo foo;
private final Provider<Baz> bazProvider;
BarProvider(Foo foo, Provider<Baz> bazProvider) {
this.foo = foo;
this.bazProvider = bazProvider;
}
#Override public Bar get() {
return foo.getBar(bazProvider.get());
}
}
}

java inheritance setting value in parent class

I have an identical method that is repeated in every subclass and I'd like to refactor it to just one method in a superclass.
public class SubClass1 extends SuperClass {
private BoltHexHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method in all subclasses but Bar formula is different amongst all subclasses
setBar(bolt.getDiameter() - 2*bolt.getPitch() - 3*bolt.getTpi());
}
private void computeSeparation() {
//computeSeparation method only exists for a Subclass 1
setSeparation(bolt.getLength() - 2*nut.getFlatDia());
}
public class SubClass2 extends SuperClass {
private BoltFlatHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method here is different than in Subclass1
setBar(bolt.getDiameter() - 4*bolt.getPitch() - 1/3*bolt.getTpi());
}
private void computeProtrusion() {
//computeProtrusionmethod only exists for a Subclass 2
setProtrusionmethod(bolt.getThreadAngle() - 6*bolt.getTpi());
}
Initially I posted that bolt wasn't getting set in the SuperClass but was in the SubClass. What I got working after my initial post was the following
public abstract class SuperClass {
protected Bolt<?> bolt; <-- this was added but uses wildcard
...bolt getters/setter
protected void computeFoo() {
//Foo formula pulled up from all subclasses
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
}
public class SubClass1 extends SuperClass {
//private BoltHexHead bolt; <-- commented this out in each subclass
}
This is a JSF app and in each controller bean I instantiate the specific joint attribute subclass and then set the specific bolt. It was an earlier design decision to use setters for setting the bolt (and other properties) in the subclass rather than doing it with the Constructor; but one refactor at a time.
Controller for a Bolt Analysis using a HexHead Bolt
private SubClass1 sc1 = new SubClass1();
private BoltHexHead bolt;
sc1.setBolt(bolt);
sc1.computeResults();
Controller for a Bolt Analysis using a FlatHead Bolt
private SubClass2 sc2 = new SubClass2();
private BoltFlatHead bolt;
sc2.setBolt(bolt);
sc1.computeResults();
So my question is, is it OK to use wildcard Bolt<?> bolt or is there a better approach?
I'm just trying to put a identical/duplicate method from all my subclasses into the parent but one of the variables (bolt) isn't getting set
Thats because in java you cannot override fields.
So your variables "private B bolt;" in your superclass and "private BoltHexHead bolt;" in your subclass are two different things. They actually both exist at the same time.
What you are trying to do actually isn't that complicated. You just need to clean up your code:
Only define "private B bolt;" and its setters/getters once in your superclass.
Only use those getters/setters to access bolt
If you want your subclass to have a "bolt" of the type "BoltHexHead" then define the generic parameter as such in the class definition ("extends JointAttribute<BoltHexHead>" instead of "extends JointAttribute<Bolt<BoltSpec>>")
A simple example for demonstration purspose:
Superclass:
public class Superclass<T> {
private T value;
protected T getValue() {
return value;
}
protected void setValue(T value) {
this.value = value;
}
protected void print() {
if(getValue()==null) {
System.out.println("NULL");
} else {
System.out.println(getValue().toString());
}
}
}
Subclass1:
public class Subclass extends Superclass<String> {
public Subclass() {
}
public static void main(String[] args) {
Subclass subclass= new Subclass();
subclass.print();
subclass.setValue("test");
subclass.print();
}
}
Subclass2:
public class Subclass2 extends Superclass<Integer> {
public Subclass2() {
}
public static void main(String[] args) {
Subclass2 subclass= new Subclass2();
subclass.print();
subclass.setValue(3);
subclass.print();
}
}

Java abstract class fields override

I have an abstract class that should implement a public field, this field is an interface or another abstract classe.
something like this:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
Now i have another specialized class Container:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java allow me to compile this, and i IMAGINE that the field child in SpecialContainer is automatically overloading the field child of the GenericContainer...
The questions are:
Am i right on this? The automatic 'overloading' of child will happen?
And, more important question, if i have another class like this:
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test() will return 1 or 2? i mean the GenericContainer container field what prop1 will call, the generic or the special?
And what if the special prop1 was declared as String (yes java allow me to compile also in this case)?
Thanks!
In Java, data members/attributes are not polymorphic. Overloading means that a field will have a different value depending from which class it's accessed. The field in the subclass will hide the field in the super-class, but both exists. The fields are invoked based on reference types, while methods are used of actual object. You can try it yourself.
It's called, variable hiding/shadowing, for more details look on here
It isn't overriding anything, you're just hiding the original field at the current class scope. If you use a variable with the subtype you will still be able to access the original property. Example:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
This prints 1 and then 2.
From SpecialChild you would also be able to go up one level using super:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
Regarding
....and i IMAGINE that the field "child" in SpecialContainer is automatically overloading the field 'child' of the GenericContainer...
No. Fields don't get overridden, only methods do.
This is one reason why use of (overridable) getter and setter methods are preferred to direct access to fields. Your fields should almost all be private.
As for your design, there's no need for your SpecialContainer class to have a SpecialChild field, but instead the SpecialChild object should be placed in the GenericChild field.
Why nobody is observing that program will throw NullPointerException.
subclass's field with same name will hide super class's field. There is no overriding with field. Overriding is only possible with methods.
Original Code by Author:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
Java allow me to compile this, and i IMAGINE that the field "child" in
SpecialContainer is automatically overloading the field 'child' of the
GenericContainer...
Firstly, Inheritence doesn't apply to variables. Fields(Insatnce variables) are not overridden in your sub-class.they are only visible in your subclass if they are marked with either public, protected or default.
To answer your question it maintains both instances. And depending on how you refer to the container (either through the abstract or the impl) determines which variable you are referring to.
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
The bigger question at hand is, why would you design something like this? I'm assuming you are asking from a theoretical perspective.
My 2 cents, this isn't great OO design. You would be better off making the public variables private and assigning their values through a constructor or property setter. As-is, it will lead to unexpected results in your code.

How do I convert an abstract class into an interface?

I have a java program which uses arraylists - these arraylists store 'variables' where 'variables' is an abstract class.
Now, to save memory, I want to use a java library called HugeCollections-VanillaJava- however this library requires an interface to be defined.
How do I convert the abstract class into an interface? What rules/restrictions do I have to follow, to correctly perform the conversion?
Finally, is it possible for me to use my abstract class with minimal code changes, so that the library that requires an interface, also works correctly? Ideally I would like not to change the abstract class at all...Is this possible?
how do I convert an abstract class into an interface?
Make a copy of the abstract class source file.
Change "class" to "interface" in the initial declaration.
Change the name (optionally, depends on what you're doing).
Remove the bodies of any methods that are implemented by the class.
Remove the word "abstract" from the other ones.
Remove all private and protected members.
Remove all constructors.
Remove the keyword "public" from the public members.
If you had any code you removed (implemented methods, private or protected stuff), have your original abstract class implement your interface and leave that stuff there.
(Incomplete) Example:
Foo as an abstract class:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo as an interface:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
In my case, as I did have some stuff the old Foo did, I'd probably have AbstractFoo or something:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...so that an implementation could use it as a starting point if desired (although with that private bar in there, it doesn't make a lot of sense).
Pattern Adapter might help you.
Imagine, you're have to use SomeClass as TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
And they have different signatures of methods - someMethod() and someMethodBlaBla().
So you're might create such adapter class:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
and somewhere in code you might use both - adapter and instance of abstract class, without interference on current code:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
If abstract class does not define any concrete methods, you can even use regular expression for that. From:
public abstract class Abstract {
public abstract void method();
//...
}
to:
public interface Interface {
void method();
//...
}
public abstract modifiers are implicit for interfaces. If the abstract class does define some methods (not all methods are abstract) or have some fields this can't be done (at least easily).

Pass parameter to constructor with Guice

I have a factory as below,
public final class Application {
private static IFoo foo;
public static IFoo getFoo(String bar)
{
// i need to inject bar to the constructor of Foo
// obvious i have to do something, not sure what
Injector injector = Guice.createInjector();
logger = injector.getInstance(Foo.class);
return logger;
}
}
This is the Foo definition:
class Foo
{
Foo(String bar)
{
}
}
OK. I m not sure how I can pass this parameter to Foo constructor with Guice?
Any ideas?
All the "Guice Constructor Parameter" answers seem to be incomplete in some way.
Here is a complete solution, including usage and a visual:
interface FooInterface {
String getFooName();
}
// Annotate the constructor and assisted parameters on the implementation class
class Foo implements FooInterface {
String bar;
#Inject
Foo(#Assisted String bar) {
this.bar = bar;
}
// return the final name
public String getFooName() {
return this.bar;
}
}
// Create a factory interface with a create() method that takes only the assisted parameters.
// FooFactory interface doesn't have an explicit implementation class (Guice Magic)
interface FooFactory {
Foo create(String bar);
}
// Bind that factory to a provider created by AssistedInject
class BinderModule implements Module {
public void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
}
// Now use it:
class FooAction {
#Inject private FooFactory fooFactory;
public String doFoo() {
// Send bar details through the Factory, not the "injector"
Foo f = fooFactory.create("This foo is named bar. How lovely!");
return f.getFooName(); // "This foo is named bar. How lovely!"
}
}
Lots of helps here: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html
What you are probably looking for is to use a Guice factory. Particularly easy with the AssistedInject functionality, but they have a manual example at the top of the page. The short of it for the manual example is that you get the factory under non-static getFoo method that you pass whatever parameters to that you need and build the object from there.
This won't work directly if you have method interception in Foo, but it will work in many other cases.
To use AssistedInject, which to me has somewhat cleaner semantics and means less manual wiring, you'll need the guice-assistedinject extension in the classpath, then when creating Foo (well, FooImpl, we should be using interfaces):
#Inject
public FooImpl(#Assisted String bar)
{
this.baz = bar;
}
Then you create a FooFactory interface:
public interface FooFactory {
public Foo create(String bar);
}
Then in your guice module:
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(FooFactory.class));
You can check out the javadoc for FactoryModuleBuilder for examples with more complex factories.
I know that this is old thread but I just hit the issue myself today.
I only need two or maximum three different instances of 'Foo' and I really didn't want to write all the bolierplate code of Factory.
With a little googling I found this Stubbisms – Tony’s Weblog I would suggest this solution which is perfect if you know exactly what instances you need.
In Guice module:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic A");
}
});
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic B");
}
});
Or in java 8:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first"));
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second"));
And in constructor of your service where you need Foo instances:
#Inject
public MyService (
#Named("firstFoo") Foo firstFoo,
#Named("secondFoo") Foo secondFoo) {
}
And Foo in my case:
public class FooImpl implements Foo {
private String name;
public FooImpl(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
Hope it helps someone.
If this class is a factory, it should be a Guice-managed object, having a non static getFoo method, and the getFoo method would just use
new Foo(bar)
Not every class needs to be instantiated by Guice.
Also see AssistedInject, to avoid creating this factory yourself and let Guice create one for you.
Although this isn't a direct answer to what you're asking, hope it helps. I was trying to understand where the constructor parameters are being passed earlier. If they are custom classes, they should be bind-ed in the module.
Class CustomHandler {
private Config config;
#Inject
CustomHandler(Config config) {
this.config = config;
}
public void handle() {
// handle using config here
}
}
Binding:
class Module extends AbstractModule {
bind(Handler.class).to(CustomHandler.class);
bind(Config.class).to(CustomConfig.class);
}
Injection:
CustomHandler handler = injector.getInstance(CustomHandler.class);
handler.handle();

Categories

Resources