0

I am trying to inject factory to my application. For this I have created

Factory: DrawShapeFactory.java

public class DrawShapeFactory implements Factory<Shape>
{
public void execute(Shape s)
{
    s.draw();

}

@Override
public void dispose(Shape shape) 
{
    // TODO Auto-generated method stub

}

@Override
public Shape provide() 
{
    // TODO Auto-generated method stub
    return null;
}

Create Binder class: DrawShapeBinder.java

 public class DrawShapeBinder extends AbstractBinder
{

 @Override
  protected void configure() 
   {
     bind(DrawShapeFactory.class).to(DrawShapeFactory.class);
   }
}

ResourceConfig file

public class App extends ResourceConfig 
{
public App()
{
    packages("com.icube.rest.authorize","com.icube.rest.test");
    register(new DrawShapeBinder());
}
}

Having classes:

Shape.java

 public class Shape 
{
    public void draw()
    {

    }

}

Circle.java

public class Circle extends Shape
{
    public void draw() 
    {
        System.out.println("===>>> Circle draw <<<<========");
    }


}

Tringle.java

public class Tringle extends Shape
{

    public void draw() {

        System.out.println("===>>> Tringle draw <<<<========");
    }

}

Square.java class having @inject

public class Square extends Shape
{
    @Inject DrawShapeFactory drawShapeFactory;
    public void drawTest() 
    {
        System.out.println("===>>> Square draw <<<<========");
        drawShapeFactory.execute(new Circle());
    }

}

My Resource code is

@SuppressWarnings({"cast"})
@Path("/auth")
public class AuthResource 
{
    //inject here
    @Inject DrawShapeFactory drawShapeFactory;

    @POST
    @Path("test") 
    public Detail test() 
    {

        Shape shape1 = new Circle();
        shape1.draw();

        Shape shape2 = new Tringle();
        shape2.draw();

        drawShapeFactory.execute(new Tringle());

        Square s= new Square();
        s.drawTest();
}

I am getting output with error like:

 ===>>> Circle draw <<<<========
 ===>>> Tringle draw <<<<========
 ===>>> Tringle draw <<<<========
 ===>>> Square draw <<<<========
 java.lang.NullPointerException
 com.icube.rest.test.Square.drawTest(Square.java:11)

Why I am getting NULL in Square.java class for @Inject DrawShapeFactory drawShapeFactory; at drawShapeFactory.execute(new Circle()); line ?

Inject is working fine at resource layer but inside any other class it is giving me NULL exception.

What am I doing wrong ?

Thanks :-)

unknownbits
  • 2,855
  • 10
  • 41
  • 81
  • The `Square` never goes through the IoC container. You can't just instantiate `Square` and exception HK2 to know about it. You need to either inject the `Square` into wherever you need it, or get it from the `ServiceLocator`. You will also need to bind the `Square` in your binder so that it's known in the system. – Paul Samsotha May 15 '17 at 11:38
  • @peeskillet I just want to Inject DrawShapeFactory class in Square.java class file. Can you please help me in this. oe you can provide me a good link from where I can get all this details about inject. THanks – unknownbits May 15 '17 at 11:49
  • Honestly, your code looks so crazy to me. It would make more sense with a real world example. I don't want to encourage any bad practices. If you want to post a real example and explain what you really want to accomplish, I'll look at it. Other than that, if you want some resources, you can check out the links in [this post](http://stackoverflow.com/a/29275727/2587435) – Paul Samsotha May 15 '17 at 12:08

1 Answers1

1

Inject is working fine at resource layer but inside any other class it is giving me NULL exception.

Both Injector and Injectee need to be HK2 aware for the @Inject annotation to work. Jersey Resources are implicitly HK2 aware and hence you are able to bind your factory in resource whereas class Square is not HK2 Aware (Not known inside HK2 Context, because you have not bound it in your Binder).

Apart from that, I can say that your DI concepts are not clear, Instead of binding factory itself your binder should bind the factory to an instance and you should inject the Shapes directly.

For. Eg.

bindFactory(DrawShapeFactory.class).to(Shape.class)

and implement the provide method, to create and return instances of Shape type.

  • now getting this error: A MultiException has 3 exceptions. They are: 1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=DrawShapeFactory,parent=AuthResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1117365981) – unknownbits May 15 '17 at 10:43
  • Downvote? Seriously? anyways, if you tried my solution then you would `@Inject` `Shape` and NOT `DrawShapeFactory`. If you just want to Inject Factory into Square SOMEHOW, you can do `bind(DrawShapeFactory.class).to(DrawShapeFactory.class);` `bind(Square.class).to(Sqaure.class);` and then do `@Inject Square square;` in AuthResource, so that whenever AuthResource is invoked it will ask HK2 to create and Inject a Square instance and then @Inject in Square class will work as you intend to. But let me tell you again what you are trying is total crazy. – Saumitra R. Bhave May 15 '17 at 14:17
  • A Factory is also a service and can be injected as itself, but it isn't normally done. When you do just a bindFactory(DrawShapeFactory.class).to(Shape.class) that is putting both the DrawShapeFactory AND the Shape in the hk2 registry as services that can be injected into other services – jwells131313 May 16 '17 at 12:47