CDI Extensions JTJ 2012 02

download CDI Extensions JTJ 2012 02

of 28

Transcript of CDI Extensions JTJ 2012 02

  • 8/13/2019 CDI Extensions JTJ 2012 02

    1/28

    Originally developed under the name Web Beans, the

    CDI specification was created to fill the gaps between EJB

    on the back end, and JSF in the view layer. There are cur-

    rently three CDI implementations available: JBoss Weld,

    Apache OpenWebBeans, and Caucho CanDI. Several

    libraries already provide CDI extensions, such as Apache

    DeltaSpike, JBoss Seam 3, and Apache MyFaces CODI.

    Deep-dive into the world of CDI with this issue of JTJ.

    www.jaxenter.comIssue March 2012 |presented by

    #16

    TM

    CDI IntroductionA Hollywood Story

    Extension ProgrammingImplementing AdditionalFunctionality with CDI

    Apache DeltaSpikeCreating a CDI Extension

    ArquillianTestable Development of CDI

  • 8/13/2019 CDI Extensions JTJ 2012 02

    2/28

    2www.JAXenter.com |March2012

    Editorial

    Putting together a JavaTechJournal issue about CDI is ahard task, one might think. But it was actually completelyeasy to get all those busy people on board helping out witharticles.

    There are multiple reasons for this. The first one is that CDIwas a community-driven technology from the very beginning.The Java Expert Group for CDI was open from the verystart and continues to do so. It is one of the prototypes forJSR.next and formed a great community because of this

    openness. And this community gives back 100 times the effortyou put into it.

    The other reason is that its really fun to work with thistechnology. CDI is not some freaky artificial phantasm thathas no common ground with any real business. Nor is it along-time-grown monster that has tons of historical burdento carry with it. If you look at a project using CDI, you get thefeeling that its really done right. Most of the things you dowith CDI just works (tm). CDI felt cool at the first touch but unlike other hyped technologies it still feels cool now,after a few years!

    Whats more, CDI has already proved itself in big projects.

    One of my CDI-based projects went live in August 2010, and

    CDI much morethan a hype!

    it serves more than 40,000 concurrent users, easily getting fivemillion page hits per day. And I do know of big banks andinsurance companies who handle even more throughput withCDI-based projects!

    In this JavaTechJournal, we will cover CDI full circle. Inour introductory article, we will lay out the basics of thedependency injection core itself: its historical background,basic mechanisms, and key features. A second article willprovide the fundamentals of CDI Extension programming,

    demonstrating how the CDI extension mechanism can beused to implement additional functionality in a portable,vendor-independent way. Another article will explain theCDI Ecosystem, showing how the popular projects Seam3and MyFaces CODI became Apache DeltaSpike. Last but notleast, we will shed a light on testing CDI applications with theJBoss Arquillian framework.

    Please allow me to finally thank all the authors and allthose people who helped us reviewing and editing the contentand providing ideas, like Shane Bryzak (JBoss), Matt Benson(ASF) and many more.

    Mark Struberg

    A Hollywood Story 3Contexts and Dependency Injection for Java EE (JSR-299)Mark Struberg and Pete Muir

    CDI Extension Programming 9Implementing additional functionality in a portable, vendor-independent wayRonald Steininger, Arne Limburg, and Mark Struberg

    Apache DeltaSpike Closes the Gaps 14Creating a stable, reliable and truly portable CDI extensionGerhard Petracek and Jason Porter

    Arquillian Makes Testing a Breeze 18Testable development of CDI

    Dan Allen, Aslak Knutsen, and Andrew L. Rubinger

    Index

  • 8/13/2019 CDI Extensions JTJ 2012 02

    3/28

    CDI Introduction

    www.JAXenter.com |March 2012 3

    by Mark Struberg and Pete Muir

    One of the most exciting features of CDI is to allow any-one to write powerful extensions to the core Java EE plat-form, even change core behaviour itself. These extensionsare fully portable across any environment which supportsCDI. Several libraries already provide CDI extensions, suchas Apache DeltaSpike, JBoss Seam 3, and Apache MyFacesCODI.

    A little bit of historyOriginally developed under the name Web Beans, the CDIspecification was created to fill the gaps between Enterprise

    Java Beans (EJB) on the back end, and JavaServer Faces (JSF)in the view layer. The first draft targeted only Java EnterpriseEdition (Java EE), but during the creation of the specification

    it became obvious that most features were very useful for anyJava environment, including Java SE.

    At the same time, both Guice and Spring communities hadbegun an effort to specify the basics of injection as JSR-330:Dependency Injection for Java (nicknamed AtInject).Considering that it did not make sense to provide a new de-pendency injection container without collaborating on theactual injection API, the AtInject and CDI expert groupsworked closely together to ensure a common solution acrossdependency injection frameworks. As a result, CDI uses theannotations from the AtInject specification, meaning that eve-ry CDI implementation fully implements the AtInject specifi-

    cation, just like Guice and Spring. CDI and AtInject are bothincluded in Java Enterprise Edition 6 (JSR-316) and thus anintegral part of almost every Java Enterprise Edition server.

    Contexts and Dependency Injection for Java EE (JSR-299)

    A Hollywood StoryCDI brings Dependency Injection to a new level. Within the first two years of its existence, CDI quickly rose from an

    unknown little JSR to now being unanimously considered the star of Java EE 6. This article provides an overview

    of the major CDI features, explores a sample web application, and outlines some of the basic mechanisms of the

    framework.

  • 8/13/2019 CDI Extensions JTJ 2012 02

    4/28

    CDI Introduction

    www.JAXenter.com |March 2012 4

    Essential CDIBefore we go on to dive into some code, lets take a quick lookat some key CDI features:

    Type Safety: Instead of injecting objects by a (string) name,CDI uses the Java type to resolve injections. When the type

    is not sufficient, a Qualifier annotation can be used. Thisallows the compiler to easily detect errors, and provideseasy refactoring.

    POJOs: Almost every Java object can be injected by CDI!This includes EJBs, JNDI resources, Persistence Units andPersistence Contexts, as well as any object which previ-ously would have been created by a factory method.

    Extensibility: Every CDI container can enhance its func-tionality by using portable Extensions. The attributeportable means that those CDI Extensions can runon every CDI container and Java EE 6 server, no matterwhich vendor. This is accomplished by a well-specified SPI

    (Service Provider Interface) which is part of the JSR-299specification.

    Interceptors: It has never been easier to write your own In-terceptors. Because of the portable behaviour of JSR-299,they now also run on every EE 6-certified server and on allstandalone CDI containers.

    Decorators: These allow to dynamically extend existinginterface implementations with business aspects.

    Events: CDI specifies a type-safe mechanism to send andreceive events with loose coupling.

    Unified EL integration: EL-2.2 opens a new horizon inregard of flexibility and functionality. CDI provides out-

    of-the-box support for it!

    Diving into CDILets start by exploring a sample web application. The ap-plication allows you to send e-mail via a web form fairlysimple. We only provide code fragments, but they should beenough to get the gist of how CDI is used. After showing eachpart of the application, we will discuss the details in the nextchapter.

    For our mail application, we need an application-scopedMailService. Application-scoped objects are essentially sin-gletons the container will ensure you always get the sameinstance whenever you inject it into your application. The re-

    plyToaddress is taken from the ConfigurationServicewhich

    is also application-scoped. Here we see our first injection the configuration field is not set by the applications code,but is injected by CDI. The @Injectannotation tells CDI toperform the injection (listing 1).

    Our application also identifies the current user (note that itdoesnt try to perform any authentication or authorization,we simply trust everyone!), and the current user is scopedto the HTTP session. CDI provides the session scope, whichensures that you will get the same instance of an object perHTTP Session (in a web application).

    By default, CDI beans are not available for use in JSF viathe Unified Expression Language. In order to expose it for useby JSF and EL, we add the @Namedannotation (listing 2).

    Now that we have a working application, lets exploresome of the CDI features we are using.

    Listing 1

    @ApplicationScoped

    public class MyMailService implements MailService {

    private @Inject ConfigurationService configuration;

    public send(String from, String to, String body) {

    String replyTo = configuration.getReplyToAddress();

    ...// send the email

    }

    }

    Listing 2

    @SessionScoped

    @Named

    public class User {

    public String getName() {..}

    ..

    }

    The web page is implemented with JSF 2. We suggest you use a controller

    class:

    @RequestScoped

    @Named

    public class Mail {

    private @Inject MailService mailService;

    private @Inject User user;

    private String text;// + getter and setter

    private String recipient;// + getter and setter

    public String sendMail() {

    mailService.send(user.getName(), recipient, text);

    return "messageSent";// forward to 'message sent' JSF2 page

    }

    }

    The only missing part now is the JSF page itself, sendMail.xhtml:




  • 8/13/2019 CDI Extensions JTJ 2012 02

    5/28

    CDI Introduction

    www.JAXenter.com |March 2012 5

    Basic mechanisms

    Sometimes it's very helpful to look behind the scenes of aframework to understand at least the very basic mechanisms.Thus we like to explain a few of those techniques first.

    Dependency Injection: DI is sometimes described as theHollywood Principle don't call us, we call you. It meansthat we let the container manage the creation of instancesand inject it instead of creating them ourselves with the newoperator. Of course, even in DI containers, nothing happenswithout anyone triggering this process. For a JSR-299 con-tainer, this trigger is a call to one of the method

    T BeanManager#getReference(Bean type, Qualifier... qualifiers);

    which returns an instance of the given type T. By doing so, itwill not only create the returned instance, but also all of its@Inject-annotated children in a recursive way.

    Usually the getReference(Bean)method is not called

    manually, but internally by the Expression Language Resolv-er. By writing something like

    the ELResolver will look for the Bean with the namemailForm and resolve the instance.

    Scopes, contexts, singletons: Each of a CDI containersmanaged objects is a singleton in the original sense specifiedby Ward Cunningham, who invented not only the Wiki butalso, together with Kent Beck, introduced design patterns intocomputer science in 1987. A singleton in this sense means

    that there is exactly one instance in a well-specified con-text. In a comment on Refactoring to Patterns by JoshuaKerievsky, Ward noted:

    There is a proper context for every computation. So muchof object-oriented programming is about establishing con-text, about balancing the lifetimes of variables, causing themto live the right length of time and then die gracefully.

    CDI is all about creating singletons in a well-specified con-text. In our case, the lifecycle of instances is defined by theirscopes. A @SessionScoped-annotated bean exists exactly onceper session. We could also name it a session singleton. If auser accesses our @SessionScopedbean for the first time, itwill get created and stored inside the session. Every subse-

    quent access will return exactly this same instance. When thesession ends, all the CDI-managed instances stored inside itwill also be properly destroyed.

    If we have a @RequestScopedbean, we could call it a re-quest singleton, a @ConversationScopedbean is a conversa-tion singleton, etc.

    Terminus Managed Bean: There are a few terms used in theCDI specification which need a short explanation. The termBean in Java is already pretty well-established and means aPOJO (Plain Old Java Object) with getters and setters. Theterminus technicus Managed Bean now means somethingcompletely different. It doesn't refer to instances of a class but

    meta-information which can be used to create those instances.It is represented by the interface Beanand will be gatheredon container startup via classpath scanning.

    Terminus Contextual Instance: Contextual Instances are ex-actly our singleton instances per scope, our session singletons,request singletons, etc. Usually a user never uses a ContextualInstance directly, but only via its Contextual Reference

    Terminus Contextual Reference: By default, a CDI con-tainer wraps all Contextual Instances via a proxy and onlyinjects those proxies instead of the real instances. In the CDIspecification those proxies are called Contextual Reference.There are plenty of reasons why CDI uses proxies by default:

    Serialisation: Instead of serialising the full object, we onlyneed to serialise the proxy. On de-serialisation, it willautomatically connect to the right Contextual Instanceagain.

    Scope differences: With proxies, it is possible to inject a@SessionScopedUserSettings into an @ApplicationScopedMailServicebecause the Proxy will connect to the rightUserSettings itself.

    Interceptors and Decorators: a proxy is the perfect way toimplement interceptors and decorators in a non-intrusiveway.

    The lifecycle of a CDI container

    Let's look at an easy scenario with a CDI container inside aplain Servlet engine such as Apache Tomcat. If a WebApplica-tiongets started, a ServletFilter will automatically also startyour CDI container which will firstly register all CDI-Exten-sions available on the ClassPathand then start with the classscanning. All ClassPathentries with a META-INF/beans.xmlwill be scanned and all classes will be parsed and stored as

    Managed Bean (interface Bean) meta-information insidethe CDI container. The reason for scanning this informationon startup is to: first. detect errors early and second, vastlyimprove the performance at runtime.

    To be able to handle all the CDI Scopes correctly, a CDIcontainer simply uses standard Servlet callbacks like Servlet-RequestListenerand HttpSessionListener.

    Standard scopes

    JSR-299 defines the most important scopes to build classicweb applications:

    @ApplicationScoped @SessionScoped @ConversationScoped

    @RequestScoped

    Those scopes are meta-annotated as @NormalScopewhichmeans they have a well-defined lifecycle.

    Beside those, there is another non-normal scope: @De-pendent. If a class doesn't have any explicit CDI scope an-notation or is explicitly annotated with @Dependent, aninstance will be created for each and every InjectionPointand will share the lifecycle of the contextual instances theyget injected into.

    An example: if a @Dependent MySecurityHelperis injectedin a @RequestScoped MyBackingBean, then the MySecuri-tyHelper instance will be destroyed along with the MyBack-

  • 8/13/2019 CDI Extensions JTJ 2012 02

    6/28

  • 8/13/2019 CDI Extensions JTJ 2012 02

    7/28

    CDI Introduction

    www.JAXenter.com |March 2012 7

    public @SessionScoped class MyBackingBean {

    Locale userLanguage;

    ...

    public void refreshLanguage(@Observes UserSettingsChanged usc) {

    userLanguage = getDefaultLanguageOfUser(usc.getUserName());

    }

    ...

    }

    If the UserSettingsChangeevent gets fired, all observer meth-ods of beans in currently active scopes will get invoked.

    Interceptors

    CDI provides an easy way to create own custom interceptors,as we will show by creating our own @Transactionalinter-ceptor. Instead of having to manage the transactions manu-ally, our small interceptor will do this for us as shown in thefollowing usage example:

    @ApplicationScoped

    public class MyUserService {

    private @Inject EntityManager em;

    @Transactional

    public storeUser(User u) {

    em.persist(u);

    }

    }

    For implementing this feature, we need to provide two parts.

    The first one is obviously the annotation itself. It is meta-annotated as @InterceptorBindingwhich marks it as an an-notation that is intended to be used for interceptors:

    @Retention(RetentionPolicy.RUNTIME)

    @Target( { ElementType.TYPE, ElementType.METHOD })

    @InterceptorBinding

    public @interface Transactional {}

    The second part is the interceptor implementation itself. Thisclass must be annotated as @Interceptor and additionallywith its intended interceptor binding. The interceptor func-tionality itself is implemented in a method which gets anno-tated as @AroundInvoke(listing 4).

    Final thoughts

    After two years of availability, CDI is already seeing wideadoption. It has proven itself in a broad range of projects,from providing productivity in small start-ups to offering reli-ability and scalability websites with millions of users per day.

    The Expert Group is currently working actively on CDI1.1, a specification which will bring small fixes and improve-ments, including much-requested standardization of Java SEbootstrap functionality for non-web applications.

    Pete leads the Seam, Weld and CDI TCK projects, is an adviser to the

    RichFaces project, and is a founder of the Arquil lian project. He has worked

    on a number of specifications including JSF 2.0, AtInject and CDI. He is

    a regular speaker at JUGs and conferences such as Devoxx (Javapolis),

    JAX, JavaBlend, JSFDays and JBoss World. Pete is currently employed by

    Red Hat Inc. working on JBoss open source projects. Before working for Red Hat, he

    used and contributed to Seam whilst working at a UK based staffing agency as IT

    Development Manager.

    Mark Strubergis a software architect with over 20 years of programming

    experience. He has been working with Java since 1996 and is actively

    involved in open source projects in the Java and Linux area. He is Apache

    Software Foundation member and serves as PMC and Committer for

    Apache OpenWebBeans, MyFaces, Maven, OpenJPA, BVal, DeltaSpike

    and other projects. He is also a CDI Expert Group member actively working on the

    specification. Mark works for the Research Group for Industrial Software (INSO) at

    the Vienna University of Technology.

    Listing 4

    @Interceptor @Transactional

    public class TransactionalInterceptor {

    private @Inject EntityManager em;

    @AroundInvoke

    public Object invoke(InvocationContext context) throws Exception{

    EntityTransaction t =em.getTransaction();

    try {

    if(!t.isActive())

    t.begin();

    return context.proceed();

    } catch(Exception e) {

    .. rollback and stuff

    } finally {

    if(t != null && t.isActive())

    t.commit();

    }

    }}

  • 8/13/2019 CDI Extensions JTJ 2012 02

    8/28

    CDI Introduction

    www.JAXenter.com |March 2012 8SIGN UP NOW TO RESERVE YOUR PLACE:WWW.JAXDAYS.COM

    Developer.Class presents JAX Days. This unique two day training and workshop

    event is crammed with quality, in-depth training and hands-on Java development

    activities. Dont miss this amazing opportunity to update your knowledge and

    introduce yourself to relevant and exciting new topics.

    2ND-3RDAPRIL 2012

    LONDONVICTORIA

    PARK PLAZA

    p re sen t s

    THE ULTIMATE HANDS-ON LEARNING EXPERIENCE

    TUESDAY

    3rd April, 2012

    Pragmatic Architecture

    with Ted Neward

    Advanced Neo4j

    with Ian Robinson

    & Jim Webber

    An Introduction to NoSQL and

    the Neo4j Graph Database

    with Ian Robinson & Jim Webber

    Java EE Efficient, Productive and Scalable

    with Adam Bien

    JavaEE Essentials

    with Adam Bien

    Groovy from Zero to Hero

    with Russel Winder

    The Busy Java Developers Guide to the JVMwith Ted Neward

    MONDAY

    2nd April, 2012

    JTJREADERS

    RECEIVE

    10%DISCOUNT

    USINGPROMOC

    ODE

    JDUGA2

  • 8/13/2019 CDI Extensions JTJ 2012 02

    9/28

    CDI Extensions

    www.JAXenter.com |March 2012 9

    by Ronald Steininger, Arne Limburg, and Mark Struberg

    This mechanism is called portable CDI extensions becauseit is based on a well-specified SPI which must be supportedby every certified standalone CDI container and EE 6 serv-er. Thus a CDI extension written on one CDI container willalso run on all others: JBoss Weld, Apache OpenWebBeans,Caucho Resin CanDI, IBM WebSphere 8, Oracle Glassfish 3,Oracle Weblogic 12c or Apache TomEE.

    Because of the portable, vendor-independent way these ex-tensions are implemented, they can be reused with all CDIprovider implementations. Projects like Apache MyFacesCODI and JBoss Seam 3 provide collections of important,commonly-needed extensions, letting CDI users easily aug-ment their applications with the extensions they need withoutweighing down the core CDI implementation.

    How does a CDI extension work?The CDI extension mechanism provides ways to hook customcode into the lifecycle of the CDI container. To leverage thispower in our own CDI extensions we must therefore know

    the very basics of the CDI container lifecycle itself. We willfirst give you a quick overview of this process and dive intothe details later in the article.

    The first task a CDI container performs is to load all CDIextensions. Next, all of the classes contained within JARfiles that have a META-INF/beans.xml marker file will bescanned also. For each of these classes an AnnotatedTypewill be constructed based on the given class. This object con-tains metadata about all annotations, constructors, methods,fields, etc. for the processed class. This information can bemodified by extensions. Later the CDI container will exposethis metadata in Bean instances used to manage contex-

    tual objects.The container will start all available contexts after all class-

    es have been scanned and all constraints have been verified.

    Writing a CDI extension for a job scheduler

    An example integration of a job scheduling service will high-light what is necessary to leverage the extension mechanism ina CDI environment. In this article, we want to go through thesteps needed to build such scheduler integration by writing aCDI extension.

    Creating a CDI extension is as simple as writing a classthat implements the interfacejavax.enterprise.inject.spi.Ex-

    tension. This class will contain the functionality of our exten-sion. We will see in later chapters how this class can interactwith the CDI container.

    Implementing additional functionality in a portable, vendor-independent way

    CDI ExtensionProgrammingIn the old days of Enterprise Java, a lot of frameworks were created, each with a very clear technological goal.

    Unfortunately these quickly became overloaded and stuffed with tons of features to fulfill each and every need.

    The CDI Expert Group aimed to avoid this problem with the CDI specification by strictly focusing on the core

    problems of dependency injection and defining a very powerful extension mechanism for implementing additional

    functionality on top of it. The CDI extension mechanism quickly became popular and a lot of high-quality exten-

    sions are already available.

  • 8/13/2019 CDI Extensions JTJ 2012 02

    10/28

    CDI Extensions

    www.JAXenter.com |March 2012 10

    The Container will pick up our extension via the Java Ser-viceLoader mechanism. Simply place a file namedjavax.en-terprise.inject.spi.Extension(the same name as the interface)within the META-INF/services folder of your JAR and ensurethis file contains the fully-qualified name of the Extensionimplementation. The container will look up the name of theclass at runtime and instantiate it via the default constructor(therefore the class needs a default constructor).

    Before we delve into the content of the extension, we willfirst look into Quartz, the scheduler we want to integratewith, and how Quartz would be used without our extension.

    The classic way to schedule jobs with Quartz

    Quartz is an open-source job scheduling service. The user de-fines jobs and lets Quartz know when these jobs shouldbe executed via so-called triggers. The scheduler itself willthen run these jobs following the given rules.

    The easiest way to use Quartz in a servlet container is prob-

    ably to use the QuartzInitializerServletQuartz provides. Thisload-on-startup servlet initializes the scheduler automaticallyand adds a second servlet which actually schedules the jobs.Listing 1 shows a typical code block in that servlet whichschedules a job named MyJob to run every ten minutes.

    Thats a lot of code just to schedule one job (and the codefor that job is still missing) but will work just fine for simpleuse cases and a small number of jobs that dont change much.

    As soon as the jobs get a bit more complicated, there's aproblem: the jobs will not be aware of the CDI container,which means that they cannot use the features provided byCDI. This will be no problem for very simple jobs but won't

    cut it as soon as the user wants to use a simple @Injectin oneof the jobs or a service that uses CDI. Some sort of integrationis needed to make all the features provided by CDI availableto the job, and the best way to accomplish this is by writingan Extension.

    Schedule jobs the CDI way

    Lets see how the jobs used with our extension will look:

    1. The job implements thejava.lang.Runnableinterfacerather than the Job interface provided by Quartz. Thisway, the code is not Quartz-specific and the schedulerused by our extension can easily switched later. The

    scheduler will call the run()method of this Runnablebased on the schedule we define.

    2. Its possible to use CDI features like injection or intercep-tors in these jobs.

    3. A @Scheduledannotation will tell our extension that thisclass defines a job that must be scheduled and what itsschedule will be (Listing 2).

    Thats all that is needed to convey the same information asthe code example before.

    For this example, @Scheduledis a simple annotation usedto set the schedule:

    @Inherited

    @Retention(RetentionPolicy.RUNTIME)

    @Target(ElementType.TYPE)

    public @interface Scheduled {

    String value();//the jobs schedule

    }

    It would be trivial to change this annotation to enable moreadvanced features like setting the schedule via dynamic con-figuration rather than hard-coding it in the jobs source; theannotation needs only to hold the information necessary to letour extension decide how to configure the job. Now its timeto look at the extension itself.

    Creating the CDI extension

    A CDI extension class implements thejavax.enterprise.inject.spi.Extensioninterface. This is just a marker interface andthus does not define any methods itself. Instead of using afixed set of methods statically defined in an interface, the con-tainer will fire a series of CDI Events during the container life-

    cycle. The Extension can interact with the CDI container bydefining observer methods for such events. An observer meth-od is a non-static non-final method which has an @Observesparameter annotation with the type of the observed event. It

    Listing 1

    import static org.quartz.JobBuilder.*;2

    import static org.quartz.TriggerBuilder.*;

    import static org.quartz.CronScheduleBuilder.*;

    ...

    SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();

    Scheduler scheduler = schedFact.getScheduler();

    JobDetail job = newJob(MyJob.class)

    .withIdentity("myJob")

    .build();

    Trigger trigger = newTrigger()

    .withIdentity("myTrigger")

    .withSchedule(cronSchedule("0 0/10 * * * ?"))

    .forJob("myJob")

    .build();

    scheduler.scheduleJob(job, trigger);

    Listing 2

    @Scheduled("0 0/10 * * * ?")

    public class MyJob implements Runnable {

    @Inject

    private MyService service;

    @Override

    public void run() {

    service.doSomething();

    }}

  • 8/13/2019 CDI Extensions JTJ 2012 02

    11/28

    CDI Extensions

    www.JAXenter.com |March 2012 11

    can not only gather information from the CDI container thisway; it can also modify this information and even transmitback new information to the container. As a rule of thumb,all things possible via CDI annotations can also be performedprogrammatically in an extension. You can very easily addor modify scopes, Interceptors, Decorators, InjectionPoints,Producer methods, ObserverMethods, etc. The defined con-tainer lifecycle events are:

    BeforeBeanDiscovery

    ProcessAnnotatedType

    ProcessInjectionTarget and ProcessProducer

    ProcessBeanand ProcessObserverMethod

    AfterBeanDiscovery

    AfterDeploymentValidation

    BeforeShutdown

    The first article of this series described how to observe cus-

    tom CDI events. Extensions can observe the container systemevents in exactly the same way. To find every class that hasthe @Scheduledannotation, the extension should observe theProcessAnnotatedTypeevent. This system event is fired forevery class scanned by the container during boot. A Quartzjob and Quartz trigger can be created and started after thecontainer initialization is complete for any such annotationfound (Listing 3).

    An observer for the BeforeBeanDiscoveryevent which isfired before the scanning process starts can be used to initial-ize the scheduler.

    public void initScheduler(@Observes BeforeBeanDiscovery event) {scheduler = StdSchedulerFactory.getDefaultScheduler();

    }

    The scheduler also has to be started. This can be done in anAfterDeploymentValidation event observer. That event isfired after the container has validated that there are no de-ployment problems, so all jobs will be scheduled at this point.Additionally, the BeanManagercan be stored in the Exten-sion for later use (e.g. in the CdiJobclass).

    public void startScheduler(@Observes AfterDeploymentValidation event,

    BeanManager bm) {

    beanManager = bm;

    try {

    scheduler.start();

    LOG.info("Started scheduler.");

    } catch (SchedulerException se) {

    throw new RuntimeException(se);

    }

    }

    Finally, the shutdown()method of the scheduler is called in anobserver of the BeforeShutdownevent.

    public void shutdownScheduler(@Observes BeforeShutdown event) {

    try {

    Listing 3public void scheduleJob(@Observes ProcessAnnotatedType pat) {

    AnnotatedType t = pat.getAnnotatedType();

    Scheduled schedule = t.getAnnotation(Scheduled.class);

    if (schedule == null) {

    //no scheduled job, ignoring this class

    return;

    }

    Class jobClass

    = t.getJavaClass().asSubclass(Runnable.class);

    if (jobClass == null) {

    LOG.error("Can't schedule job " + t);

    return;}

    JobDetail job = newJob(CdiJob.class)

    .usingJobData(CdiJob.JOB_CLASS_NAME, jobClass.getName())

    .build();

    Trigger trigger = newTrigger()

    .withSchedule(cronSchedule(schedule.value()))

    .build();

    scheduler.scheduleJob(job, trigger);

    }

    Listing 4public class CdiJob implements org.quartz.Job {

    public final static String JOB_CLASS_NAME = CDI_JOB_CLASS_NAME;

    @Override

    public void execute(JobExecutionContext context)

    throws JobExecutionException {

    JobDataMap jobData = context.getJobDetail().getJobDataMap();

    String className = jobData.getString(JOB_CLASS_NAME);

    Class jobClass;

    try {

    jobClass = Class.forName(className).asSubclass(Runnable.class); } catch (ClassNotFoundException e) {

    throw new JobExecutionException(e);

    }

    BeanManager bm = QuartzExtension.getBeanManager();

    Set jobBean = bm.resolve(jobBeans);

    CreationalContext c = bm.createCreationalContext(jobBean);

    Runnable job = (Runnable) bm.getReference(jobBean, Runnable.class, c);

    try {

    job.run();

    } finally {

    jobBean.destroy(job, c);

    }

    }

    }

  • 8/13/2019 CDI Extensions JTJ 2012 02

    12/28

    CDI Extensions

    www.JAXenter.com |March 2012 12

    scheduler.shutdown(true);

    } catch (SchedulerException se) {

    throw new RuntimeException(se);

    }

    }

    The following class does the work needed, so that a CDI-managed instance of the Runnable (our actual job) we definedis run as a Quartz job.

    1. It extracts the job class from the Quartz configuration.2. Before calling the run()method, it receives the actual

    CDI-managed instance from the BeanManager.3. After the run()method returns, the instance is destroyed

    (Listing 4).

    Our extension sets up all scheduled jobs to use this class, sothat all of this happens in a manner completely transparent to

    the user. Keep in mind that contexts like the RequestContextand SessionContextare not active for this job (there is noactive request nor session). If the injected services need thesecontexts because they depend on beans like a RequestScopedEntityManager, the contexts can be started and stopped in@PostConstructand @PreDestroymethods of the job. Thisis container-specific at the moment, but work is underwaywithin the Apache DeltaSpike project to make this possible ina vendor-independent way.

    Publisher

    Software & Support Media GmbH

    Editorial Office Address

    Darmstdter Landstrae 108

    60598 Frankfurt am Main

    Germany

    www.jaxenter.com

    Editor in Chief: Sebastian MeyenEditors: Claudia Frhling, Diana KupferAuthors: Dan Allen, Aslak Knutsen, Arne Limburg, Pete Muir, Gerhard Petraczek,

    Jason Porter, Andrew L. Rubinger, Ronald Steininger, Mark Struberg

    Copy Editor: Nicole Bechtel,Lisa PychlauCreative Director:

    Jens Mainz

    Layout: Tobias Dorn

    Sales:

    Cindy Ng

    +44 (0)20 7401 4837

    [email protected]

    Entire contents copyright 2012 Software & Support Media GmbH. All rights reserved. No

    part of this publication may be reproduced, redistributed, posted online, or reused by any

    means in any form, including print, electronic, photocopy, internal network, Web or any other

    method, without prior written permission of Software & Support Media GmbH

    The views expressed are solely those of the authors and do not reflect the views or po-

    sition of their firm, any of their clients, or Publisher. Regarding the information, Publisher

    disclaims all warranties as to the accuracy, completeness, or adequacy of any informa-

    tion, and is not responsible for any errors, omissions, inadequacies, misuse, or the con-

    sequences of using any information provided by Publisher. Rights of disposal of rewarded

    articles belong to Publisher. All mentioned trademarks and service marks are copyrightedby their respective owners.

    Imprint

    Summary

    One of the most important features of CDI is the possibilityto create extensions. With this mechanism, CDI can be ex-tended in a portable, vendor-independent way to provide newfeatures (like custom scopes), implement application-specificfunctionality (like loading configuration from an external da-tabase) or to integrate other technologies in a CDI-like fash-ion.

    Ronald Steiningeris a Senior Software Engineer for the Research Group

    for Industrial Software (INSO) at the Vienna University of Technology. He

    spent the last six years working with Java on both rich clients and web

    applications. He and his colleagues use CDI and Java EE 6 for all of their

    projects since late 2009. He spends his spare time working on his mas-

    ter thesis about the software architecture of campus management systems.

    Arne Limburgis Enterprise Architect at open knowledge GmbH in Olden-

    burg, Germany. He is an experienced developer, architect and trainer in

    the Enterprise environment and also regularly involved in Android devel-

    opment. He frequently speaks at conferences and conducts workshops

    in those fields. He is also an active participant in open source projects,e.g. as a committer of Apache OpenWebBeans and as initiator and Project Lead of

    JPA Security.

    Mark Strubergis a software architect with over 20 years of programming

    experience. He has been working with Java since 1996 and is actively

    involved in open source projects in the Java and Linux area. He is Apache

    Software Foundation member and serves as PMC and Committer for

    Apache OpenWebBeans, MyFaces, Maven, OpenJPA, BVal, DeltaSpike

    and other projects. He is also a CDI Expert Group member actively working on the

    specification. Mark works for the Research Group for Industrial Software (INSO) at

    the Vienna University of Technology.

  • 8/13/2019 CDI Extensions JTJ 2012 02

    13/28

    Announcing the

    JAX Innovation Awards 2012Celebrating the Best Innovations

    in the Java Ecosystem

    Submissions for the JAX Innovation Awards 2012 open

    on March 16th. Nominate the people, companies andtechnologies you think are innovating the most.

    www.jaxconf.com

    The JAX Innovation Awards will be presented to winners

    at a special ceremony on July 9 in San Francisco, CA.

    Most Innovative Java Technology

    Most Innovative Java Company

    Top Java Ambassador

  • 8/13/2019 CDI Extensions JTJ 2012 02

    14/28www.JAXenter.com |March 2012 14

    Apache DeltaSpike

    by Gerhard Petracek and Jason Porter

    In 2004 the world of J2EE started to change with the rise ofan alternative framework. Version 1.0 of the Spring frame-work was released and it became easier to implement enter-prise level applications. Spring gained a lot of popularity overtime and it also influenced Java EE. With the next version,Java EE focused on Ease of Development as well techni-cal concerns of the growing technical complexities requiredin applications. Even though Java EE became much simpler,there were still some loose ends. Therefore version 1.0 ofJBoss Seam was released in 2006. It provided a toolbox to fixsome of the shortcomings. At the same time, the Spring frame-work provided its own approach for integrating several partsof Java EE in a different manner. About one year later, JBossSeam version 2.0 was released and the MyFaces communityreleased version 1.0 of a new Spring extension named ApacheMyFaces Orchestra. MyFaces Orchestra introduced scopeswhich differed a lot from what was available so far, but thebasic purpose was similar to JBoss Seam. JSF users who pre-

    ferred the Spring framework got a powerful tool with My-Faces Orchestra, and JSF users who were in favor of Java EE 5could use the Seam framework as a convenient toolbox. Lateron, several dependency injection frameworks inspired a newJava EE specification with the name Contexts and Dependen-cy Injection for Java EE (aka CDI) which was released in 2009as a part of Java EE 6. In parallel also the Spring frameworkmoved in a very similar direction. Both camps solve the sameproblems, but there are still significant differences.

    The rise of CDI extensionsIn contrast to the Spring framework, CDI is available out-

    of-the-box in Java EE 6+ application servers and thereforeits very important to have sufficient standardized hooks foradditional frameworks to use them independent of the details

    of an application server to avoid vendor lock-in. Java EE 6is the first Java EE specification which doesnt need an addi-tional framework for painless usage or for replacing manualintegrations of different parts of the platform. At least thatsa common message of some community members. Java EE6 is closer to this statement than the former versions. How-ever, it turns out the real world isnt that shiny. A lot of newinnovations still happen in the Open Source space first andsome features might even be too special to be included intoa specification. Therefore it was intended to provide a richset of extension points from the very beginning. That allowsto keep specifications in general and CDI in particular con-sistent and simple without restricting custom approaches andmechanisms.

    As mentioned earlier, CDI is provided out-of-the-box byJava EE 6+ servers and therefore a very important aspect ofCDI extensions is portability which allows them to be usedseamlessly in combination with all implementations of theCDI specification. Apache OpenWebBeans and JBoss Weldare such CDI implementations and they allow to use CDI

    even with plain Java SE. Therefore, neither CDI nor portableCDI extensions are restricted to Java EE. That allows to cre-ate different types of CDI extensions. Apache DeltaSpike issuch a collection of portable CDI extensions. To understandthe roots of DeltaSpike its important to look at two famousportable CDI extensions - JBoss Seam3 and Apache MyFacesExtCDI (aka MyFaces CODI).

    JBoss Seam3Seam 3 started shortly after JSR 299 completed. The goal ofSeam 3 was not to be a complete migration of all things fromSeam 2, but it provides a rich toolbox for building standards-

    based web applications tailored for traditional and clouddeployments. Certainly some ideas came from Seam 2, butmany more came from the community. Unlike the starting

    Creating a stable, reliable and truly portable CDI extension

    Apache DeltaSpikeCloses the GapsThis article traces the development of Apache DeltaSpike from the roots to its present status.

    This rapidly-growing project is surrounded by a very active team of developers whose goal is

    to create a thoroughly tested and stable version 1.0 that is compatible with all major server

    platforms which support CDI.

  • 8/13/2019 CDI Extensions JTJ 2012 02

    15/28www.JAXenter.com |March 2012 15

    Apache DeltaSpike

    of Seam 1 and 2, Seam 3 did not simply want to improve JSFsupport, but to unite many technologies with CDI.

    Many of the modules developed in Seam 3 demonstrate thissuch as Mail, JMS, JCR, Reports and Spring-Integra-tion. All of these modules came from the community as a holewas discovered while using the technologies and seeking a

    more unified and simpler approach for developers. Other ar-eas in developer productivity were explored in Seam 3 such astype safe logging in Solder, exception handling also in Solderthough formerly Seam Catch, XML configuration via SeamConfig, now in Solder.

    Apache MyFaces CODISimilar to JBoss Seam, MyFaces Orchestra provided betterscopes for JSF applications as well as an optional integrationwith the Java Persistence API (JPA) to allow the usage of anextended persistence context. Originally MyFaces CODI wasstarted to port some concepts provided by MyFaces Orches-

    tra to a portable CDI extension. However, since CDI endorsestype-safe dependency injection, MyFaces CODI was designedfrom scratch and only some of the basic and successful con-cepts of MyFaces Orchestra were used as basis for some fea-tures of MyFaces CODI.

    The most important qualities of MyFaces CODI, which at-tracted several users even before the release of version 1.0,are the reality check of existing concepts in combination withinnovative new mechanisms, the support for almost all majorJava EE 5/6 application servers, an easy but powerful API andSPI as well as a fast and solid implementation, and last butnot least, a great community.

    MyFaces CODI doesnt enforce a specific programmingmodel. Instead it relies on CDI concepts as much as possibleand users just use what they need in addition. They can evenreplace parts of MyFaces CODI with custom implementa-tions which get picked up by the rest of the framework ordeactivate parts completely to improve the performance evenfurther. Like CDI itself, MyFaces CODI relies on type-safetyas much as possible. This allows use of standard Java supportin existing Java IDEs without the need for special IDE Add-ons. In addition, it avoids mistakes like typos and thereforeallows an easier refactoring and maintenance process.

    The future Apache DeltaSpike

    Since CDI encourages the usage of portable CDI extensions,users have to look at several accredited portable CDI exten-sions like JBoss Seam3 and Apache MyFaces CODI as well asseveral smaller projects and blog entries about implementingsuch extensions with varying quality. Several communities ofCDI extensions came up with similar ideas and features. Mostof the time it is possible to mix multiple portable CDI exten-sions without problems. However, usually there is no out-of-the-box optimization across different extension-projects,and to combine them sometimes requires a detailed know-ledge about the projects. For example, it is not difficult to useSeam3 in combination with MyFaces CODI, but both have

    different security concepts which are not aware of each otherout-of-the-box. Instead of implementing and documentingthe corresponding adapters for the major extensions, a large

    part of the community decided to start a shared CDI exten-sions project developed and maintained by the community.The Apache Software Foundation was chosen due to its repu-tation concerning community-driven and vendor-independ-ent projects.

    Amongst many others, the project management committee

    of Apache MyFaces was excited about this idea, and the leaddevelopers of MyFaces CODI helped to draft a proposal forsuch a new Apache project. The hardest part was the namefor the project. After some discussions the upcoming commu-nity agreed on the intermediate name DeltaSpike. With thisname, the community entered the Apache Incubator, which isthe entry point for all new Apache projects. Before the projectleaves the incubator and graduates to an Apache top levelproject, the community will vote a final project-name.

    The initial committers of the DeltaSpike community arerepresentatives of several existing CDI communities whichjoined the effort from the very beginning. Aside from some

    other important tasks, the community merges features of theparticipating extension projects, adds new features and growsa community before DeltaSpike becomes a top level projectand leaves the Apache Incubator. Before a feature gets addedto DeltaSpike it is discussed by the community.

    Progressing fastTwo months after the first e-mail on the mailing list [1],DeltaSpike v0.1 incubating was announced. With this firststep, the community started to merge features of Apache My-Faces CODI-Core and JBoss Solder which is a central partof Seam3. Every DeltaSpike release is well tested on multi-ple containers and many real world projects. Nonetheless it'sexpected that even APIs will change until version 1.0 basedon the feedback of the community and new features and bugfixes will be added quickly.

    In the next release, the community will add further Del-taSpike-Core features as well as new modules. Besides re-viewing, discussing and adding features to DeltaSpike, thecommunity is also working on a great documentation, ex-amples, as well as a test-suite which should ensure true andtested portability across different environments.

    Join the communityThere are already several very active community members

    who enjoy the great cooperation. At Apache the most impor-tant part of a project is its community. Especially users whoare not familiar with Open-Source communities in general orApache projects in particular sometimes do not know how toget involved. Therefore the DeltaSpike community is work-ing on a short overview of different types of involvement andthe corresponding steps. Everybody is very welcome to get intouch with the community and every question which is notcovered by the Wiki [2] is very welcome to improve the Wikiand therefore the experience for new users. Its important tounderstand that everybody is welcome to join the discussionsor to provide feedback to improve DeltaSpike step by step. It

    makes sense to join the effort as soon as possible because thecommunity moves fast and has agreed on releasing early andoften.

  • 8/13/2019 CDI Extensions JTJ 2012 02

    16/28www.JAXenter.com |March 2012 16

    Apache DeltaSpike

    The new era DeltaSpike v1.0 and beyondAfter merging the best features and introducing new con-cepts, you can expect that the result is better than the originalparts. An example which is available since v0.1-incubatingis @Exclude. In case of @Exclude the community merged@Vetofrom Solder with @ExpressionActivatedand @Pro-jectStageActivated of MyFaces CODI. Originally, the dis-cussion was about more expressive names for all of thoseannotations, and the result was a single annotation called@Excludewith the features of the original annotations. Thismeans the final version is more expressive and easier for userswithout losing functionality. The listings 1-3 show independ-ent beans with the new annotation. The result might soundobvious, but it took some time and a lot of e-mails to findthe right name which allowed to merge the functionality andpreserve the expressiveness.

    As mentioned earlier, DeltaSpike will release early and of-ten. So 0.1-incubating doesn't contain that many features for

    application developers, but DeltaSpike grows rapidly and be-sides DeltaSpike-Core the community is currently working ontwo new modules which will be part of the next release.

    Right now all modules can be used even in Java SE ap-plications. After finishing the most important modules likeSecurity, I18n, Exception handling which can be used in JavaSE applications as well, the community plans to start with

    Listing 1: Service implementation for

    project-stage UnitTest

    @Alternative

    @Exclude(exceptIfProjectStage = ProjectStage.UnitTest.class)

    public class TestServiceMockImpl implements Service

    {

    //...

    }

    Listing 2: Service implementation for a

    database different from type 'prodDB'

    @Alternative

    @Exclude(onExpression = "db_type==prodDB")

    public class DevServiceMockImpl implements Service

    {

    //...

    }

    Listing 3: Utility class which shouldn't

    be a CDI bean

    @Exclude

    public class CustomUtilClass

    {

    //...}

    several integration modules for Java EE technologies like JSF,JPA, REST, JMS as well as other frameworks like Spring andQuartz.

    The goal regarding JBoss Seam3 and Apache MyFacesCODI is to add as much as the majority can agree on. Sincethe community is optimistic to add and/or merge most fea-tures in/into DeltaSpike, it is expected to be easy for usersof the original extension projects to migrate to DeltaSpike.Instead of using workarounds for the migration, users are in-vited to join the effort early and share use cases which mightnot be supported at the time they try to switch to the corre-sponding module of DeltaSpike. In the end they should see aneven better approach they can use. Version 1.0 should be fast,thoroughly tested, very stable and compatible with all majorserver platforms which support CDI. The DeltaSpike teamis already very active, and all of us are confident that it willgrow as fast as DeltaSpike itself to reach the goal of a stable,reliable and truly portable CDI extension and even more im-

    portant: a great community.

    Gerhard Petracek is Apache MyFaces committer and PMC chair; Apache

    OpenWebBeans committer and PMC member; Apache DeltaSpike com-

    mitter, PPMC member and mentor; Apache member; Bean-Validation ex-

    pert group member and a founder of Apache MyFaces Extensions

    Validator, Apache MyFaces CODI and Apache DeltaSpike. At IRIAN Solu-

    tions Gerhard is responsible for Java-EE trainings and the development of modernweb-applications for customers such as Credit-Suisse. Furthermore, he holds lectures

    at an Austrian University of Applied Sciences and is the author of several articles on

    JSF and Java-EE.

    Jason Porter is a software engineer currently working in the Java Enter-

    prise Edition Space and Seam at Red Hat. His specialties include JBoss

    AS, Seam, CDI, JSF, Java EE, Gradle. He has worked with PHP, Ruby (both

    stand-alone and Rails), Groovy, XSLT the rest of the web language arena

    (HTML, CSS, JS, etc). His current position as Senior Software Engineer at

    Red Hat has him work primarily on Seam, however, he also contributes to JBoss Forge,

    Arquillian and Apache DeltaSpike.

    References & Additional Resources

    [1] http://mail-archives.apache.org/mod_mbox/incubator-deltaspike-dev/

    [2] https://cwiki.apache.org/confluence/display/DeltaSpike

  • 8/13/2019 CDI Extensions JTJ 2012 02

    17/28

    JOIN US FOR 4 DAYS CRAMMED FULL OFTHE BEST JAVA CONTENT, SPEAKERS,

    DISCUSSIONS AND NETWORKING

    July 9 12, San Francisco, CA

    Technical presentations and tutorials

    In-depth coverage of the latest technologies

    Practical implementation techniques

    Neutral coverage of the most important Java Ecosystem topics

    Register Now for Very Early Bird Tickets!

    www.jaxconf.com

    follow us: twitter.com/JAXconf JAXConf

    Continous Delivery

    Open Source Tools & Framework

    SpringJava EE Languages

    JavaScriptBig Data & NoSQL

    Agile

    Cloud

    Java Performance

    Android

    HTML5

    Java Core

    Web Architecture

  • 8/13/2019 CDI Extensions JTJ 2012 02

    18/28

    Arquillian

    www.JAXenter.com |March 2012 18

    Testable development of CDI

    Arquillian MakesTesting a Breeze

    Its our opinion that testing is development; were not doing our job as programmers if we cannot ensure that

    our code is working as advertised. To that end, CDI has been a tremendous step forward for Java EE as a simpli-

    fied POJO-based component model. Of course, CDI beans become such only within the context of a CDI Contain-

    er, and that infers both starting a server and deploying into it. Until now, that work has been the responsibility of

    the developer; with the introduction of the Arquillian testing framework, these concerns can safely be put aside.

    by Dan Allen, Aslak Knutsen, and Andrew L. Rubinger

    Arquillian is a platform that simplifies integration testing forJava middleware. It deals with all the plumbing of containermanagement, deployment and framework initialization soyou can focus on the task at hand, writing your tests. Realtests. Arquillian minimizes the burden on you the developer by covering aspects surrounding test execution, including:

    Managing the lifecycle of the container (start/stop),

    Bundling the test class with dependent classes and resourc-es into a deployable archive,

    Enhancing the test class (e.g., resolving @Inject, @EJB and@Resource injections),

    Deploying the archive to test (deploy/undeploy) and

    Capturing results and failures.

    To avoid introducing unnecessary complexity into the devel-opers build environment, Arquillian integrates seamlessly withfamiliar testing frameworks (e.g., JUnit 4, TestNG 5), allowingtests to be launched using existing IDE, Ant and Maven testplug-ins without any add-ons. This guide introduces you toArquillian. After reading this guide, you will be able to:

    Add the Arquillian infrastructure to a Maven-based Javaproject

    Write an Arquillian test case to assert the behaviour of aCDI bean

    Execute the Arquillian test case in multiple compatiblecontainers

    Youll learn all of these skills by incorporating Arquillian intothe test suite of a Java EE application with a Maven build. Wevedesigned this guide to be a fast readto get you started quickly!

    Assumptions

    The easiest way to get started with Arquillian is to incorpo-rate it into the test suite of a project build that offers depend-ency management. Today, the most widely-used build tool in

    this category is Apache Maven. This guide will navigate youto your first green bar using a sample Maven project.

    Arquillian does not depend on Maven, or any specific buildtool for that matter. It works just as well if not better whenused in a project with an Ant or Gradle build. Ideally, thebuild tool should offer dependency management as it simpli-fies the task of including the Arquillian libraries since they aredistributed in the Maven Central repository

    This guide assumes you have Maven available, either inyour command shell or your IDE. If you dont, please installMaven now [1]. You will also need JDK 1.6 [2] or better in-

    stalled on your machine.

    Create a new project

    There are two ways we recommend you create a new Mavenproject:

    1. Generate a project from a Maven archetype [3]2. Create and customize a project using JBoss Forge [4]

    If you already have a Maven project, you can use this sectionas review to ensure you have the proper dependencies beforemoving on.

    By far, JBoss Forge is the simpler approach, but this guide

    will offer both options in the event you arent ready to adoptJBoss Forge. Select from one of the two options above tojump to the instructions.

    Generate a project from a Maven archetype

    First, create a Maven-based Java project using the commandbelow. Copy the text after the $ and paste it into your com-mand shell.

    $ mvn archetype:generate -DarchetypeGroupId=net.avh4.mvn.archetype \

    -DarchetypeArtifactId=java-1.6-archetype

    Respond to the prompts by entering the value shown aftereach double colon below. Hit the Enter key after each line (asindicated by ).

  • 8/13/2019 CDI Extensions JTJ 2012 02

    19/28

    Arquillian

    www.JAXenter.com |March 2012 19

    Define value for propertygroupId: : org.arquillian.example Define value for property artifactId: : arquillian-tutorial

    Define value for property version: : Define value for propertypackage: :

    Confirm properties configuration:groupId: org.arquillian.exampleartifactId: arquillian-tutorialversion: 1.0-SNAPSHOTpackage: org.arquillian.exampleY: :

    This command generated a Maven-based Java project in-side a new folder named arquillian-tutorialunder the cur-rent directory. The file structure of the project is shownbelow:

    src/ main/

    java/ Place all application Java source files here(under Java package)

    resources/ Place all application configuration fileshere

    test/ java/ Place all test Java source files heres (under

    Java package) resources/ Place all test configuration files here

    (e.g., arquillian.xml)pom.xml The Maven build file. Tells Maven how your

    project should be built.

    The project is preconfigured to use Java 6 and JUnit 4.8, theminimum required versions of Java and JUnit for using Ar-quillian, respectively.

    The generator also created a Java package named org.

    arquillian.example underneath the two java folders. Youshould put your Java source files in this package rather thanat the root of the java folder. Arquillian also supports TestNG5. However, we will be using JUnit throughout this guide.

    Go ahead and open up the pom.xml in your editor. Youshould see an XML file containing basic project information, abuild section and a dependencies section. You can remove all theelements below the JUnit dependency as they arent required.

    After making the change, you should end up with the con-tents seen in listing 1 (trimmed for brevity).

    Were going to be writing Java EE 6 components. There-fore, we also need to add the Java EE 6 API to the classpath

    so we can compile these components.Open up thepom.xmlfile once again and add the follow-ing XML fragment directly inside the element.Listing 2 shows how the section should look once youre done.

    We strongly recommend that you do notuse the Java EEAPI artifact with coordinatesjavax:javaee-api. That bundlecontains classes with stripped method bodies, which willcause your application to throw strange Absent Code errorsif left on the classpath at runtime (even when running tests).Read the FAQ under [5] if you want more background.

    The foundation of your project is now ready! Skip to thenext section to open the project in Eclipse [6] so we can startwriting some code!

    Create a project using Forge

    JBoss Forge [7] is a command shell for rapid-application de-velopment in a standards-based environment. Another wayto think of it is that its like Maven Archetypes on steroids.

    Installing Forge is a relatively short process, and this guidewill take you through the fundamentals. Follow these simplesteps to get it installed:

    1. Download Forge and unzip it into a folder on your hard-drive, which well call $FORGE_HOME

    2. Well assume you extracted the distribution to a folder

    named forge in your home directory3. Add $FORGE_HOME/bin to your path (Windows, Linux

    or Mac OSX)

    Listing 1

    pom.xml

    4.0.0

    org.arquillian.example

    arquillian-tutorial

    1.0-SNAPSHOT

    jar

    arquillian-tutorial

    org.apache.maven.plugins

    maven-compiler-plugin

    2.3.2

    1.6

    1.6

    junit

    junit

    4.8.1

    test

  • 8/13/2019 CDI Extensions JTJ 2012 02

    20/28

    Arquillian

    www.JAXenter.com |March 2012 20

    On Unix-based operating sys-tems, adding Forge to yourpath typically means edit-ing your $HOME/.bashrc or$HOME/.profile; you willneed to set the following envi-

    ronment variables:

    $ export FORGE_HOME=$HOME/forge/$ export PATH=$PATH:$FORGE_HOME/bin

    On Windows, you will need to right-click on CP, then click S P, open the Atab, then click E V and add these twoentries visually. We recommended setting User variables forForge, unless you have placed the unzipped distribution in afolder where all users can access it.

    Now that Forge is installed (i.e., extracted), open a com-

    mand prompt (a shell) and run the forge command (figure 1):

    $ forge

    [no project] ~ $

    Thats it! Youve got Forge up and running. Now its time tocreate the project.

    Inside the Forge shell, execute the following command tocreate a blank project, much like we created a project usingthe Maven Archetype above:

    $ new-project --named arquillian-tutorial --topLevelPackage org.arquillian.example

    This command generates a Maven-based Java project inside anew folder named arquillian-tutorial under the current direc-tory. The file structure of the project Forge generates is shownbelow:

    src/ main/ java/ Place all application Java source files here (un-

    der Java package) resources/ Place all application configuration files

    here META-INF/ forge.xml An empty Forge settings file test/ java/ Place all test Java source files heres (under Java

    package) resources/ Place all test configuration files here (e.g.,

    arquillian.xml)pom.xml The Maven build file. Tells Maven how your

    project should be built.

    Forge also makes the project folder your current directorywithin the Forge shell.

    [arquillian-tutorial] arquillian-tutorial $

    By default, Forge sets up the project to use Java 1.6, the mini-mum required version of Java to use Arquillian, a nice con-venience. What we need to add now is the Java EE APIs. Thatsdone using the project add-dependency command below:

    $ project add-dependency org.jboss.spec:jboss-javaee-6.0:1.0.0.Final:pom:provided

    You will also need to add JUnit 4.8, the minimum requiredversion of JUnit to use Arquillian, as a test-scoped dependency:

    $ project add-dependency junit:junit:4.8.1:test

    The result of thepom.xmlthat Forge generates is shown inListing 3.

    Arquillian is now distributed in the Maven Central re-pository, so the JBoss Public repository declaration in thepom.xmlis unnecessary and can be removed. Keep in mind,though, you may need it to retrieve other JBoss software notavailable in Maven Central. If you follow the camp that con-sider repositories explicitly defined in your projectspom.xmlto be an antipattern, then read the instructions under [8] toenable the repository globally in your settings.xmlfile.

    The foundation of your project is now ready! Lets nowopen the project in Eclipse so we can start writing some code!

    Open the project in Eclipse

    When developing a Java project, youll likely use an IDE, suchas Eclipse. Thats why Arquillian has been designed to be IDEfriendly, meaning you can run Arquillian tests from the IDEwithout making unconventional changes. So lets start takingadvantage of the IDE immediately.

    Begin by launching Eclipse. Now, since this is a Maven pro-ject, you need the Maven Integration for Eclipse(m2e) plug-in[9] installed to open the project. If you dont already have

    the integration installed, the simplest way to get it is to in-stall JBoss Tools [10]. Follow these steps to install it from theEclipse Marketplace (sort of like the app store for Eclipse).

    Fig. 1: Starting Forge

    Listing 2

    pom.xml

    org.jboss.spec

    jboss-javaee-6.0

    1.0.0.Final

    pom

    provided

    junit

    junit

    4.8.1

    test

  • 8/13/2019 CDI Extensions JTJ 2012 02

    21/28

    Arquillian

    www.JAXenter.com |March 2012 21

    1. Select H | E M... from the main menu2. Type jboss tools in the Find input field (no quotes) and

    press Enter3. Click the Install button next to JBoss Tools (Indigo)4. Complete the install wizard, then restart Eclipse if prompted

    JBoss Tools provides a nice environment for developing JavaEE applications, including excellent CDI support. Dont wor-ry, its not a heavyweight plugin.

    However, if you just wantthe Maven integration with-out the extras that JBoss Toolsbrings, you can follow thesesteps instead:

    1. Select H | E M-... from the mainmenu

    2. Type maven in the Findinput field (no quotes) andpress E

    3. Click the I buttonnext to Maven Integration for Eclipse

    4. Complete the install wizard, then restart Eclipse if prompted5. Repeat the steps to install the Maven Integration for Eclipse

    WTP

    Once you have the Maven Integration plugin installed, followthese steps to open the project:

    1. Select F | I... from the main menu2. Type existing maven in the input source field3. Select the option E M P, then click

    the N button4. Click the B button5. Navigate the project folder on your filesystem, then click

    the OK button6. Click the F button to open the project

    Eclipse will recognize the Maven project and open it in theProject Navigator view. If you expand the project, it shouldlook similar to figure 2. Now we can really get down to busi-ness!

    Create a component

    In order to write an Arquillian test, we need to have a compo-nent for it to test. Lets begin by creating a basic componentso that you can learn how to execute an Arquillian test with-out other distractions. Well gradually move to more complexscenarios.

    In your IDE, create a new Java class named Greeter in theorg.arquillian.example package. Replace the contents of the

    file with this greeter logic (Listing 4).We want to verify that this class behaves properly when in-

    voked as a CDI bean. Of course, we could simply write a unittest. But lets pretend that the bean uses enterprise services suchas dependency injection and messaging and must be used insidea container. (Besides, that way we give it room to grow).

    To use the class as a CDI bean, well be injecting it into thetest using the @Injectannotation. That calls for an Arquilliantest, which means its time to add the Arquillian API to theproject!

    Add the Arquillian APIs

    Once again open up the pom.xmlfile, located in the rootfolder of the project, in your editor. We need to instruct Ma-ven which versions of the artifacts to use. Insert the following

    Fig. 2: Eclipse will recognize and

    open the Maven project in the

    Project Navigator view.

    Listing 3

    pom.xml

    4.0.0

    org.arquillian.example

    arquillian-tutorial

    1.0.0-SNAPSHOT

    org.jboss.spec

    jboss-javaee-6.0

    1.0.0.Final

    provided

    pom

    junit

    junit

    4.8.1

    test

    JBOSS_NEXUS

    http://repository.jboss.org/nexus/content/groups/public

    arquillian-tutorial

    maven-compiler-plugin

    2.3.2

    1.6

    1.6

  • 8/13/2019 CDI Extensions JTJ 2012 02

    22/28

    Arquillian

    www.JAXenter.com |March 2012 22

    XML fragment directly above the element to importthe BOM, or version matrix, for Arquillians transitive de-pendencies.

    pom.xml

    org.jboss.arquillian

    arquillian-bom

    1.0.0.CR7

    import

    pom

    Next, append the following XML fragment directly under thelast element to add the Arquillian JUnit inte-gration:

    pom.xml

    org.jboss.arquillian.junit

    arquillian-junit-container

    test

    The Arquillian JUnit integration artifact also adds the Arquil-lian and ShrinkWrapAPIs to the test classpath. You need allof these libraries to write and compile a JUnit Arquillian test.To use TestNG instead of JUnit, substitute the ArquillianJUnit integration with the Arquillian TestNG integration. Ifyoure having trouble with thepom.xmlup to this point, you

    can download the file from the gist [11]. Youre all set towrite your first Arquillian test!

    Write an Arquillian test

    An Arquillian test looks just like a unit test, just with someextra flair. Lets return to the IDE. If you get the message

    Project configuration is out of date with pom.xml, thenright click and select P | M | U PC to resync the project.

    Begin by creating a new JUnit test case in src/test/javaunderthe org.arquillian.example package and name it GreeterTest.You wont need the typical setup and teardown methods sinceArquillian is doing most of the heavy lifting. Heres what wehave so far:

    src/test/java/org/arquillian/example/GreeterTest.java

    package org.arquillian.example;

    import org.junit.Assert;import org.junit.Test;

    public class GreeterTest {

    @Test

    public void should_create_greeting() {

    Assert.fail("Not yet implemented");

    }

    }

    Now, about that flair. An Arquillian test case must have threethings:

    1. A @RunWith(Arquillian.class) annotation on the class2. A static method annotated with @Deploymentthat returns

    a ShrinkWrap archive3. At least one method annotated with @Test

    The @RunWithannotation tells JUnit to use Arquillian as thetest controller. Arquillian then looks for a static method anno-tated with the @Deploymentannotation to retrieve the test ar-chive (i.e., micro-deployment). Then some magic happens andeach @Testmethod is run inside the container environment.

    Whats a test archive?

    The purpose of the test archive is to isolate the classes andresources which are needed by the test from the remainderof the classpath. Unlike a normal unit test, Arquillian doesnot simply dip into the entire classpath. Instead, you includeonly what the test needs (which may be the entire classpath, ifthats what you decide). The archive is defined using Shrink-Wrap [12], which is a Java API for creating archives (e. g., jar,war, ear) in Java. The micro-deployment strategy lets youfocus on precisely the classes you want to test and, as a result,the test remains very lean.

    ShrinkWrap also supports resolving artifacts (libraries) andcreate configuration files programmatically, which can then

    be added to the test archive. For a more thorough introduc-tion to ShrinkWrap, see the ShrinkWrap introduction guide[13]. Lets add that Arquillian flair to the test (listing 5).

    Listing 4

    src/main/java/org/arquillian/example/Greeter.java

    package org.arquillian.example;

    import java.io.PrintStream;

    /**

    * A component for creating personal greetings.

    */

    public class Greeter {

    public void greet(PrintStream to, String name) {

    to.println(createGreeting(name));

    }

    public String createGreeting(String name) {

    return "Hello, " + name + "!";

    }}

  • 8/13/2019 CDI Extensions JTJ 2012 02

    23/28

    Arquillian

    www.JAXenter.com |March 2012 23

    Using ShrinkWrap, weve defined a Java archive (jar) as thedeployment that includes the Greeter class that the test willinvoke and an empty beans.xmlin the META-INF directoryto activate CDI in this archive.

    Now all we need to do is inject the Greeter instance into afield directly above the test method and replace the unimple-

    mented test method with one that asserts the behavior of thebean. To give you that warm fuzzy feeling, well also print thegreeting to the console.

    src/test/java/org/arquillian/example/GreeterTest.java

    // clip

    @Inject

    Greeter greeter;

    @Test

    public void should_create_greeting() {

    Assert.assertEquals("Hello, Earthling!",

    greeter.createGreeting("Earthling")); greeter.greet(System.out, "Earthling");

    }

    Listing 6 shows how the test should look when youre done.Youve written your first Arquillian test! Ah, but youre

    probably wondering how to run it. If youre thinking, Justlike a unit test youre correct! However, we first need to adda container adapter to the classpath.

    Add a container adapter

    Weve been talking a lot about testing in a container, but sofar we have not mentioned which one. Thats because its aruntime decision. Arquillian selects the target container basedon which container adapter is available on the test classpath.That means well be adding more libraries to the project.

    An Arquillian test can be executed in any container that iscompatible with the programming model used in the test (aslong as the container has an Arquillian adapter). Our test isusing the CDI programming model, so we need to use anycontainer to supports CDI. We want fast turnaround dur-ing development, so well start with the Weld EE embeddedcontainer.

    Open thepom.xmlfile again and add the following groupof dependencies directly below the other ele-ments (listing 7).

    To summarize, here are the three libraries you need to useArquillian (with JUnit):

    1. Arquillian JUnit integration2. Arquillian container adapter for the target container3. Container runtime (embedded container) or container

    client (remote container)

    Listing 6

    src/test/java/org/arquillian/example/GreeterTest.java

    package org.arquillian.example;

    import org.jboss.arquillian.container.test.api.Deployment;

    import org.jboss.arquillian.junit.Arquillian;

    import org.jboss.shrinkwrap.api.ShrinkWrap;

    import org.jboss.shrinkwrap.api.asset.EmptyAsset;

    import org.jboss.shrinkwrap.api.spec.JavaArchive;

    import org.junit.Test;

    import org.junit.Assert;

    import org.junit.runner.RunWith;

    @RunWith(Arquillian.class)

    public class GreeterTest {

    @Deployment

    public static JavaArchive createDeployment() {

    return ShrinkWrap.create(JavaArchive.class) .addClass(Greeter.class)

    .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

    }

    @Inject

    Greeter greeter;

    @Test

    public void should_create_greeting() {

    Assert.assertEquals("Hello, Earthling!",

    greeter.createGreeting("Earthling"));

    greeter.greet(System.out, "Earthling");

    }}

    Listing 5

    src/test/java/org/arquillian/example/GreeterTest.java

    package org.arquillian.example;

    import org.jboss.arquillian.container.test.api.Deployment;

    import org.jboss.arquillian.junit.Arquillian;

    import org.jboss.shrinkwrap.api.ShrinkWrap;

    import org.jboss.shrinkwrap.api.asset.EmptyAsset;

    import org.jboss.shrinkwrap.api.spec.JavaArchive;

    import org.junit.Assert;

    import org.junit.Test;

    import org.junit.runner.RunWith;

    @RunWith(Arquillian.class)public class GreeterTest {

    @Deployment

    public static JavaArchive createDeployment() {

    return ShrinkWrap.create(JavaArchive.class)

    .addClass(Greeter.class)

    .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

    }

    @Test

    public void should_create_greeting() {

    Assert.fail("Not yet implemented");

    }}

  • 8/13/2019 CDI Extensions JTJ 2012 02

    24/28

    Arquillian

    www.JAXenter.com |March 2012 24

    Were using an embedded container in this example, so weneed the container runtime, Weld.Now back to the test.

    Run the Arquillian test

    Once you add all the necessary Arquillian libraries to theclasspath, you can run an Arquillian test just like a unit test,whether you are running it from the IDE, the build script or

    any other test plugin. Lets run the test in Eclipse.From the IDE window, right click on the GreeterTest.javafile in the Package Explorer (or in the editor) and select RA | JU T from the context menu (see fig. 3)

    When you run the test, you should see the following linesprinted to the console:

    26 [main] INFO org.jboss.weld.Version WELD-000900 1.1.1 (Final)

    Hello, Earthling! You should then see the JUnit view appear, revealing a green bar (fig. 4)!

    You can also run the test on the commandline using Maven:

    $ mvn test

    You should see the following lines printed to the console:

    -------------------------------------------------------

    T E S T S

    -------------------------------------------------------

    Running org.arquillian.example.GreeterTest

    21 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.1 (Final)

    Hello, Earthling!

    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.858 secCongratulations! Youve earned your first green bar with Arquill ian!

    A closer look

    How do you know that CDI really worked? For all you know,Arquillian created a new instance of theGreeter class and in-jected it into the test without any involvement from CDI.Lets prove its there. Create a new CDI bean named Phrase-Builderin the org.arquillian.examplepackage that can createphrases from templates.

    Next, open up the Greeter class and create a new construc-tor that will inject PhraseBuilderusing constructor injection.

    Then, delegate the task of creating the greeting to the injectedbean (listing 9)Now, in order for the test to work, an instance of Phrase-

    Builder must be created, its @PostConstructmethod invoked

    Listing 8

    src/main/java/org/arquillian/example/PhraseBuilder.java

    package org.arquillian.example;

    import java.text.MessageFormat;

    import java.util.HashMap;

    import java.util.Map;

    import javax.annotation.PostConstruct;

    public class PhraseBuilder {

    private Map templates;

    public String buildPhrase(String id, Object... args) {

    return MessageFormat.format(templates.get(id), args);

    }

    @PostConstruct

    public void initialize() {

    templates = new HashMap();

    templates.put("hello", "Hello, {0}!");

    }}

    Fig. 4: JUnit view revealing a green bar

    Fig. 3: Starting the test

    Listing 7

    pom.xml

    org.jboss.arquillian.container

    arquillian-weld-ee-embedded-1.1

    1.0.0.CR3

    test

    org.jboss.weld

    weld-core

    1.1.1.Final

    test

    org.slf4j

    slf4j-simple

    1.5.10

    test

  • 8/13/2019 CDI Extensions JTJ 2012 02

    25/28

    Arquillian

    www.JAXenter.com |March 2012 25

    and must be injected into the constructor of Greeter whenan instance of Greeter is created. We can be certain CDI is atwork if all that comes together.

    One last step. Because we created a new class, we must besure that its getting added to the archive returned by the @Deployment method in the test. Simply change the line:

    .addClass(Greeter.class)

    ...to read:

    .addClasses(Greeter.class, PhraseBuilder.class)

    Run the test again. You should get another green bar! Feelsgood, doesnt it?

    Debug the test

    This is going to be a short chapter. Why? Because an Arquil-lian test is so straightforward that you debug it exactly howyou debug a unit test. Just add a breakpoint anywhere either

    in the test or in the application code. Then right-click on thefile and select D A | JU T (figure 5).Youre nowdebugging in the container! Have fun poking around!

    If you are using a remote container, D A does not causebreakpoints to be activated. Instead, you need to start the con-tainer in debug mode and attach the debugger. Thats becausethe test is run in a different JVM than the original test runner.

    As youve just witnessed, Arquillian is the ideal tool fortesting CDI applications. It takes care of loading the CDI en-vironment and injecting beans directly into the test. Best ofall, when using an embedded CDI container, the test runs justas quickly as a unit test. If thats all you need, then you can

    exit the tutorial now and start writing tests.

    But! Is the embedded container telling the whole story? Will

    the component work if running inside a full container?One of the perks of Arquillian is that you can run the same

    test in different compatible containers, whether its anotherembedded container or a standalone container. If you intendto use multiple containers, read on.

    Add more containers

    As you learned earlier, Arquillian selects the container basedon which container adapter is on the classpath. To switch toanother container, you just change which container adapteris on the classpath before you run the test. There can only beone container adapter on the classpath at a given time.

    One way to swap the libraries on the classpath is to manu-ally edit the dependencies defined in thepom.xmleach time.But thats just crazy. Theres a much better way.

    We can use Maven profiles to partition the dependenciesinto groups, one group for each container adapter and its re-lated artifacts. When running the tests, you activate one ofthose groups to select the container using either a command-line flag (-P) or a preference in the IDE.

    Open up thepom.xmland create a new profile for Weld EEembedded by inserting the following XML directly under theelement (listing 10).

    Next, remove the jboss-javaee-6.0 dependency and thedependencies for the Weld EE embedded container adapter

    from the main section. Listing 11 shows howthe and sections should look whenyoure done.

    The Java EE API dependency has been moved to the pro-file since some containers, like Embedded GlassFish, alreadyprovide these libraries. Having both on the classpath at thesame time would result in conflicts. So we have to play thisclasspath dance.

    Well now include two additional profiles in the pom.xmlinside the element, the first for Embedded Glass-Fish ([14], listing 12).

    Now you have the choice of running the tests in one of

    three containers. If youre having trouble with thepom.xmlup to this point, you can download the file from the gist[15].

    Listing 9

    src/main/java/org/arquillian/example/Greeter.java

    package org.arquillian.example;

    import java.io.PrintStream;

    import javax.inject.Inject;

    public class Greeter {

    private PhraseBuilder phraseBuilder;

    @Inject

    public Greeter(PhraseBuilder phraseBuilder) {

    this.phraseBuilder = phraseBuilder;

    }

    public void greet(PrintStream to, String name) {

    to.println(createGreeting(name));

    }

    public String createGreeting(String name) {

    return phraseBuilder.buildPhrase("hello", name);

    }

    }

    Fig. 5: Debugging the container

  • 8/13/2019 CDI Extensions JTJ 2012 02

    26/28

    Arquillian

    www.JAXenter.com |March 2012 26

    Test across containers

    When you refresh the project in Eclipse, youll notice that itno longer builds. Thats because you need to activate one ofthe container profiles. Lets activate the Weld EE embeddedprofile to restore the previous state. There are two ways toactivate a Maven profile in Eclipse:

    1. Manual configuration (standard approach)2. Maven profile selector (JBoss Tools)

    Set active Maven profile: manual configuration

    To set the active profile manually, follow these steps:

    1. Right click on the project and select Properties2. Select the Maven properties tab3. Enter the profile id in the Active Maven Profiles field (e. g.,

    arquillian-weld-ee-embedded)4. Click the OK button and accept the project changes

    Figure 6displays the Maven properties screen showing theprofile weve activated.

    Set active Maven profile: Maven profile selector

    If you have JBoss Tools installed, selecting the active profilebecomes much easier:

    1. Right click on the project and select M | SA P

    2. (alternatively, you can use the keybinding Ctrl+Shift+P orthe button in the toolbar)

    3. Check the box next to the profile you want to activate (e.g.,arquillian-weld-ee-embedded)

    4. Click the OK button

    Listing 11

    pom.xml

    junit

    junit

    4.8.1

    test

    org.jboss.arquillian.junit

    arquillian-junit-container

    test

    arquillian-weld-ee-embedded

    org.jboss.spec

    jboss-javaee-6.0

    1.0.0.Final

    pom

    provided

    org.jboss.arquillian.container

    arquillian-weld-ee-embedded-1.1

    1.0.0.CR3

    test

    org.jboss.weld

    weld-core

    1.1.1.Final

    test

    org.slf4j

    slf4j-simple

    1.5.10

    test

    Listing 10

    pom.xml

    arquillian-weld-ee-embedded

    org.jboss.spec

    jboss-javaee-6.0

    1.0.0.Final

    pom

    provided

    org.jboss.arquillian.container

    arquillian-weld-ee-embedded-1.1

    1.0.0.CR3

    test

    org.jboss.weld

    weld-core

    1.1.1.Final

    test

    org.slf4j

    slf4j-simple

    1.5.10

    test

  • 8/13/2019 CDI Extensions JTJ 2012 02

    27/28

    Arquillian

    www.JAXenter.com |March 2012 27

    Figure 7displays the Maven profile selector dialog showingthe profile weve activated.

    Once you have activated the profile, you should be able torun the test again successfully.

    You already know the test works in Weld EE Embedded.Lets switch to GlassFish Embedded by repeating the stepsabove, this time activating only the arquillian-glassfish-em-bedded profile. Run the test again. You should see GlassFishstart in the consoleand another green bar!

    Youve now run the same test on two different embeddedcontainers, a CDI container (Weld) and a Java EE container(GlassFish). Both of these executions are in process. To really

    be sure the component works in a pure environment, we needto use a standalone container. Lets switch to using JBoss AS.To run the test on a standalone instance of JBoss AS, you

    first need to set it up. You can either:

    1. download and unpack it in a location outside the project or2. you can have Maven download and unpack it during a

    build.

    Follow these steps to setup JBoss AS 7 outside the project:

    1. Download JBoss AS 7 [16]2. (be sure the version you select matches the version youve

    defined in your pom.xml for jboss-as-arquil-lian-container-managed )

    3. Extract the archive4. (optional) Set theJBOSS_HOMEenvironment variable to

    the path of the extracted directory

    To have Maven handle this task for you instead, add the fol-lowing XML fragment under the element of the arq-jbossas-managed profile (listing 13).

    To target a managed JBoss AS 7 instance, you also needa small bit of Arquillian configuration. Create the followingconfiguration file and assign the value of thejbossHomeprop-

    erty to the location where JBoss AS 7 is installed. If youreusing the Maven dependency plug-in, the location is target/jboss-as-7.0.2.Final(listing 14).

    Listing 12

    pom.xml

    arquillian-glassfish-embedded

    org.jboss.arquillian.container

    arquillian-glassfish-em