Wednesday Jun 23, 2010

QA#2: Java EE 6: Integrated specifications, simple and annotation driven, next level of industry standard - by Markus Eisele

This blog entry is second (previous ones) in the Java EE 6 feedback from the community series. You can learn about how Java EE 6 is currently being used in production, development and deployment environments used within the community, and even feature requests for Java EE 7.
This entry comes from Markus Eisele - a senior technology consultant working for msg systems ag in Germany. The msg systems ag is one of the top 10 IT consulting and systems integration companies in Germany. Markus works as a software architect, developer and consultant. He also writes for German IT magazines. Markus joined msg in 2000 and has been a member of the
Center of Competence IT-Architecture since then. After being a Technical Director with BEA Systems, he has been a proud member of the Oracle ACE Directors program since 2008 (for Fusion Middleware and SOA). He works daily with customers and projects dealing with Enterprise Java and other new technologies, on a variety of platforms using different vendors. You can catch him on @myfear or read his blog.

Here is a short summary of Java EE 6 from him:

Higher integrated specifications, simple and annotation driven, single-classloader WARs, next level of industry standard


Read on for other fun stuff ...

1. How are you using Java EE 6 today ? What limits your adoption ?

Enterprise Java has been my business since more than 9 years now. The first J2EE server I was using was the former BEA WebLogic 5.1. It supported Java 2 Platform, Enterprise Edition Specification, v. 1.2 (containing EJB 1.1, JDBC 2.0, JSP 1.1, Servlet 2.2). To be honest, it wasn't big fun looking back into these days. There was lots of configuration and weird coding. And don't even think about full-blown IDE support. It was very basic and lots of coding had to be done without any assistance.

Compared to that Java EE 6 seems to be this feels as if it is light years ahead. So many things happened to the standard in the past and it is still very exiting to see the ongoing changes. Even though I am not a member of any related expert group, I am closely monitoring the public discussions and outcomes. What I can evaluate more is the adoption in the enterprise with our customers. They are more like fast followers than early adopters. And that's basically the setup I am looking at Java EE 6 today. More from an educational or research point of view. The goal is to be ready when first customers jump in. We have to answer questions for them, like:

- What can we do to migrate existing applications?
- What is the most standards compliant way of using this technology?
- What application servers should we use?
- What do the new specifications save in terms of time and/or money?
- How stable are new product versions?

If first projects start using new standards, we will be there to support them and already have answers at hand. At the moment we do not start over with Java EE 6 in projects. First projects are expected with the first commercial server versions from Oracle or IBM (WebLogic respectively WebSphere). Some of our customers are using GlassFish and they are sticking to the latest GlassFish 2.x versions while waiting for the clustering support coming in GlassFish 3.1. In the meantime we try to enable the developers with workshops and informative sessions about new features and updated specs.



2. What Java EE 6 technologies are you using and why ?

I am still working my way through the new features at the moment. Of both: GlassFish 3.x and Java EE 6. I started with the new CDI (JSR-299 + JSR-330) capabilities and looked at the improvements for implementing business logic with EJB 3.1 and JPA 2.0. The JSF 2.0 features gave a face to many of my prototypes.

The biggest improvements at the moment are the no-interface beans and the JPA 2.0 enhancements. In combination with the single-classloader model of WAR-deployment this is very handy for even the smallest applications. A situation we were forced to use Spring or other frameworks in the past. The ongoing annotation support is another feature-set I love to see. The reduced configuration effort with xml files seems handy but could bear risks for bigger applications using different frameworks and libraries. A big part of our daily work is cluster related. Therefore I am experimenting with the first 3.1 milestones at the moment.



3. What is your development and deployment environment ?

This is highly dependent on our customers. There is no single, company wide directive on what to use. The majority is using Eclipse. I personally prefer the latest Oracle Version (OEPE) but also have different plain Eclipse versions in use. Experimenting with GlassFish 3 I often use NetBeans 6.9 for demonstrations because of the very good GlassFish and Java EE 6 integration. I tend to be very close to productive environments in development. Therefore I am rarely using other databases than Oracle or DB2. I personally love to use MySQL for PoCs or demos.

In general we use lots of other environments based upon customer needs. Maven is the favorite build tool of choice at the moment. Longer running projects however still stick to ANT.



4. What previous versions of Java EE / J2EE have you used ? How has the migration to Java EE 6 benefited ?

I used J2EE since 1.2. Simple, technical migration from one product version to another was not too challenging at all in the past. Problems arose from switching vendors (Oracle/IBM) or updating specifications with major functional changes (CMP/JPA). Most challenging are customers staying with older product versions (and their bugs and needed workarounds). The pollution with workarounds and fixes never did any good in projects. Thankfully the times of custom frameworks to hide complexity seems to be up since Java EE 5. This was probably the most expensive part in many J2EE/Java EE 5 migrations in the past.

Seeing the advantages in OSGi based servers customers will hopefully be able to adopt new standards more easier in the future. Most valuable will be the new Web Profile. Most applications simply use the included specifications and could run on lighter environments. With the new CDI specifications we could remove some third party solutions and put it in the standard way. The so far missing JAX-RS closes a big gap left open by Java EE 5.



5. Describe the benefits of Java EE 6 to you in 120 characters.

Higher integrated specifications, simple and annotation driven, single-classloader WARs. Next level of industry standard.


6. Advice for anybody who is looking at Java EE 6 for their next project ?

If you are asking for available servers and the question, which specification is right for me today, I already tried to answering this in my blogpost http://blog.eisele.net/2010/05/java-ee-5-or-6-which-to-choose-today.html.

The programming approach itself is a advancement of existing Java EE 5 projects. Everything is pointing into the direction of POJOs and more Java SE like programming. Container services should be injected respectively annotated in a last step; if needed. Programming is getting more closer to solving business problems and not to the fulfillment of specification or container requirements.



7. What new features you'd like to see in Java EE 7 ?

I think the specifications are more or less feature complete. Of course I can think of a lot of improvements and I believe it's important to stay up to date and integrate new approaches.

If you look at JSF and the RI for example, I am still missing a lot of more complex components. I always find myself implementing one or two own in my projects. If you work for  more restrictive enterprises, you are not always able to use the component suite of choice. If possible I still prefer to work with either RichFaces or PrimeFaces. Further on the cooperation between JSR 299 and JSR 330 should be clearer in general. The interaction between all JSRs should be taken to a next level. Clear but abstract guidelines
have to be specified, who is working with whom and how. If you look at the @ManagedBean annotation for example, you have three different ways of defining beans that are managed (JSR-314, JSR-316, JSR-299). That's not exactly what I would call intuitive ;)

Generally I would love to see the Managed Beans specification becoming the heart of enterprise java. Containers should belong to the past. Services should be available to POJOs and injected (and of course started) as needed. This could speed up the whole environment a lot and frees developers from having to implement interfaces. But the most important improvements would be administrative. Java EE 7 should put those pruning ideas forward and realy try to drop some old stuff. And finally it is time to
solve all those never-ending licensing discussions about the TCKs!

Are you using, consulting, training, authoring books, etc in Java EE 6 ? Drop a comment on this blog and I'll line you up for the Q&A session :-)

The Java EE 6 hub is your key resource to learn all about the technology.

And you can always try all Java EE 6 features in GlassFish.

Technorati: javaee6 community feedback markuseisele glassfish v3

Friday Jun 18, 2010

QA#1 - Java EE 6: Standards compliance, Vendor independence, Light-weight deployment - by Adam Bien

The Java EE 6 platform was released over 6 months ago - Dec 10, 2009 to be specific. This blog has published multiple blog entries highlighting the agility, light-weight, ease-of-development, extensibility, and other aspects of the platform. This blog entry starts a new series sharing feedback gathered from the key Java EE 6 community members in form of Q&A. You can learn about how Java EE 6 is currently being used in production, development and deployment environments used within the community, and even feature requests for Java EE 7.
The first one comes from consultant and author Adam Bien (blog.adam-bien.com) who is an Expert Group member for the Java EE 6, EJB 3.1, and JPA 2.0 JSRs. He has worked with Java technology since JDK 1.0 and Servlets/EJB 1.0 in several large-scale projects and is now an architect and developer in Java SE/EE/FX projects. He has edited several books about Java (FX) and J2EE / Java EE and is the author of Real World J2EE Patterns (http://press.adam-bien.com). Adam is a Java Champion and JavaOne 2009 Rock Star.

Here is a short summary of Java EE 6 from him:

Standards compliance, vendor independence, milliseconds and kilobyte deployment

Read on for other fun stuff ...

1. How are you using Java EE 6 today ? What limits your adoption ?

For server-side development Java EE 6 is the simplest thing you can get today. Because I’m lazy - Java EE 6 is the obvious choice. You can get everything you need with a single download. It works really well. Recently I let 20 students in a workshop install IDE, application server + database ...in 15 minutes. After that we started hacking. The machines were really heterogenous (Windows, Mac, Linux)- and it worked.

I’m using Java SE and EE since their inception. I didn’t used EJB 1.0 (it was before J2EE), but started with 1.1. In several projects I had to use J2EE but omitted successfully the XML-hell with XDoclet.

This was fixed with Java EE 5 - since then (>4years) there are no more workarounds necessary and you can fully concentrate on the business logic. Java EE 6 became even better.

The adoption of Java EE is far better, than expected (by me). It turns out, that in economic slow down management is really interested in standards again. This is the only explanation I have. Java EE 6 seems to take off. I had to limit the number of registrations in last workshops to 20 and repeat a workshop at a JAX-conference (one of the biggest European conferences). The organizer ask me, whether I would like to repeat a workshop, because they were already 75 registrations. The workshop was repeated - ...with about 160-180 attendees.

J2EE was said to be too complex for simple applications. The opposite is true in Java EE 6. It turns out to be any leaner, simpler and more maintainable comparing it with the alternatives. All attempts of wheel re-invention I saw so far resulted in far more complex and harder to understand code.



2. What Java EE 6 technologies are you using and why ?

I’m really enjoying the single-classloader model of WAR-deployment. In all new Java EE 6 projects we got rid off “modular” EARs and EJB-JARs and deployed everything into a WAR. It doesn’t seem to be hype-compatible, but it works very well. Especially if you don't have any additional versioning or modularization requirements. The lack of dynamic reloading and module-hot-replacement in product is given for the majority of all enterprise projects. In real world the deployment units become even coarser.

I start the implementation of the business logic with EJB 3.1 and JPA 2.0. In case remoting is necessary - I use REST (JAR-RS) with JSON for the vast majority of all cases. CDI (JSR-299 + JSR-330) is even more powerful, but I don’t use the extended dependency injection capabilities (produces, alternatives, custom annotations, stereotypes, events) from the beginning, rather than applying them selectively to solve particular problems. CDI allows you to realize a factory, observer or strategy patterns without any overhead. In fact a plain Java SE solution would be even more bloated.

For the web part - I start with JSF 2.0. Also the adoption of JSF 2.0 is unique. There are many books, tutorials, frameworks and libraries available already. I attended a JSF conference this year with several hundred attendees.

Frameworks like Wicket or GWT are very interesting. I always start, however, with the evaluation of JSF 2. Is is already available on every Java EE 6 server - so why don’t use it. 

I would choose the alternative web frameworks, in case there is an evidence that the solution would be leaner, cheaper or easier to maintain. In the majority of all recent cases - JSF 2.0 was just good enough. Before JSF 2.0 I often used Wicket.

3. What is your development and deployment environment ?

I’m using mainly NetBeans 6.9 “Java Edition” with Glassfish v3 and Java DB / Derby (in early iterations). After the setup and stabilization phase I always use the production databases. These are mainly Oracle, sometimes DB 2 or MySQL.

In smaller teams I prefer the NetBeans build-system (Ant). In bigger teams and projects Maven. NetBeans supports both flavors really well, but Ant incremental deployment is orders of magnitudes faster than maven. You can redeploy an EJB/CDI or JPA entity with Ant in millisecods, with Maven it will take seconds. This is a huge productivity gain.

I also have an IntelliJ 9.0.2 Ultimate license and use this IDE as well. It excels NetBeans in some areas like e.g. JPA QL autocompletion. These features, however, are part of the commercial distribution and so hard to introduce into teams. In most cases I fallback to NetBeans.


4. What previous versions of Java EE / J2EE have you used ? How has the migration to Java EE 6 benefited ?

I used J2EE since 1999. The migrations were never fun. Except the migrations from J2EE into Java EE 5. Because Java EE 5/6 have still to support the old J2EE components, you can deploy your old application into a new server and start to delete code. The benefits are obvious: you can delete > 60% of the code without any impact on the functionality. With the code you can also get rid off strange patterns, extensive layering and other strange “legacy” practices. This leads to reduction of the maintenance costs.

5. Describe the benefits of Java EE 6 to you in 120 characters.

Standards compliance, vendor independence, milliseconds and kilobyte deployment.

6. Advice for anybody who is looking at Java EE 6 for their next project ?

Reduce to the max. Concentrate on the business logic and not the technology. Write plain Java SE domain objects first (Unit-Tests of course before that :-)), introduce EJB 3.1 / CDI facades later. Don’t even try to use everything what is offered by Java EE 6. But before you start to implement you own solution, look at Java SE 6 first, then Java EE 6. You will be surprised how much functionality is already there.

7. What new features you'd like to see in Java EE 7 ?

Further simplification and unification of the APIs would be great. The synergies of JSF 2, EJB and CDI could be a lot more leveraged. A more natural use of java.util.concurrent in Java EE would be also interesting (e.g. injection of Executors). For all of my cases @Asynchronous worked perfectly, but Executors seem somehow to fascinate developers :-)

JPA 2.0 could be also extended with some useful features like support of resource injection (EntityManager is the most important) into JPA-entities. Its a controversial topic - but really important for projects. Also better support for stateful environments would be nice.

I would also expect a standardized JAX-RS client. Something like jersey, but with javax.ws.rs. prefix :-)

I’m really surprised, that actually no-one really complains over the really old JMS programming model (1997). This spec could be drastically simplified. A plain injection of a simplified queue or topic would be sufficient for > 80% of all cases.

Are you using, consulting, training, authoring books, etc in Java EE 6 ? Drop a comment on this blog and I'll line you up for the Q&A session :-)

The Java EE 6 hub is your key resource to learn all about the technology.

And you can always try all Java EE 6 features in GlassFish.

Technorati: javaee6 community feedback adambien glassfish v3

Wednesday Jun 02, 2010

TOTD #140: Moving GlassFish Installation - Referenced file does not exist "osgi-main.jar"

This is a quick Tip Of The Day (TOTD) to show how to get GlassFish running again if the directory is moved to a new location after it has been started once. Note, of course, you are not moving the directory while the server is running. Its only after the server has been started once at least and stopped.

If you move your GlassFish installation to a different directory then you may see errors like:

ERROR: Error creating archive. (java.io.IOException: Referenced file does not exist: /Users/arungupta/tools/glassfish/v3/glassfishv3/glassfish/modules/osgi-main.jar)
java.io.IOException: Referenced file does not exist: /Users/arungupta/tools/glassfish/v3/glassfishv3/glassfish/modules/osgi-main.jar
        at org.apache.felix.framework.cache.BundleArchive.createRevisionFromLocation(BundleArchive.java:994)
        at org.apache.felix.framework.cache.BundleArchive.revise(BundleArchive.java:631)
        at org.apache.felix.framework.cache.BundleArchive.(BundleArchive.java:206)
        at org.apache.felix.framework.cache.BundleCache.getArchives(BundleCache.java:149)
        at org.apache.felix.framework.Felix.init(Felix.java:558)
        at org.apache.felix.main.Main.main(Main.java:292)
. . .
org.osgi.framework.BundleException: Bundle symbolic name and version are not unique: com.sun.grizzly.grizzly-config:1.9.18.k
 at org.apache.felix.framework.BundleImpl.createModule(BundleImpl.java:1145)
 at org.apache.felix.framework.BundleImpl.<init>(BundleImpl.java:79)
 at org.apache.felix.framework.Felix.installBundle(Felix.java:2372)
. . .
May 30, 2010 4:27:05 PM Main install
WARNING: Failed to install file:/Users/arungupta/tools/glassfish/v3/glassfishv3-2/glassfish/modules/grizzly-config.jar
org.osgi.framework.BundleException: Bundle symbolic name and version are not unique: com.sun.grizzly.grizzly-config:1.9.18.k
 at org.apache.felix.framework.BundleImpl.createModule(BundleImpl.java:1145)
 at org.apache.felix.framework.BundleImpl.<init>(BundleImpl.java:79)
 at org.apache.felix.framework.Felix.installBundle(Felix.java:2372)
. . .

Fortunately the fix is simple, just remove your "domains/domain1/osgi-cache" directory. The cache will be rebuilt during the next run of GlassFish.

Technorati: totd glassfish v3 osgi cache error

Monday May 31, 2010

TOTD #139: Asynchronous Request Processing using Servlets 3.0 and Java EE 6

Server resources are always valuable and should be used conservatively. Consider a Servlet that has to wait for a JDBC connection to be available from the pool, receiving a JMS message or reading a resource from the file system. Waiting for a "long running" process to completely blocks the thread - waiting, sitting and doing nothing - not an optimal usage of your server resources. Servlets 3.0 introduces the ability to asynchronously process requests such that the control (or thread) is returned back to the container to perform other tasks while waiting for the long running process to complete. The request processing continues in the same thread after after the response from the long running process is returned or or may be dispatched to a new resource from within the long running process. A typical use case for long running process is a Chat Application.

The asynchronous behavior need to be explicitly enabled on a Servlet. This is achieved by adding "asyncSupported" attribute on @WebServlet as shown below:

@WebServlet(name="AsyncServlet", urlPatterns={"/AsyncServlet"}, asyncSupported=true)
public class AsyncServlet extends HttpServlet {

The asynchronous processing can then be started in a separate thread using "startAsync" method on the request. This method returns "AsyncContext" which represents the execution context of the asynchronous request. The asynchronous request can then be completed by calling AsyncContext.complete (explicit) or dispatching to another resource (implicit). The container completes the invocation of asynchronous request in the later case.

Lets say the long running process is implemented as:

class MyAsyncService implements Runnable {
    AsyncContext ac;

    public MyAsyncService(AsyncContext ac) {
        this.ac = ac;
    }

    @Override
    public void run() {
        System.out.println("Some long running process in \\"MyAsyncService\\"");
    }
}

Note this is running in a separate thread. This service can be invoked from the original servlet as:
AsycnContext ac = request.startAsync();

The service may also be started as:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new MyAsyncService(ac));

The ScheduledThreadPoolExecutor usage is recommended as it makes the thread management easier.

A listener can be associated with the AsyncContext to get notified of when the async request is complete, timed out, or resulted in an error. This can be achieved as:

ac.addListener(new AsyncListener() {

    @Override
    public void onComplete(AsyncEvent event) throws IOException {
        System.out.println("onComplete.");
    }

    . . .
});

A more complete code for the above fragment is given below. The "onComplete" method is used to clean up resources created during async processing.

The asynchronous request processing can be either completed in "run" method of "MyAsyncService" by invoking "AsycnContext.complete" as shown below:

@Override
public void run() {
    System.out.println("Some long running process in \\"MyAsyncService\\"");
    ac.complete();
}

or dispatched to a different resource as:

@Override
public void run() {
    System.out.println("Some long running process in \\"MyAsyncService\\"");
    ac.dispatch("/response.jsp");
}

Lets take a look at our complete code:

@WebServlet(name="AsyncServlet", urlPatterns={"/AsyncServlet"}, asyncSupported=true)
public class AsyncServlet extends HttpServlet {
   
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try {
            System.out.println("Starting doGet");
            AsyncContext ac = request.startAsync();
            ac.addListener(new AsyncListener() {

                @Override
                public void onComplete(AsyncEvent event) throws IOException {
                    System.out.println("onComplete");
                }

                @Override
                public void onTimeout(AsyncEvent event) throws IOException {
                    System.out.println("onTimeout");
                }

                @Override
                public void onError(AsyncEvent event) throws IOException {
                    System.out.println("onError");
                }

                @Override
                public void onStartAsync(AsyncEvent event) throws IOException {
                    System.out.println("onStartAsync");
                }
            });

            System.out.println("Do some stuff in doGet ...");


            // Start another service
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
            executor.execute(new MyAsyncService(ac));

            System.out.println("Some more stuff in doGet ...");
        } finally { 
        }
    }

    class MyAsyncService implements Runnable {
        AsyncContext ac;

        public MyAsyncService(AsyncContext ac) {
            this.ac = ac;
            System.out.println("Dispatched to " + "\\"MyAsyncService\\"");
        }

        @Override
        public void run() {
            System.out.println("Some long running process in \\"MyAsyncService\\"");
            ac.complete();
        }
    }
} 

Invoking the GET operation of this Servlet shows the following sequence of statements in GlassFish server log:

INFO: Starting doGet
INFO: Dispatched to "MyAsyncService"
INFO: Doing some stuff in doGet ...
INFO: Some more in doGet ...
INFO: Some long running process in "MyAsyncService"
INFO: onComplete

The first statement marks the beginning of "doGet", the second statement indicates that the request is dispatched to the long running
"MyAsyncService", the third and fourth statement indicates that the response returned back to "doGet" for normal request processing. Finally fifth and sixth statement shows that now the asynchronous request is getting processed and is completed.

Clean and simple!

A request may be dispatched from Asynchronous servlet to Synchronous but other way around is illegal. The section 2.3.3.3 in the Servlets 3.0 specification provides an introduction to the Asynchronous Processing in Servlets 3.0.

The asynchronous behavior is available in the Servlet Filter as well.

The complete code used in this blog can be downloaded here. A fully working sample of a Chat Application using Servlets 3.0 can be seen here.

Technorati: totd glassfish v3 servlets javaee asynchronous comet

Tuesday May 18, 2010

TOTD #137: Asynchronous EJB, a light-weight JMS solution - Feature-rich Java EE 6

One of the new features introduced in Enterprise Java Beans 3.1 (JSR 318)  is asynchronous invocation of a business method. This allows the control to return to the client before the container dispatches the instance to a bean. The asynchronous operations can return a "Future<V>" that allow the client to retrieve a result value, check for exceptions, or attempt to cancel any in-progress invocations.

The "@Asynchronous" annotation is used to mark a specific (method-level) or all (class-level) methods of the bean as asynchronous. Here is an example of a stateless session bean that is tagged as asynchronous at the class-level:

@Stateless
@Asynchronous
public class SimpleAsyncEJB {

    public Future<Integer> addNumbers(int n1, int n2) {
        Integer result;

        result = n1 + n2;
        try {
            // simulate JPA queries + reading file system
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        return new AsyncResult(result);
    }
}

The method signature returns "Future<Integer>" and the return type is "AsyncResult(Integer)". The "AsyncResult" is a new class introduced in EJB 3.1 that wraps the result of an asynchronous method as a Future object. Under the covers, the value is retrieved and sent to the client. Adding any new methods to this class will automatically make them asynchronous as well.

The 2 second sleep simulates server side processing of the response which may involve querying the database or reading some information from the filesystem.

This EJB can be easily injected in a Servlet using the normal way:

@EJB SimpleAsyncEJB ejb;

This business method can be invoked in the "doGet" method of a Servlet as:

PrintWriter out = response.getWriter();
try {
    Future<Integer> future = ejb.addNumbers(10, 20);
    print(out, "Client is working ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    }

    print(out, "Client is working again ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    }

    print(out, "Client is still working ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    } else {
        print(out, "Response is now ready");
    }

    Integer result = future.get();

    print(out, "The result is: " + result);
} catch (InterruptedException ex) {
    ex.printStackTrace();
} catch (ExecutionException ex) {
    ex.printStackTrace();
} finally { 
    out.close();
}

The control is returned to the client right after the the EJB business method is invoked and does not wait for the business method execution to finish. The methods on "Future" API are used to query if the result is available. The "Thread.sleep()" for 1 second simulate that client can continue working and possibly check for results at a regular interval. The "print" is a convenience method that prints the string to "response.getWriter" and flushes the output so that it can be instantly displayed instead of getting buffered. Invoking this "doGet" shows the following output:

1274142978365: Client is working ...
1274142979365: Response not ready yet ...
1274142979365: Client is working again ...
1274142980366: Response not ready yet ...
1274142980366: Client is still working ...
1274142981366: Response is now ready
1274142981366: The result is: 30

The client transaction context does not and security context do propagate from the client to the asynchronous business method.

Up until now, any kind of asynchrony in the EJB required to use the Message Driven Beans which in turn required some JMS setup. Introduction of this feature allows you to easily incorporate asynchrony in your EJB applications.

Try this and other Java EE 6 features in GlassFish Server Open Source Edition 3 or Oracle GlassFish Server today!

The complete source code used in this blog can be downloaded here.

Technorati: totd javaee ejb asynchronous glassfish v3

Monday May 17, 2010

TOTD #136: Default Error Page using Servlets 3.0 - Improved productivity using Java EE 6

Servlets 2.x allowed to create a mapping between an HTTP error code or an exception type to the path of a resource in the Web application. This is achieved by specifying an "error-page" element in the "web.xml". The element definition looks like:

So any HTTP error code or an exception thrown within the application can be mapped to a resource bundled with the application. Here is a sample:

<error-page>
     <error-code>404</error-code>
     <location>/error-404.jsp</location>
</error-page>

Adding the above fragment in "web.xml" of an application will display "error-404.jsp" page to the client if a non-existing resource is accessed. This mapping can be easily done for other HTTP status codes as well by adding other <error-page> elements.

Similarly, <exception-type> element can be used to map an exception to a resource in the web application. This allows fine-grained mapping of errors from your web application to custom pages.

Starting with Servlets 3.0, <error-code> and <exception-type> elements are optional. An <error-page> without any <exception-type> and <error-code> will be considered as the webapp's default error page, and will act as a "catch-all" for any error codes or exception types. It will be an error if a web.xml contains more than one such default error page.

A default error page may be overridden for specific exception types and error codes. For example:

     <error-page>
       <location>/error-default.jsp</location>
     </error-page>

     <error-page>
       <error-code>404</error-code>
       <location>/error-404.jsp</location>
     </error-page>

Any response with a status code other than 404 will be error-dispatched to /default.jsp, while a 404 response will be error-dispatched to /error-404.jsp.

So if the Servlet code looks like:

@WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"})
public class HelloServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, 
                         HttpServletResponse response) throws IOException {
        String type = (String)request.getParameter("type");

        if (type == null) {
            response.getWriter().print("hello world"); 
            return;
        }

        if (type.equals("helloex")) {   
          throw new HelloException();
        } else if (type.equals("ncdfe")) {
            throw new NoClassDefFoundError();
        } else {
            throw new NullPointerException();
        }
    }
}

And the "web.xml" looks like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <error-page>
       <exception-type>java.lang.NoClassDefFoundError</exception-type>
       <location>/error-ncdfe.jsp</location>
    </error-page>
    <error-page>
       <exception-type>server.HelloException</exception-type>
       <location>/error-helloex.jsp</location>
    </error-page>
    <error-page>
       <error-code>404</error-code>
       <location>/error-404.jsp</location>
    </error-page>
    <error-page>
       <location>/error-default.jsp</location>
    </error-page>
</web-app>

Lets say the directory structure looks like:

WEB-INF/classes/
WEB-INF/classes/server/
WEB-INF/classes/server/HelloException.class
WEB-INF/classes/server/HelloServlet.class
WEB-INF/web.xml
error-404.jsp
error-default.jsp
error-helloex.jsp
error-ncdfe.jsp

and this application is deployed as "DefaultErrorPage.war". Then here is a table of the page that gets displayed when the URL mentioned in the first column is accessed:

URL Response Comment
http://localhost:8080/DefaultErrorPage/HelloServlet "hello world" Expected result
http://localhost:8080/DefaultErrorPage/HelloServlet2 error-404.jsp HTTP 404
http://localhost:8080/DefaultErrorPage/HelloServlet?type=ncdfe error-ncdfe.jsp System exception
http://localhost:8080/DefaultErrorPage/HelloServlet?type=helloex error-helloex.jsp User exception
http://localhost:8080/DefaultErrorPage/HelloServlet?type error-default.jsp Catch-all exception


Try this and other Java EE 6 features in GlassFish Server Open Source Edition 3 or Oracle GlassFish Server today!

The complete source code used in this blog can be downloaded here.

The default setting in Chrome is to show suggestions to navigate to other parts of the website or search with Google. This can be easily disabled by Chrome -> Preferences -> Under the Hood and deselecting "Show suggestions for navigation errors" in Privacy section. This is explained in detail here.

Technorati: totd javaee glassfish v3 servlet default error

Tuesday May 11, 2010

TOTD #135: JSF2 Composite Components using NetBeans IDE - lightweight Java EE 6

NetBeans IDE provide comprehensive feature set to build applications using Java Server Faces 2 (JSR 314). This Tip Of The Day (TOTD) explains how to create JSF composite components using wizards provided by the NetBeans IDE.

The JSF2 specification, section 3.6 defines composite components as:

A tree of "UIComponent" instances, rooted at a top level component, that can be thought of and used as a single component in a view. The component hierarchy of this subtree is described in the composite component defining page.

This definition is good from the specification perspective but can help with some layman explanation. Essentially, a composite component is what it says - a composition of two or more components such that it behaves like a single component. For example, consider four components in a panel grid where 2 components are "h:outputText" to display prompts and other 2 are "h:inputText" to receive input from the user. The composite components allow all of these components (1 panel grid + 2 "h:inputText" + 2 "h:outputText") packaged as a single component.

Resource Handling and Facelets, both features newly introduced in the JSF2 specification, makes the creation of composite component much easier. The Resource Handling defines a standard location for bundling resources in a web application and Facelets defines a cleaner templating language that enables composition. In technical terms:

A composite component is any Facelet markup file that resides inside of a resource library.

Lets create a simple Web application using JSF 2 that accepts a username/password and displays it in a new page. The application is first created using the traditional "h:inputText" and "h:outputText" elements and is then converted to use a composite component.

Before we dig into composite component creation using JSF2, here are the steps listed to create one using JSF 1.2:

  1. Implement UIComponent subclass
  2. Markup rendering code in Renderer
  3. Register your component and renderer in faces-config.xml
  4. Implement your JSP tag
  5. And the TLD

There is Java code involved, sub-classing from JSF classes, deployment descriptor editing in "faces-config.xml", declaring TLDs and then implementing the JSP tag. Creating a composite component in JSF 1.2 was quite a chore and spread all over. There are lots of files

With that background, lets see what it takes us to create a composite component using JSF2.

The CDI backing bean for the application looks like:

package server;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("simplebean")
@RequestScoped
public class SimpleBean {
    String name;
    String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The "index.xhtml" Facelet markup file looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Enter Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Enter Name &amp; Password</h1>
    <h:form>
      <h:panelGrid columns="2">
        <h:outputText value="Name:"/>
        <h:inputText value="#{simplebean.name}" title="name" 
                     id="name" required="true"/>
        <h:outputText value="Password:"/>
        <h:inputText value="#{simplebean.password}" title="password" 
                     id="password" required="true"/>
      </h:panelGrid>
      <h:commandButton action="show" value="submit"/>
    </h:form>
  </h:body>
</html>


And the "show.xhtml" Facelet markup looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Show Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Show Name &amp; Password</h1>
    <h:panelGrid columns="2">
      <h:outputText value="Name:"/>
      <h:outputText value="#{simplebean.name}" />
      <h:outputText value="Password:"/>
      <h:outputText value="#{simplebean.password}" />
    </h:panelGrid>
  </h:body>
</html>



Now select the <panelGrid> fragment in "index.xhtml" as shown below:

Right-click and select "Convert To Composite Component ..." and specify the values as given in the wizard below:

Note, most of the values are default and only the "File Name:" is changed. After clicking on "Finish" in the wizard, the updated page looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:ez="http://java.sun.com/jsf/composite/ezcomp">
  <h:head>
    <title>Enter Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Enter Name &amp; Password</h1>
    <h:form>
      <ez:username-password/>
      <h:commandButton action="show" value="submit"/>
    </h:form>
  </h:body>
</html>

The namspace/prefix "http://java.sun.com/jsf/composite/ezcomp" is added to the markup page. <ez:username-password> is the composite component used instead of those multiple components. The namespace prefix, "ez", and the tag name, "username-password", are chosen based upon the values entered in the wizard.

The JSF 2 specification, section 3.6.1.4 defines that:

The occurrence of the string “http://java.sun.com/jsf/composite/” in a Facelet XML namespace declaration means that whatever follows that last “/” is taken to be the name of a resource library.

The resource library location is relative to the Facelet markup file that is using it. So in our case, all the code is rightly encapsulated in the "resources/ezcomp/username-password.xhtml" file as:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:cc="http://java.sun.com/jsf/composite"
     xmlns:h="http://java.sun.com/jsf/html">

    <!-- INTERFACE -->
    <cc:interface>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
      <h:panelGrid columns="2">
        <h:outputText value="Name:"/>
        <h:inputText value="#{simplebean.name}" title="name"
                   id="name" required="true"/>
        <h:outputText value="Password:"/>
        <h:inputText value="#{simplebean.password}" title="password"
                   id="password" required="true"/>
      </h:panelGrid>
 </cc:implementation>
</html>

Notice, the composite component name matches the Facelet markup file name. The markup file lives in "resources/ezcomp" directory as indicated by the namespace value.

<cc:interface> defines metadata that describe the characteristics of component, such as supported attributes, facets, and attach points for event listeners. <cc:implementation> contains the markup substituted for the composite component.

The "index.xhtml" page is using the composite component and is conveniently called the using page. Similarly the "username-password.xhtml" page is defining the composite component and is conveniently called the defining page. In short, creating composite components in JSF2 requires the following steps:

  1. Move the required tags to a separate Facelet markup file, "defining page", in the "resources" directory
  2. Declare the namespace/prefix derived from "http://java.sun.com/jsf/composite" and the directory name
  3. Refer the composite component in the "using page".

Much simpler and cleaner than JSF 1.2. Are you using JSF 2 composite components ?

The entire source code used in this blog can be downloaded here.

JSF 2 implementation is bundled with GlassFish Server Open Source Edition, try it today!

Technorati: totd glassfish v3 netbeans jsf2 javaee composite components ajax

Monday May 10, 2010

TOTD #134: Interceptors 1.1 in Java EE 6 - What and How ?

TOTD #129 explained Managed Beans 1.0, this Tip Of The Day (TOTD) attempts to explain the basics of Interceptors 1.1 - a "new" specification introduced in the Java EE 6.

The specification is not entirely new as the concept is borrowed from the EJB 3.0 specification and abstracted at a higher level so that it can be more generically applied to a broader set of specifications in the platform. Interceptors do what they say - they intercept on invocations and lifecycle events on an associated target class. Basically, interceptor is a class whose methods are invoked when business methods on the target class are invoked and/or lifecycle events such as methods that create/destroy the bean occur. Interceptors are typically used to implement cross-cutting concerns like logging, auditing, and profiling.

Contexts and Dependency Injection (CDI, aka JSR 299) uses the concept defined by Interceptors 1.1 and adds the notion of interceptors binding.

Let see some code to make it all clear.

Each interceptor require at least one interceptor binding to associate with the target class. An interceptor binding is defined as:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyInterceptorBinding {
}

And then the interceptor is defined as:

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Interceptor
@MyInterceptorBinding
public class MyInterceptor {

    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        System.out.println("before interception");
        Object result = context.proceed();
        System.out.println("after interception");

        return result;
    }
}

The "@AroundInvoke" annotation (can be only one per interceptor) on a method in the interceptor class ensures that this method is invoked around the business method interception. This will be more clear after the program flow is explained later. Multiple interceptors can be chained and the flow/outcome may be diverted in any of them using "InvocationContext".

The associated target bean looks like:

. . .
import javax.interceptor.Interceptors;

@ManagedBean(value="mybean")
@Interceptors(MyInterceptor.class)
public class MyManagedBean {
    @PostConstruct
    public void setupResources() {
        // setup your resources
        System.out.println("Setting up resources ...");
    }

    . . .

}

The only missing part on the server-side is enabling bean discovery by adding an empty "beans.xml" as:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

Notice, there is no need to explicitly mention <interceptors> in "beans.xml". Multiple interceptors on a bean can be easily defined as:

@ManagedBean(value="mybean")
@Interceptors({MyInterceptor.class, MyInterceptor2.class})
public class MyManagedBean {

Lets see how this bean and interceptor can be used. Create a Servlet as:

@WebServlet(name="TestServlet", urlPatterns={"/TestServlet"})
public class TestServlet extends HttpServlet {

Inject a bean as ...

@Inject
MyManagedBean bean;

and then invoke the bean's method in "doGet" or "doPost" methods of the servlet as:

String result = bean.sayHello("Duke");

Notice that @Inject is used to inject the managed bean and bean discovery is enabled by adding an empty "beans.xml". This ensures that CDI inject works as expected and all the interceptors are invoked as well. Another alternative is to inject the bean using @Resource but "beans.xml" need to be removed in order for the interceptors to be invoked. So inject your bean using @Inject + "beans.xml" or @Resource. The recommended approach is to use @Inject + "beans.xml" as CDI might be used in other parts of your applications as well.

If 2 interceptors, each with a separate interceptor binding, managed bean class, and the servlet is included in a web application then the directory structure will look like:

./META-INF
./META-INF/MANIFEST.MF
./WEB-INF
./WEB-INF/beans.xml
./WEB-INF/classes
./WEB-INF/classes/server
./WEB-INF/classes/server/MyInterceptor.class
./WEB-INF/classes/server/MyInterceptor2.class
./WEB-INF/classes/server/MyInterceptorBinding.class
./WEB-INF/classes/server/MyInterceptorBinding2.class
./WEB-INF/classes/server/MyManagedBean.class
./WEB-INF/classes/server/TestServlet.class

If there are "System.out.println"s inserted at relevant positions in the interceptor and the Servlet code, then the code flow looks like:

Before Intercept
Before Intercept2
sayHello
After Intercept2
After Intercept
processRequest

"Before XXX" messages are printed by a method from the interceptors, in the order of chaining, before "context.proceed" is invoked in all the interceptors. "sayHello" method is invoked from the "doGet" or "doPost" method in the Servlet. "After XXX" messages are printed from the interceptors after "context.proceed" method is invoked, this time in the reverse order of chain. And finally "processRequest" method is invoked again from the "doGet" or "doPost" method in the Servlet.

The complete source code for the sample explained above can be downloaded here.

Technorati: javaee glassfish v3 managedbeans interceptors cdi ejb servlet

Wednesday May 05, 2010

TOTD #133: JPA2 (JPQL & Criteria), JavaDB, and embedded GlassFish - perfect recipe for testing

TOTD #132 explained how to use embedded GlassFish for deploying/testing a simple Servlet. As mentioned in that blog, this Tip Of The Day (TOTD) will extend that entry and show how to create a simple test that:

  • Creates a JDBC Connection Pool using GlassFish APIs
  • Creates a JDBC Resource using that Connection Pool, again programmatically
  • Persists and Queries an entity in that database using JPQL and the newly introduced Criteria APIs in JPA 2

This application uses a "Games" entity with two simple fields - "id" for the primary key and "name" for the name of a game. The test persists 3 entries in the database and then retrieves them by issuing a JPQL statement and Criteria API. There are four tests:

  • The first test consists of creating a JDBC Connection Pool & a JDBC Resource using that pool in the embedded GlassFish instance
  • The second test stores 3 entities in the database using the JDBC resource
  • The third test queries the database using JPQL
  • The fourth test queries the database using Criteria API

The entire source code is available here and "mvn test" is all you need to see the action. The updated directory structure from TOTD #132 is:

src
src/main
src/main/java
src/main/java/org
src/main/java/org/glassfish
src/main/java/org/glassfish/embedded
src/main/java/org/glassfish/embedded/samples
src/main/java/org/glassfish/embedded/samples/App.java
src/main/java/org/glassfish/embedded/samples/Games.java
src/main/resources
src/main/resources/META-INF
src/main/resources/META-INF/persistence.xml
src/test
src/test/java
src/test/java/org
src/test/java/org/glassfish
src/test/java/org/glassfish/embedded
src/test/java/org/glassfish/embedded/samples
src/test/java/org/glassfish/embedded/samples/AppTest.java

The newly added files are highlighted in the bold. "Games.java" is the new entity class and "persistence.xml" provides the definition of Persistence Unit.

Here is our simple entity class:

package org.glassfish.embedded.samples;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/\*\*
 \* @author arungupta
 \*/
@Entity
@Table
public class Games implements Serializable {
    @Id
    int id;

    @Column
    String name;

    public Games() { }

    public Games(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Adding "@Entity" and "@Table" annotation on this POJO makes it an JPA Entity Bean. In addition, the primary key is defined using the "@Id" annotation on the field and an additional column is marked using "@Column"annotation.

In "AppTest.java", add a new method to create and test for JDBC connection pool and a JDBC resource using that pool as shown below:

public void testJDBCPoolAndResource() throws Throwable {
    Server.Builder builder = new Server.Builder("server");
    server = builder.build();
    server.createPort(8080);

    // add the required containers
    server.addContainer(ContainerBuilder.Type.web);
    server.addContainer(ContainerBuilder.Type.jpa);

    // Create a JDBC connection pool
    ParameterMap params = new ParameterMap();
    params.add("datasourceclassname", "org.apache.derby.jdbc.EmbeddedDataSource");
    params.add("property",
       "databaseName=games:connectionAttributes=\\\\;create\\\\=true");
    params.add("jdbc_connection_pool_id", JDBC_POOL);
    executeCommand("create-jdbc-connection-pool", server, params);
    System.out.println("JDBC Connection Pool successfully created.");

    // Assert the JDBC connection pool
    List<MessagePart> messageParts = 
        executeCommand("list-jdbc-connection-pools", server);
    assertInArray(messageParts, JDBC_POOL);

    // Create a JDBC resource
    System.out.println("Creating JDBC resource ...");
    ParameterMap params2 = new ParameterMap();
    params2.add("connectionpoolid", "MyPool");
    params2.add("jndi_name", JDBC_RESOURCE);
    executeCommand("create-jdbc-resource", server, params2);

    // Assert the JDBC resource
    messageParts = executeCommand("list-jdbc-resources", server);
    assertInArray(messageParts, JDBC_RESOURCE);
}

A disk representation of the database is created in the current directory by using "databaseName=games". Using in-memory JavaDB would've avoided the directory creation but facing issues with that (more on this at the end).

Here are convenience methods to execute an "asadmin"-equivalent command and used in the method above ...

private List executeCommand(String command, Server server) throws Throwable {
    return executeCommand(command, server, null);
}

private List executeCommand(String command, Server server, ParameterMap params) 
    throws Throwable {
    CommandRunner runner = server.getHabitat().getComponent(CommandRunner.class);
    ActionReport report = server.getHabitat().getComponent(ActionReport.class);
    if (params == null)
        runner.getCommandInvocation(command, report).execute();
    else
        runner.getCommandInvocation(command, report).parameters(params).execute();
    if (report.hasFailures()) {
        report.writeReport(System.out);
        throw report.getFailureCause();
    }

    return report.getTopMessagePart().getChildren();
}   

The error messages are shown on the console. Add another method for asserting on the created JDBC connection pool and resource as:

private void assertInArray(List messageParts, String resource) throws Throwable {
    boolean found = false;

    for (MessagePart part : messageParts) {
        if (part.getMessage().equals(resource)) {
            found = true;
            break;
        }
        System.out.println(part.getMessage());
    }

    if (!found)
        throw new Throwable("\\"" + resource + "\\" resource not found");
}

Here is a method to insert new values in the database using standard JPA calls:

public void testInsert() throws Throwable {
    EntityManagerFactory emf = 
        Persistence.createEntityManagerFactory("webtier2-PU");
    EntityManager em = emf.createEntityManager();

    // list of games to be added
    String[] games = {
               "Super Mario Galaxy",
               "Super Mario Brothers",
               "Mario Kart" };

    // create a transaction
    EntityTransaction utx = em.getTransaction();
    System.out.println("Persisting " + games.length + " games ...");
    utx.begin();
    for (int i=0; i<games.length; i++) {
        em.persist(new Games(i, games[i]));
        System.out.println("\\t " + games[i]);
    }
    utx.commit(); // and commit
    System.out.println("Committed.");
}

The method to query the database using JPQL ...

public void testJPQL() throws Throwable {
    EntityManagerFactory emf = 
        Persistence.createEntityManagerFactory("webtier2-PU");
    EntityManager em = emf.createEntityManager();

    // now query them
    List list = em.createQuery("select g from Games g").getResultList();
    assertEquals("Games retrieved", 3, list.size());
    System.out.println("Found " + list.size() + " games (using JPQL) ...");
    for (Object o : list) { // and dump
        System.out.println("\\t" + ((Games)o).getName());
    }
}

And finally a method to query the database using JPA 2 Critieria API ...

public void testCriteria() throws Throwable {
    EntityManagerFactory emf = 
        Persistence.createEntityManagerFactory("webtier2-PU");
    EntityManager em = emf.createEntityManager();

    CriteriaBuilder cb = emf.getCriteriaBuilder();
    CriteriaQuery<Games> criteria = cb.createQuery(Games.class);

    // FROM clause
    Root<Games> games = criteria.from(Games.class);

    // SELECT clause
    criteria.select(games);

    // No WHERE clause - pick all

    // FIRE
    List<Games> list = em.createQuery(criteria).getResultList();
    assertEquals("Games retrieved", 3, list.size());
    System.out.println("Found " + list.size() + " games (using Criteria) ...");
    for (Object o : list) { // and dump
       System.out.println("\\t" + ((Games)o).getName());
    }
 }

And here is the "persistence.xml"

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="webtier2-PU" transaction-type="JTA">
       <jta-data-source>jdbc/MyResource</jta-data-source>
       <properties>
           <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
       </properties>
       <class>org.glassfish.embedded.samples.Games</class>
   </persistence-unit>
</persistence>

The Persistence Unit is referring to "jdbc/MyResource" JDBC Resource created earlier. The table creation strategy is "drop-and-create-tables" and this can be "create-tables" if in-memory JavaDB is used instead.

The version of "glassfish-embedded-all" dependency in "pom.xml" is changed from "3.0" to "3.1-SNAPSHOT" so that latest updates are picked. The updated dependency looks like:

<dependency>
   <groupId>org.glassfish.extras</groupId>
   <artifactId>glassfish-embedded-all</artifactId>
   <version>3.1-SNAPSHOT</version>
</dependency>

Change the source version of "maven-compiler-plugin" from "1.5" to "1.6", the updated entry looks like:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
       <source>1.6</source>
       <target>1.6</target>
    </configuration>
</plugin>


And now when you fire "mvn clean test", a test output is shown as ...

INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
[EL Info]: 2010-05-05 13:49:28.339--ServerSession(149074043)--file:/Users/arungupta/samples/v3/
embedded/webtier2/target/classes/_webtier2-PU login successful
Persisting 3 games ...
         Super Mario Galaxy
         Super Mario Brothers
         Mario Kart
Committed.
Found 3 games (using JPQL) ...
        Mario Kart
        Super Mario Galaxy
        Super Mario Brothers
Found 3 games (using Criteria) ...
        Mario Kart
        Super Mario Galaxy
        Super Mario Brothers

You may see the following exception during the test run:

May 5, 2010 1:49:24 PM com.sun.logging.LogDomains$1 log
SEVERE: loader.asurlclassloader_malformed_url
java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.(ZipFile.java:114)
        at java.util.jar.JarFile.(JarFile.java:133)
        at java.util.jar.JarFile.(JarFile.java:97)

This occurs because no URL is specified in the connection properties. This error message can be ignored as sufficient information is available to resolve the database otherwise.

Using the in-memory JavaDB is causing some sort of race condition in the test path and throwing an exception at random runs. After trying the configuration on couple of Macs, Windows 7 and Ubuntu and still not able to detect the cause of randomness, no formal issue is logged yet but its still being followed with the required folks.

In the meanwhile, enjoy the power of embedded GlassFish with JPA and Java DB.

Technorati: totd glassfish v3 javaee embedded servlet jpa persistence javadb

Friday Apr 30, 2010

TOTD #132: Servlets 3.0 in Embedded GlassFish Reloaded - lightweight Java EE 6

This Tip Of The Day (TOTD) is a refresh of Embeddable GlassFish in Action - Servlet in a Maven Project.

GlassFish v3 runs easily in embedded mode - no download, installation, or configuration - every thing done programmatically within a JVM. This blog shows how to deploy a simple Servlet using these APIs and then write a simple test to invoke it - all within the same VM.

Lets get started!

  1. Lets create our Maven project:
    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \\
    -DgroupId=org.glassfish.embedded.samples -DartifactId=webtier2
    
  2. Add the following <repository>, <dependency>, and <plugin> to the generated "pom.xml:
    <repositories>
      <repository>
        <id>glassfish-repository</id>
        <name>Java.net Repository for Glassfish</name>
        <url>http://download.java.net/maven/glassfish</url>
      </repository>
    </repositories>
    . . .
    <dependencies>
      . . .
      <dependency>
        <groupId>org.glassfish.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>3.0</version>
      </dependency>
    </dependencies>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.0.2</version>
          <configuration>
            <source>1.5</source>
            <target>1.5</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    

    Read Setting the Class Path for more discussions on the different JAR files that are available. The version may be changed form "3.0" to "3.1-SNAPSHOT" to pick the latest bug fixes and improvements.
  3. Change the generated "src/main/java/org/glassfish/embedded/samples/App.java" to:
    package org.glassfish.embedded.samples;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /\*\*
     \* Hello world!
     \*/
    @WebServlet(name="app", urlPatterns={"/app"})
    public class App extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response)
                throws ServletException, IOException {
            response.getWriter().println("Hello Duke");
        }
    }
    
    This is using "@WebServlet" annotation, a new feature in Servlets 3.0, to mark a POJO as a Servlet. Notice the servlet is hosted at "/app" URL. No "web.xml" will be required in this case.
  4. Edit the generated "src/test/java/org/glassfish/embedded/samples/AppTest.java" and add the following method:
    public void testServlet() throws IOException, LifecycleException {
        // Build a server
        Server.Builder builder = new Server.Builder("server");
        Server server = builder.build();
    
        // Specify the port
        server.createPort(8080);
    
        // Add the Web container
        server.addContainer(ContainerBuilder.Type.web);
    
        // Create the WAR file
        ScatteredArchive.Builder saBuilder = new ScatteredArchive.Builder("test",
                Collections.singleton(new File("target/classes").toURI().toURL()));
        ScatteredArchive archive = saBuilder.buildWar();
    
        // Deploy the WAR file
        EmbeddedDeployer deployer = server.getDeployer();
        deployer.deploy(archive, null);
    
        // Read the response from the servlet hosted at "/app"
        URL url = new URL("http://localhost:8080/test/app");
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                url.openConnection().getInputStream()));
    
        // ... and assert
        assertEquals("Hello Duke", br.readLine());
    }
    
    This method is well commented and where all the magic is happening.

    The updated import statements look like:
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.util.Collections;
    import junit.framework.Test;
    import junit.framework.TestCase;
    import junit.framework.TestSuite;
    import org.glassfish.api.deployment.DeployCommandParameters;
    import org.glassfish.api.embedded.ContainerBuilder;
    import org.glassfish.api.embedded.EmbeddedDeployer;
    import org.glassfish.api.embedded.LifecycleException;
    import org.glassfish.api.embedded.ScatteredArchive;
    import org.glassfish.api.embedded.Server;
    

  5. And now fire the following command:
    mvn test
    

    and see the output as:

    Running org.glassfish.embedded.samples.AppTest
    Apr 30, 2010 10:49:55 AM com.sun.enterprise.v3.server.AppServerStartup run
    INFO: GlassFish v3 (74.2) startup time : Embedded(498ms) startup services(433ms) total(931ms)
    Apr 30, 2010 10:49:55 AM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
    INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
    Apr 30, 2010 10:49:55 AM org.glassfish.admin.mbeanserver.JMXStartupService$JMXConnectorsStarterThread run
    INFO: JMXStartupService: JMXConnector system is disabled, skipping.
    Apr 30, 2010 10:49:55 AM AppServerStartup run
    INFO: [Thread[GlassFish Kernel Main Thread,5,main]] started
    Apr 30, 2010 10:49:55 AM org.hibernate.validator.util.Version INFO: Hibernate Validator null
    Apr 30, 2010 10:49:55 AM org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
    INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
    Apr 30, 2010 10:49:56 AM com.sun.enterprise.v3.services.impl.GrizzlyProxy$2$1 onReady
    INFO: Grizzly Framework 1.9.18-k started in: 154ms listening on port 8080
    Apr 30, 2010 10:50:00 AM com.sun.common.util.logging.LoggingConfigImpl openPropFile
    INFO: Cannot read logging.properties file. 
    Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer createHttpListener
    INFO: Created HTTP listener embedded-listener on port 8080
    Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer configureHttpServiceProperties
    WARNING: pewebcontainer.invalid_http_service_property
    Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer createHosts
    INFO: Created virtual server server
    Apr 30, 2010 10:50:00 AM com.sun.enterprise.web.WebContainer loadSystemDefaultWebModules
    INFO: Virtual server server loaded system default web module
    Apr 30, 2010 10:50:02 AM com.sun.enterprise.security.SecurityLifecycle INFO: security.secmgroff
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.ssl.SSLUtils checkCertificateDates
    SEVERE: java_security.expired_certificate
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.SecurityLifecycle onInitialization
    INFO: Security startup service called
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.PolicyLoader loadPolicy
    INFO: policy.loading
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm admin-realm of classtype com.sun.enterprise.security.auth.realm.file.FileRealm successfully created.
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm file of classtype com.sun.enterprise.security.auth.realm.file.FileRealm successfully created.
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm certificate of classtype com.sun.enterprise.security.auth.realm.certificate.CertificateRealm successfully created.
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.security.SecurityLifecycle onInitialization
    INFO: Security service(s) started successfully....
    classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
    SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@71e13a2c
    Apr 30, 2010 10:50:03 AM com.sun.enterprise.web.WebApplication start
    INFO: Loading application test at /test
    Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 9.845 sec
    
    Results :
    
    Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    

    The key messages in the log are highlighted in bold.

    As you can see embedded GlassFish started in less than a second ... neat! It also shows a message that HTTP listener is starting on port 8080. And finally the 2 tests passed - one is the default one generated by Maven and other is the new one that we added!

A future blog will show how to create JDBC resource using these APIs and use the JPA 2 APIs to query an in-memory database.

Alternatively, you can also use the Maven plug-in or EJB 3.1 Embeddable API. Always refer to the GlassFish v3 Embedded Server Guide for the definitive documentation. The latest javadocs are available here.

How are you using embeddable GlassFish ?

Technorati: totd glassfish v3 javaee embedded servlet

About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today