samedi janv. 16, 2010

Testing with the GlassFish Maven plugin and JavaDB Embedded

This blog has moved to alexismp.wordpress.com
Follow the link for the most up-to-date version of this blog entry.

Having GlassFish v3 usable in embedded mode made it easy to create a maven plugin with multiple goals (see this previous entry). This in turn makes it easy to configure the plugin for maven-driven unit testing. Here's an example :

<plugin>
    <groupId>org.glassfish</groupId>
    <artifactId>maven-embedded-glassfish-plugin</artifactId>
    <version>3.0</version>
    <configuration>
       <goalPrefix>embedded-glassfish</goalPrefix>
       <app>${basedir}/target/myapp.ear</app>
       <autoDelete>true</autoDelete>
       <port>8080</port>

    </configuration>

    <executions>
       <execution>
          <id>start-glassfish</id>
          <phase>pre-integration-test</phase>
          <goals>
             <goal>start</goal>
          </goals>
       </execution>
       <execution>
          <id>glassfish-deploy</id>
          <phase>pre-integration-test</phase>
          <goals>
             <goal>deploy</goal>
          </goals>
       </execution>
       <execution>
          <id>glassfish-undeploy</id>
          <phase>post-integration-test</phase>
          <goals>
             <goal>undeploy</goal>
          </goals>
       </execution>
       <execution>
          <id>stop-glassfish</id>
          <phase>post-integration-test</phase>
          <goals>
             <goal>stop</goal>
          </goals>
       </execution>
    </executions>
</plugin>

Now it's certainly nice to be able to automate tests right from a single pom.xml and not have to deal with starting, deploying, stopping the app server. It's even better when the runtime starts fast and uses only the required memory (as it is the case with GlassFish v3), but what about running tests involving a database? If a database server needs to be started using external tools (or worse, manually) it's a bit back to square "one".

This is where JavaDB embedded can come in handy. The trick with an application server like GlassFish is that it's not enough to use the embedded driver (org.apache.derby.jdbc.EmbeddedDriver), you also need to reference an embedded JTA datasource. GlassFish v3 ships with one such datasource pre-configured: jdbc/__TimerPool so lazy as I am, I simply reused this in by setup - using the following JPA persistence-unit enables my test to fire up an embedded (in-process) instance of JavaDB (no separate startup, no port used). As the names implies, this pool isn't really a general purpose one (it's used for by the Timer Service) so this is a bit of a hack. A handy one, but a hack.

<persistence-unit name="tempdb">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/__TimerPool</jta-data-source>
    <properties>
       <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
       <property name="eclipselink.target-database" value="DERBY"/>
       <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
</persistence-unit>

You see here that I use the drop-and-create-tables ddl generation strategy (create-tables would work too) and consider the database to be volatile. The next step would be to run all of this in-memory and no longer write files to disk (which shouldn't be that hard).

vendredi déc. 18, 2009

GlassFish v3 Documentation - Embedded Guide

This blog has moved to alexismp.wordpress.com
Follow the link for the most up-to-date version of this blog entry.

As a follow-up to my previous GlassFish Embedded blog posts I wanted to point out that since we shipped GlassFish v3, we now have lots of documentation available, including a formal "Embedded Server Guide" document (19 pages).

To extend what's covered in this Aquarium entry, note that you can install the entire GlassFish v3 documentation straight from your v3 install using the update center. This will place the HTML version of the docs in glassfish/docs/manuals/. You can use bin/updatetool or simply type bin/pkg install glassfish-docs.

In any case you can get the complete GlassFish v3 documentation set (for a total of 24 books).

lundi nov. 23, 2009

GlassFish Embedded Reloaded, an appserver in your pocket

It wasn't enough for GlassFish v3 to be broken into 200+ OSGi bundles executable on different OSGi implementations such as Felix or Equinox (or even without OSGi, i.e. in "Static" mode), we also had to make it embeddable (in-process, using an API).

In a previous entry, I discussed EJBContainer.createEJBContainer() (a standard EJB 3.1 API) which is really a specific use-case of the more generic case of using the GlassFish Embedded API. The latter is the topic of this newer post and whichever you decide to use, you should remember that this is all one code-base offering different facets with as many entry points.

Definition

GlassFish embedded is in-process integration of the GlassFish v3 features (not just the web container) using an API to start/stop/configure the server and its containers and to deploy/undeploy applications.

While this definition and the use-cases (testing, shipping shrink-wrapped apps, ...) has not changed since GlassFish v3 Prelude which shipped a year ago, the API has substantially evolved (up to promoted build 65 in late September I believe) as you can read below and can now be considered stable. As you'll see later in this post, the deployment can be trivial.

An overview of the API

Main classes are :
    org.glassfish.api.embedded.Server
    org.glassfish.api.embedded.EmbeddedFileSystem
    org.glassfish.api.embedded.ContainerBuilder
    org.glassfish.api.embedded.EmbeddedDeployer
    org.glassfish.api.deployment.DeployCommandParameters

Update: you'll find the entire API for Java EE 6 and GlassFish v3 here.
Update 2: make sure you read the formal "Embedded Server Guide" documentation now available for GlassFish v3

The API offer a flexible inner-class Builder pattern :
     EmbeddedFileSystem.Builder efsb = new EmbeddedFileSystem.Builder();
     efsb.installRoot(EmbeddedServerUtils.getServerLocation());

Simple Hello world

Let me walk you through a simple example which deploys an existing WAR from a main() which in turn would let you ship and start the entire app using a JAR (full source here). I'll leave it as a simple exercise to the reader to adapt it to the testing use-case.

First the logic :
     foo.Embedded myGlassFish = new foo.Embedded("myArchive.war"); // init with the archive name
     myGlassFish.start();
     boolean deployed = myGlassFish.deploy();
     if (deployed) {
         // TODO: do something  useful  like wait for a shutdown order
        
     }
     myGlassFish.undeployAndStop(); // stops and exits the JVM

The startup process :
     public void start() throws IOException {
         Server.Builder builder = new Server.Builder("testBuilder");
        
         // get the builder for EmbeddedFileSystem
         EmbeddedFileSystem.Builder efsb = new EmbeddedFileSystem.Builder();
         EmbeddedFileSystem efs = efsb.build();
         builder.embeddedFileSystem(efs);
    
         // Start the embedded server (should take no more than a few of seconds)
         server = builder.build();
    
         // Add a WEB container (other containers include ejb, jpa, all, ...)
         ContainerBuilder containerBuilder = server.createConfig(ContainerBuilder.Type.web);
         server.addContainer(containerBuilder);
         containerBuilder.create(server);
         server.createPort(port); // Starts grizzly on the given port
     }

The deployment :
     public boolean deploy() {
         // Setup machinery to deploy
         deployer = server.getDeployer(); // type is EmbeddedDeployer
         DeployCommandParameters deployParams = new DeployCommandParameters();
         deployParams.name = "myApplication"; // needed for undeploy
         deployParams.contextroot = context; // overrides whatever the WAR contains
        
         // Creates default virtual server, web listener, does the deploy and
         // returns the applicationName as a String (null means something went wrong)
         // duration depends on application size and nature. Heavy lifting done here.
         File archive = new File(archiveName);
         applicationName = deployer.deploy(archive, deployParams);
         return (applicationName == null) ? false : true;
     }

... and the cleaning up :
     public void undeployAndStop() throws LifecycleException {
         deployer.undeploy(applicationName, null); // Could have undeploy params like cascade, ...
         server.stop(); // May take a little while to clean everything up
         System.exit(0); // to kill any threads left running
     }

The above example is only scratching the surface. You can deploy exploded archives (check out the org.glassfish.api.embedded.ScatteredArchive API) or reuse an existing domain.xml configuration file for instance. I'd like to encourage you to look around the various Embedded tests to find out more about the richness of the API.

As little as one JAR

There are two modes for running GlassFish Embedded :

implanted: this uses an existing GlassFish installation and requires having glassfish/lib/embedded/glassfish-embedded-static-shell.jar in your classpath. The JAR itself is an empty shell with relative references to all the JARs in the GlassFish v3 distribution. This is approach taken by NetBeans project tests for example.

autonomous: for easier distribution an all-in-one JAR file is available in two flavors: full profile (40 MB) and web profile (30 MB). Not bad for a full-blown app server! The complete application+runtime bundle can then be deployed using Maven, an installer (such as IzPack), a jar file (eventually wrapped in an .exe) or even via Java Web Start.

Still early days

Whether you're using the implanted or autonomous mode (using the uber-jar), you'll be running the same code, simply using different entry paths. Because of the different packaging and the temporary filesystem layout the autonomous mode uses, differences are always possible. Many issues were fixed in the past couple of months thanks, including some by users themselves.

Note that there is no OSGi involved in the embedded mode (I don't think this is a limitation, but it's certainly an important data point). It is much like running in static mode (same classloader hierarchy). There are also some limitations such as TimerEJB not being supported for the time being. But other than that, a non-trivial application like Hudson deploys to GlassFish embedded like a charm.

If this sounds interesting to you, please use a recent promoted build (b73 and above) or wait (a few weeks) for the GlassFish v3 final release in December (2009) and certainly ask questions on the USERS mailing list (or forum), and share your experience via blogs, tweets, etc...

lundi oct. 05, 2009

Using the EJBContainer API with or without Maven (but with GlassFish v3)

This blog has moved to alexismp.wordpress.com
Follow the link for the most up-to-date version of this blog entry.

This blog is still pretty accurate but do note that GlassFish v3 and NetBeans 6.8 have been released in final version

The typical way to start GlassFish is to use $asadmin start-domain but you could also start it using java -jar modules/glassfish.jar. Both start a standalone instance of GlassFish. The following paragraphs discuss GlassFish Embedded (i.e. start it using an API).

There are at least two ways to start GlassFish in embedded mode: using org.glassfish.api.embedded.Server and associated classes but also using the (now standard in EJB 3.1) EJBContainer.createEJBContainer() API. Let me describe here the latter one and reserve the more general embedded case for a later blog entry.

The goal is to write something like as simple as this to test your EJB :

    EJBContainer c = EJBContainer.createEJBContainer(); // new in EJB 3.1!
    Context ic = c.getContext();
    SimpleEjb ejb = (SimpleEjb) ic.lookup("java:global/sample/SimpleEjb");
    ejb.sayHello();

EJB's found in the classpath of the running code above will automatically be deployed and made available via lookups.

Calls to EJBContainer.createEJBContainer() are likely to be made from your tests. If you're making those calls by constructing yourself the execution classpath, then you simply need to add glassfish/lib/embedded/glassfish-embedded-static-shell.jar, an empty jar with a Class-Path: listing the required jars and that is part of the GlassFish distro. In fact, if you're using recent builds of NetBeans 6.8 (and the soon-to-be-released beta), the IDE does this for you when GlassFish is the target server. If you are using Maven, it's a bit trickier.

To use EJBContainer.createEJBContainer() from Maven tests, you'll need to add the following dependency to your POM (updated to final version of GlassFish v3):

     <groupId>org.glassfish.extras</groupId>
     <artifactId>glassfish-embedded-all</artifactId>
     <version>3.0</version>
     <scope>test</scope>

You could restrict this to a smaller set of GlassFish artifacts but for non-trivial tests (if you use JPA for instance), you would start to have a fairly long list of dependencies so the above sounds like a reasonable thing to do. This will require Maven to download the GlassFish All-in-one JAR file (40MB or so). The reason I wrote it would be trickier with maven is that you need to pass a property during the createEJBContainer() call indicating the location of a GlassFish v3 install. The above Java code would need to read something like this:

     Map p = new HashMap();
     p.put ("org.glassfish.ejb.embedded.glassfish.installation.root",
           "/path/to/glassfish"); // include trailing "/glassfish"
     ec = EJBContainer.createEJBContainer(p);

As of build 69 (maybe 70?), this is no longer needed - i.e. you can simply have glassfish-embedded-all.jar as a dependency or simply in your classpath. A full install of GlassFish is no longer required (although it may be interesting if you want to use JDBC configurations). Read this blog by Thomas for another interesting approach: Nice follow-up blog here: http://ctpjava.blogspot.com/2009/10/unit-testing-ejbs-and-jpa-with.html

Starting the appserver this way (with or without Maven) exercises the actual GlassFish code, not another implementation or a customized fork. There are some limitations to what you can run and in particular port configuration is ignored (not listening on any) and only local EJB interfaces are available (the spec only requires EJB 3.1 lite support). On the other hand, JPA calls are very much possible.

This should all work with v3 promoted build 66 (I just tested this with promoted build 70, see above simplification). Adam Bien beat me to covering that topic, but I hope you get some additional info here. In my case the start-up, setup, deploy and shutdown of GlassFish Embedded are worth about 6 seconds. Note that there is no OSGi involved here.

For a complete working example with JPA calls, check out this sample code.
The EJB 3.1 specification has a chapter (#22) on "Embeddable Usage". Check it out for further details about EJBContainer.

Update: some people are facing classpath/maven issues that causes the test to fail to find any EJB to test. The above is meant to run with an existing install of GlassFish (sorry this wan't clear) and this great thread has more data on what the issues can be. Marina describes the expected behavior and Laird goes into details about the use of maven-surefire-plugin and its <forkMode> configuration parameter. Make sure you read this if you have similar issues.

Update 2: per the EJB 3.1 specification EJBContainer is only required to support "EJB light" (no remote interfaces for instance).

jeudi janv. 29, 2009

GlassFish Embedded progress

Update: things have changed quite bit since I wrote this. Please check this link for up-to-date info on GlassFish Embedded.

Seen on the GlassFish forum, giving it a bit more spotlight here:

There are many ways to use GFE (Embedded GlassFish) Here is the easiest possible way to get you started:

Get http://download.java.net/glassfish/v3-prelude/embedded/nightly/latest.jar
$ java -jar latest.jar --help
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\*\*\*\*\* Welcome to Embedded GlassFish \*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Below are a list of valid options.
To use the longname, prepend it with '--'.
To use a short name prepend it with '-'.
The webapp war file names should be supplied after all the options.
You can enter as many web apps as you like.

Example to start an Embedded GlassFish Server with a web app packaged in a jar:

java -jar glassfish-embedded-all-3.0-Prelude-SNAPSHOT.jar myapp.war

Same example but listen at port 80 instead of the default 8888

java -jar glassfish-embedded-all-3.0-Prelude-SNAPSHOT.jar -p 80 myapp.war


Description Long Name Short Name Default Required

HTTP Port --port -p 8888 true
Filesystem Installation Directory --installDir -d false
Filesystem Instance Directory --instanceDir -i false
domain.xml filename or URL --xml -x false
Admin HTTP --adminport -q 4848 true
JMX System Connector Port --jmxport -j 8686 true
Help --help -h false true
Create the server and then exit. --create -c false true
Verbose Mode --verbose -v true true
Send logging to instance-root/logs/server.log --log -l true true
Automatically delete Filesystem --autodelete -a true true

Looking at the forum, blogs, and people already using it, there is a lot of interest for this new feature in GlassFish v3 (still in development) and I would encourage you to keep sending requirements and bug reports, ideally here but sharing them on the mailing list of forum also works.

vendredi oct. 03, 2008

Bundling GlassFish v3 Prelude - XWiki and the GlassFish Embedded (Part 2)

Update: things have changed quite bit since I wrote this for v3 Prelude (now v3 Final is the way to go).
Please check this link for up-to-date info on GlassFish Embedded.


In Part I, I covered a first technique to bundle the XWiki application with GlassFish v3 Prelude. The distribution and packaging discussed included a "traditional" auto-deployment of a web application (WAR) in a lightweight application server (GlassFish v3 Prelude).

GlassFish Embedded API

XWiki is a non-trivial application and I felt it would be a great test for the GlassFish Embedded API. This enables GlassFish to run in-process as explained in the rest of this entry. While the embedded API can be very useful for testing (it can now already be used with Maven and Grails for instance), the goal here is to produce a self-container Java SE application which contains GlassFish Embedded, the XWiki WAR archive and some glue code to start glassfish and deploy the application

Putting the pieces together

GlassFish Embedded does not use OSGi but rather a more traditional class-loader hierarchy so I had to work around a "classical" JAR precedence issue:
• removed the log4j jar from the XWiki application and make it available as a library (appropriate Class-Path: entry in the manifest of the overall JAR).
• used <class-loader delegate="false"/> in sun-web.xml to avoid further library conflicts (documented here)

Using the GlassFish Embedded API is pretty straightforward :



import org.glassfish.embed.App;
import org.glassfish.embed.AppServer;


public class XWikiOnGlassFish {
    public static void main(String[] args) throws IOException {

        AppServer glassfish = new AppServer(8080);
        App app = glassfish.deploy( new File("/path/to/xwiki-enterprise-web-1.5.2.war") );
    }
}

Results

The application weights 20 MB for the full GFv3 Prelude embedded (see other distributions here) + 4Ko "glue" application + 40MB XWiki.

The startup time is as follows:

with an additional 12 seconds to load the XWiki web app. The memory consumed (used heap as reported by VisualVM) is 15 MB right after the welcome page is displayed and 35 MB after exercising the application a bit.

I'll leave the packaging of this Java SE application (see what the OpenSSO guys did) using Java Web Start as an exercice to the reader.

More coverage of the GlassFish Embedded API (including the ScatteredWar API, and the Maven integration) can be found here. Note that a few API changes happened since that post.

About

This blog has moved

Alexis Moussine-Pouchkine's Weblog

GlassFish - Stay Connected

Search

Archives
« avril 2014
lun.mar.mer.jeu.ven.sam.dim.
 
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
Blogroll

No bookmarks in folder

News

No bookmarks in folder