Help

I'm the creator of Hibernate, a popular object/relational persistence solution for Java, and Seam, an application framework for enterprise Java. I've also contributed to the Java Community Process standards as Red Hat representative for the EJB, JPA, JSF specifications and as spec lead of the CDI specification. At Red Hat, I'm currently working on Ceylon, a new programming language for the JVM.

I also post stuff on G+.

Location: Guanajuato, Mexico, cabrones!
Occupation: Fellow at JBoss, a Division of Red Hat
Archive 'Weld'
My Books
Java Persistence with Hibernate
with Christian Bauer
November 2006
Manning Publications
841 pages (English), PDF ebook
Hibernate in Action
with Christian Bauer
August 2004
Manning Publications
408 pages (English), PDF ebook
17. Nov 2009, 03:45 CET, by Gavin King

A developer new to Java EE posted in the Weld forum asking for advice on getting started learning EE 6. I've decided to promote part of my response in the forum to the blog.

So, what should I start learning. Java EE 5 and Seam? Java EE 6 and Weld? Is there any learning material about 6 and Weld right now?

Unless you plan on putting your system into production inside the next 2-3 months, you should start learning CDI and Weld. CDI defines the basic infrastructure you'll use to get the various kinds of Java EE components working together (and much more).

You also need to decide what web framework to use. This is the hard bit for most people.

  • You could use plain servlets and JSP, which in EE 6 both include out-of-the-box CDI integration. However, most people prefer to use something with more features. But honestly, if you're new to enterprise Java, it's not a bad place to start. The latest servlet spec lets you use annotations, which is a big step forward in usability.
  • JSF2 is included as part of the platform, and is integrated with CDI out of the box. Many people find JSF difficult to learn. We believe that for some kinds of applications, it pays off in the end. Unfortunately, most of the books and articles about JSF make it appear much more complex than it actually is. In particular, the specification is horribly written and not worth reading (so I won't link to it). Take a look at the Weld examples to get a taste of what JSF2 is really like.
  • An option we recommend is Wicket. Wicket is an alternative to JSF that is easier to learn. Weld comes with Wicket integration.
  • There are many other possibilities including about a thousand frameworks which are basically alternatives to the servlet API. Struts2 and Stripes seem like popular options. I don't find any of these kinds of frameworks very interesting or sexy, but they're usually easy to learn. It should be very relatively easy to integrate any of them with Weld.
  • A final option worth mentioning is GWT. GWT is an entirely different beast, with its own Java to JavaScript compiler. It's great for certain kind of application. We should have GWT integration for Weld available very soon.

My personal view is that you should start out by looking at either JSF and/or Wicket, unless you're truly a beginner at this, in which case start with writing some plain servlets. If these options don't suit your needs, cast a wider net.

You'll also need a persistence solution. For most people writing EE 6 applications that means JPA2. There are at least three excellent implementations of this specification to choose from, including ours. You'll probably want to use JPA2 together with Bean Validation.

Once you've got a handle on CDI, JPA2, and whatever web framework you decide to use, take a look at EJB 3.1, and the more advanced functionality it offers for integrating with data stores and messaging, and managing asynchronicity. Unfortunately, the EJB spec itself is quite hard to read, so you should probably try to find a good tutorial. Be careful, there is still a lot of information about EJB 2 out there on the web. EJB 3.1 is a quite different beast.

16. Nov 2009, 14:35 CET, by Gavin King

One of the nicest features of CDI is the portable extension SPI. According to the spec:

A portable extension may integrate with the container by:
  • Providing its own beans, interceptors and decorators to the container
  • Injecting dependencies into its own objects using the dependency injection service
  • Providing a context implementation for a custom scope
  • Augmenting or overriding the annotation-based metadata with metadata from some other source

We've got plenty of examples of CDI application code floating about, but not much in the way of examples for framework developers who want to integrate with CDI, or augment the built-in functionality. So here's a little taste of the what a CDI portable extension looks like.

Let's start with an example of an extension that provides support for the use of @Named at the package level. The package-level name is used to qualify the EL names of all beans defined in that package.

Portable extensions implement the marker interface Extension and observe container lifecycle events, in this case ProcessAnnotatedType, an event that is fired by the container when it discovers a class or interface in a bean archive. The portable extension wraps the AnnotatedType object and overrides the value() of the @Named annotation of the bean.

public class QualifiedNameExtension implements Extension {

    <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> pat) {

        //wrap this to override the annotations of the class
        final AnnotatedType<X> at = pat.getAnnotatedType();

        AnnotatedType<X> wrapped = new AnnotatedType<X>() {

            @Override
            public Set<AnnotatedConstructor<X>> getConstructors() {
                return at.getConstructors();
            }

            @Override
            public Set<AnnotatedField<? super X>> getFields() {
                return at.getFields();
            }

            @Override
            public Class<X> getJavaClass() {
                return at.getJavaClass();
            }

            @Override
            public Set<AnnotatedMethod<? super X>> getMethods() {
                return at.getMethods();
            }

            @Override
            public <T extends Annotation> T getAnnotation(final Class<T> annType) {
                if ( Named.class.equals(annType) ) {
                    class NamedLiteral 
                            extends AnnotationLiteral<Named> 
                            implements Named {
                        @Override
                        public String value() {
                            Package pkg = at.getClass().getPackage();
                            String unqualifiedName = at.getAnnotation(Named.class).value();
                            final String qualifiedName;
                            if ( pkg.isAnnotationPresent(Named.class) ) {
                                qualifiedName = pkg.getAnnotation(Named.class).value() 
                                      + '.' + unqualifiedName;
                            }
                            else {
                                qualifiedName = unqualifiedName;
                            }
                            return qualifiedName;
                        }
                    }
                    return (T) new NamedLiteral();
                }
                else {
                    return at.getAnnotation(annType);
                }
            }

            @Override
            public Set<Annotation> getAnnotations() {
                return at.getAnnotations();
            }

            @Override
            public Type getBaseType() {
                return at.getBaseType();
            }

            @Override
            public Set<Type> getTypeClosure() {
                return at.getTypeClosure();
            }

            @Override
            public boolean isAnnotationPresent(Class<? extends Annotation> annType) {
                return at.isAnnotationPresent(annType);
            }
            
        };

        pat.setAnnotatedType(wrapped);
    }
    
}

We need to deploy this portable extension in a jar containing a file named javax.enterprise.inject.spi.Extension in the META-INF/services directory. This file should contain the full name of our QualifiedNameExtension class.

Here's a second example, of a portable extension that creates Bean objects for each class in a set of classes and registers the beans with the container. This is similar to what the container does for classes it discovers in bean archives.

public class RegisterExtension implements Extension {
    
    List<Class<?>> getBeanClasses() { 
        //get some classes from somewhere
    }
    
    void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
        for ( final Class c: getBeanClasses() ) {
            
            //use this to read annotations of the class
            AnnotatedType at = bm.createAnnotatedType(c); 

            //use this to create the class and inject dependencies
            final InjectionTarget it = bm.createInjectionTarget(at); 

            abd.addBean( new Bean() {
    
                @Override
                public Class<?> getBeanClass() {
                    return c;
                }
    
                @Override
                public Set<InjectionPoint> getInjectionPoints() {
                    return it.getInjectionPoints();
                }
    
                @Override
                public String getName() {
                    return null;
                }
    
                @Override
                public Set<Annotation> getQualifiers() {
                    Set<Annotation> qualifiers = new HashSet<Annotation>();
                    qualifiers.add( new AnnotationLiteral<Default>() {} );
                    qualifiers.add( new AnnotationLiteral<Any>() {} );
                    return qualifiers;
                }
    
                @Override
                public Class<? extends Annotation> getScope() {
                    return Dependent.class;
                }
    
                @Override
                public Set<Class<? extends Annotation>> getStereotypes() {
                    return Collections.emptySet();
                }
    
                @Override
                public Set<Type> getTypes() {
                    Set<Type> types = new HashSet<Type>();
                    types.add(c);
                    types.add(Object.class);
                    return types;
                }
    
                @Override
                public boolean isAlternative() {
                    return false;
                }
    
                @Override
                public boolean isNullable() {
                    return false;
                }
    
                @Override
                public Object create(CreationalContext ctx) {
                    Object instance = it.produce(ctx);
                    it.inject(instance, ctx);
                    it.postConstruct(instance);
                    return instance;
                }
    
                @Override
                public void destroy(Object instance, CreationalContext ctx) {
                    it.preDestroy(instance);
                    it.dispose(instance);
                    ctx.release();
                }
                
            } );
        }
    }
    
}

UPDATE: I've finally got a proper chapter on portable extensions written up in the Weld reference documentation. Check out chapter 16 of this version if this post piqued your interest.

14. Nov 2009, 11:31 CET, by Gavin King

William Drai has blogged about his experience integrating Granite DS and CDI.

Our feeling is that JCDI is a perfect fit for Flex RIAs with an event-driven architecture. JCDI applications look extremely clean and even though JBoss Seam provides a lot more features, they do not necessarily make sense with a RIA front-end.

The mapping to Flex does look very clean to me. I especially like what William has done with mapping CDI events into the client. Very nice, and very faithful to CDI.

13. Nov 2009, 11:36 CET, by Gavin King

I've written a couple of posts about using @Alternative to achieve deployment-time polymorphism. What I've never really talked about is its role in CDI modularity.

Modularity and alternatives

From our point of view, support for modularity in dependency management means that injection points of the same type, in different modules, can resolve to different beans. For example, suppose I have an interface Supplier, with two implementations. Let's say they are beans like BookSupplier and CameraSupplier, but they could easily be something more exotic. Now, in one module, bookshop.war, of my application, I have a BookShop:

class BookShop {
   @Inject
   BookShop(Supplier supplier) { ... }
   ...
}

In another module, camerashop.war, I have a CameraShop:

class CameraShop {
   @Inject
   CameraShop(Supplier supplier) { ... }
   ...
}

Now, how does the container tell that the Supplier in BookShop is a BookSupplier, but the Supplier in CameraShop is a CameraSupplier?

Well, there's two possibilities:

BookSupplier and CameraSupplier are deployed in different modules

Suppose that BookSupplier and CameraSupplier are deployed in separate modules, books.jar and cameras.jar respectively. Then the solution is easy. Just declare that bookshop.war depends on books.jar and that camerashop.war has a dependency to cameras.jar, and we're done. That's enough information for CDI to know what to inject where.

So bookshop.war would contain the following line in MANIFEST.MF:

Class-Path: books.jar

Meanwhile, camerashop.war would contain this line in its MANIFEST.MF:

Class-Path: cameras.jar

BookSupplier and CameraSupplier are deployed in the same module

But what if BookSupplier and CameraSupplier are both deployed in suppliers.jar? Well, there's a solution in this case, too.

First we need to add the @Alternative annotation to BookSupplier and CameraSupplier. @Alternative tells CDI not to inject a bean into a module that does not explicitly declare its dependency to the bean.

Next, we need to declare the appropriate alternative in each module. In bookshop.war, we specify:

<beans>
   <alternatives>
      <class>org.mydomain.supplier.BookSupplier</class>
   </alternatives>
</beans>

In camerashop.war, we specify:

<beans>
   <alternatives>
      <class>org.mydomain.supplier.CameraSupplier</class>
   </alternatives>
</beans>

And now each module has it's own, private, implementation of Supplier.

What if BookShop and CameraShop are deployed in the same module?

I suppose, at this point, you're wondering what happens if the clients, BookShop and CameraShop are deployed in the same module. Well, in this case we need to look for another solution. CDI doesn't support more granular alternative activation. There are no bean-level or package-level alternatives. (At least not in this release of CDI.)

Instead we need to add a qualifier, for example:

class BookShop {
   @Inject
   BookShop(@Supplies(Book.class) Supplier supplier) { ... }
   ...
}

or, more likely, add a generic type parameter to Supplier:

class BookShop {
   @Inject
   BookShop(Supplier<Book> supplier) { ... }
   ...
}

Unified EL

The example we've worked with involves Java classes using injection to obtain their dependencies. But what about JSP or JSF pages, which use Unified EL expressions to interact with beans. Well, happily, exactly the same rules apply during EL name resolution.

Modularity beyond Java EE

I've given examples from the Java EE environment. In this environment, a module is a Java EE module like a war, EJB jar or rar, or a library jar. But what about other module architectures like OSGi or a future Java language-level module system?

Well, the CDI spec is slightly future-proof in this respect. This functionality is defined for an abstract notion of a module in an abstract module architecture. So it's more or less well-defined what a CDI implementation should do in an OSGi architecture, if it wanted to support OSGi.

11. Nov 2009, 07:10 CET, by Gavin King

Today, Red Hat submitted the final draft of JSR-299[1], which now goes under the moniker CDI (Contexts and Dependency Injection), along with the Reference Implementation and TCK. Check out the spec[1] and Javadoc.

This specification defines a powerful set of complementary services that help improve the structure of application code.
  • A well-defined lifecycle for stateful objects bound to lifecycle contexts, where the set of contexts is extensible
  • A sophisticated, typesafe dependency injection mechanism, including the ability to select dependencies at either development or deployment time, without verbose configuration
  • Support for Java EE modularity and the Java EE component architecture - the modular structure of a Java EE application is taken into account when resolving dependencies between Java EE components
  • Integration with the Unified Expression Language (EL), allowing any contextual object to be used directly within a JSF or JSP page
  • The ability to decorate injected objects
  • The ability to associate interceptors to objects via typesafe interceptor bindings
  • An event notification model
  • A web conversation context in addition to the three standard web contexts defined by the Java Servlets specification
  • An SPI allowing portable extensions to integrate cleanly with the container

I would like to take this opportunity to thank the Expert Group and everyone else who contributed ideas and criticism to this specification. Folks outside the JCP probably can't really imagine the incredible investment of time and emotional energy that it takes to create a spec like this. I would really, really like to single out a couple of individual members of the EG for their great ideas and totally uncompensated work, but I guess there's no way to do that without leaving someone feeling unrecognized.

On a more personal note, I believe (and hope) that we've done right by the community, and created something beautiful.

Tomorrow we'll be releasing Weld 1.0.

Showing 6 to 10 of 14 blog entries tagged 'Weld'