0

I am studying Weld Event from jboss weld event tutorial and I want to write an example which observes an event and print helloword when it was fired.

this is my code:

//MyEvent when it was fired, print HelloWorld
public class MyEvent{}

//observe MyEvent and when it happen print HelloWorld
public class EventObserver {
    public void demo(@Observes MyEvent event){
        System.out.println("HelloWorld");
    }
}

//Main Class fire Event in demo method
public class EventTest {
    @Inject @Any Event<MyEvent> events;
    public void demo(){
        Weld weld = new Weld();
        WeldContainer container = weld.initialize();
        events.fire(new MyEvent());
        container.shutdown();
    }
    public static void main(String[] args){
        EventTest test = new EventTest();
        test.demo();
    }
}

it doesnt work and give below exception info:

Exception in thread "main" java.lang.NullPointerException
       at weldLearn.event.EventTest.demo(EventTest.java:18)
       at weldLearn.event.EventTest.main(EventTest.java:24)

it seems that there are no beans in container which can initialize

Event<MyEvent> events;

Then what should I do to make it running, my beans.xml is empty

  • Maybe I should do something in beans.xml?
  • or I should write a java class implements Event interface?
    anything will be apprecited.
nail fei
  • 2,179
  • 3
  • 16
  • 36
  • Class with injection should be part of container, that is it should be instantiated after container creation and has annotation for class. You should add annotations to Event, EventObserver, split EventTest into boostrap creating container and @Inject-able class. beans.xml can define beans, but it still will not help unless you split EventTest class – Alexander Anikin Dec 26 '16 at 09:20
  • @ Alexander Anikin `@Inject @Any Event events;` I think I have add annotation to Event but the trouble does happen at this place. I think I dont understand your idea fully, can you give more details? Thank you. – nail fei Dec 26 '16 at 12:18
  • 1
    EventTest can not use container injections directly, since injections will not be served by the time class instance is created. Take a look at Java SE 6 example here: https://antoniogoncalves.org/2011/01/12/bootstrapping-cdi-in-several-environments/ – Alexander Anikin Dec 26 '16 at 13:42

1 Answers1

0

Basically, your code fails because you're not using a managed instance of your class. Here's a better way to do it

@ApplicationScoped
public class EventTest {
  @Inject Event<MyEvent> events;
  public void demo(){
      events.fire(new MyEvent());
  }
  public static void main(String[] args){
    Weld weld = new Weld();
    WeldContainer container = weld.initialize();
    EventTest test = container.select(EventTest.class).get();
    test.demo();
    container.shutdown();
  }
}

You start the container in main, and use a managed reference to your class. Injection points are only resolved when you're using managed references.

John Ament
  • 11,595
  • 1
  • 36
  • 45