Help

One of the really nice things about Weld is how nicely it works in Java SE. Of course, if you run Weld on its own, you won't get nice functionality like EJBs (you'll need an embeddable EJB container for that), but you do get a bunch of great stuff, including:

  • Managed beans with @PostConstruct and @PreDestroy lifecycle callbacks
  • Dependency injection with qualifiers and alternatives
  • @ApplicationScoped, @Dependent and @Singleton scopes
  • Interceptors and decorators
  • Stereotypes
  • Events
  • Portable extension support

The Weld distribution comes with an example console application, and an example Swing application.

Here's a very simple console application:

@Singleton
public class HelloWorld {

    @PostConstruct
    void init() {
        System.out.println("Initializing Hello World application");
    }

    void printHello(@Observes ContainerInitialized event, 
                    @Parameters List<String> parameters) {
        System.out.println("Hello " + parameters.get(0));
    }

}

The printHello() method is a CDI observer method for the ContainerInitialized event. This event is fired by the Weld Java SE extension when the console application starts. The command line parameters are available for injection using @Parameters List<String>.

As usual, we need a file named META-INF/beans.xml the the jar or classpath directory containing our HelloWorld class.

We run the application using:

java org.jboss.weld.environments.se.StartMain Gavin

Of course, if you're using CDI you probably want to make much more use of dependency injection, for example:

@Singleton
public class HelloWorld {

    void printHello(@Observes ContainerInitialized event, 
                    @Parameters List<String> parameters, 
                    Hello hello) {
        hello.say(parameters.get(0));
    }

}

Where Hello is a bean:

public class Hello {
    public void say(String name) {
        System.out.println("Hello " + name);
    }
}

The Weld SE extension was created by contributor Peter Royle.

13 comments:
 
17. Nov 2009, 08:24 CET | Link

Shouldn't you use @Inject annotation to inject Hello bean into printHello() or @Observes for the event parameter is enough to suggest injection for the other parameters?

ReplyQuote
 
17. Nov 2009, 08:36 CET | Link

@Observes is enough.

 
17. Nov 2009, 12:01 CET | Link
Aslak Knutsen | aslak(AT)conduct.no

A interesting extension to Weld SE is Weld Test. Unreleased as of now, but soon..

It gives you CDI/Weld injection in your test cases. The JUnit version also supports method argument injection.

package org.jboss.weld.test.junit;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(CDIRunner.class)
public class ModelTestCase
{

   @Language(LanguageType.NO)
   private WelcomeService service;

   @Test
   public void shouldBeAbleToInjectInstanceVars() throws Exception
   {
      Assert.assertEquals("Hei " + userName, service.greet(user));
   }

   @Test
   public void shouldBeAbleToInjectParameters(@Language(LanguageType.SE) WelcomeService welcomeService)
         throws Exception
   {
      Assert.assertEquals("Hej " + userName, welcomeService.greet(user));
   }
}

If you want to test it, it can be found at: svn

 
17. Nov 2009, 15:56 CET | Link

Nice, Aslak. I like it.

 
17. Nov 2009, 17:57 CET | Link

Hi. Is it possible to extends all java.awt. and javax.swing. UI component to run well with weld? I know there is JSR 296 to satisfy this, but I think the JSR is not transparent enough.

 
17. Nov 2009, 18:27 CET | Link
xsalefter wrote on Nov 17, 2009 17:57:
Hi. Is it possible to extends all java.awt. and javax.swing. UI component to run well with weld? I know there is JSR 296 to satisfy this, but I think the JSR is not transparent enough.

I'm not sure what you mean by run well. You're thinking of databinding? That's a problem that needs to be solved in Swing, I guess...

 
17. Nov 2009, 19:07 CET | Link

Hmm, since I have try seam in my last project, I have some idea to swing like:

@UI("main")
public class Main extends JFrame {
  
  JMenuItem menuLogin;
  JMenuItem menuLogout;
  
  public MainFrame() {
  // init component..
  }
}

@Controller
public MainApplicationController {
  
  @Inject Main main;
  @Inject AccountingFrame accountingFrame;
  
  @UIEvent(for="menuLogin", at="main")
  public void login() {
    if (validate()) {
        acountingframe.show();
        // other logic after login
    }
  }

  @UIEvent(for="menuLogout", at="main")
  public void logout() {
    mainapps.dispose();
    // Other logic for logout..
  }
}

// etc etc..

I dont know whether this is a good idea, since I know nothing in deep about Weld (Just seam with its seam gen :D ) and just newbie in DI world, but I think I can archive more clarity with this way.

How do you thing?

And, yes, databinding in swing also need an encachement.

 
17. Nov 2009, 19:09 CET | Link
xsalefter wrote on Nov 17, 2009 19:07:
How do you thing?

Upps.. Sorry, typo. What should I write is How do you think?

 
17. Nov 2009, 21:18 CET | Link

Looks untypesafe. The usual swing approach of registering event listeners has the advantage of being typesafe...

 
18. Nov 2009, 23:14 CET | Link

The testing stuff does look nice. Is it easy to integrate with TestNG? Probably just a @BeforeClass or something? Also what do the @Language annotations do?

 
19. Nov 2009, 16:22 CET | Link
Aslak Knutsen | aslak(AT)conduct.no

Weld Test supports both JUnit and TestNG.

The @Language annotation is just a CDI annotation used as a example.. :)

26. Dec 2009, 00:10 CET | Link

Would be great to have sample JUnit base class for test cases that use weld. Like spring test base classes that are injected as well. There was a reference to svn but it seems to be broken?

 
10. Jan 2010, 19:53 CET | Link
Chris

Hi. Test SVN Url is no longer existing.

Post Comment