Skip to main content

Quick introduction to Embeddability of GlassFish Open Source Edition 3.1

Posted by bhavanishankar on March 2, 2011 at 2:39 PM PST

Embeddability of GlassFish is been around for quite some time now. In 3.1, the embeddable APIs have been revised. Most of the GlassFish community is already aware of the API revision, however I would like to briefly describe the revised APIs in this blog and welcome any feedback.

Embeddable API overview:

API JavaDocs are at http://embedded-glassfish.java.net/nonav/apidocs/

The APIs are briefly categorized as :

(a) Top level APIs (org.glassfish.embeddable) : Provides classes and interfaces necessary to embed GlassFish and perform lifecycle operations, application deployments and runtime configurations

(b) Scattered Archive APIs (org.glassfish.embeddable.archive) : Abstraction for a scattered Java EE archive (parts disseminated in various directories).

(c) Web Container APIs  (org.glassfish.embebdable.web, org.glassfish.embeddable.web.config) : Provides classes and interfaces necessary to programmatically configure embedded WebContainer and create contexts, virtual servers, and web listeners.

(d) Advanced pluggability (org.glassfish.embeddable.spi) : Provides classes and interfaces necessary to plugin a custom GlassFish runtime.

(e) EJB container APIs (javax.ejb.embeddable) : Refer "Embedded Server Guide" for EJB embeddable APIs

Basic examples of embedding GlassFish and deploying applications to embedded GlassFish:

These examples are can be run with either of the following jars in your CLASSPATH:

Full profile uber jar : http://download.java.net/maven/glassfish/org/glassfish/extras/glassfish-embedded-all/3.1/glassfish-embedded-all-3.1.jar
Web profile uber jar: http://download.java.net/maven/glassfish/org/glassfish/extras/glassfish-embedded-web/3.1/glassfish-embedded-web-3.1.jar
Installed GlassFish's shell jar : $GF_INSTALLATION/lib/embedded/glassfish-embedded-static-shell.jar

Once you have ANY ONE of the above jar file with you, GlassFish can be embedded in your application by simply doing:

import org.glassfish.embeddable.*;

/** Create and start GlassFish */
GlassFish glassfish = GlassFishRuntime.bootstrap().newGlassFish();
glassfish.start();

Let us say that you would like 8080 web container port to be started while embedding GlassFish, then you have to do this:

import org.glassfish.embeddable.*;

/** Create and start GlassFish which listens at 8080 http port */
GlassFishProperties gfProps = new GlassFishProperties();
gfProps.setPort("http-listener", 8080); // refer JavaDocs for the details of this API.

GlassFish glassfish = GlassFishRuntime.bootstrap().newGlassFish(gfProps);
glassfish.start();

Or let us say that you have 3.1 installation and want to embed GlassFish domain1 in your application, then you can do:

import org.glassfish.embeddable.*;

/** Bootstrap the GlassFish runtime pointing to 3.1 installation */
BootstrapProperties bsProps = new BootstrapProperties();
bsProps.setInstallRoot(System.getEnv("GF_INSTALLATION"));
GlassFishRuntime gfRuntime = GlassFishRuntime.bootstrap(bsProps);

/** Point GlassFish to domain1 */
GlassFishProperties gfProps = new GlassFishProperties();
gfProps.setInstanceRoot(System.getEnv("GF_INSTALLATION") + "/domains/domain1");
GlassFish glassfish = gfRuntime.newGlassFish(gfProps);

glassfish.start();

Note: If you have a custom domain.xml while embedding GlassFish, then you can use setConfigFileURI(String configFile) API of GlassFishProperties. JavaDoc has all the details.

Once you have the GlassFish embedded and is running, you may like to deploy a pre-built Java EE archive using the code below:

import org.glassfish.embeddable.*;

// Obtain the deployer from the glassfish which is embedded via the piece of code above.
Deployer deployer = glassfish.getDeployer();

// syntax of deployment params are same as how they are passed to 'asadmin deploy' command.
deployer.deploy(new File("simple.war"), "--contextroot=test", "--name=test", "--force=true");

// if you have no deployment params to pass, then simply do this:
deployer.deploy(new File("simple.war"));

If your archive is not pre-built, instead it's components are scattered in multiple directories, then you may be interested in using the scattered archive APIs:

import org.glassfish.embeddable.*;
import org.glassfish.embeddable.archive.*;

Deployer deployer = glassfish.getDeployer();

// Create a scattered web application.
ScatteredArchive archive = new ScatteredArchive("testapp", ScatteredArchive.Type.WAR);
// target/classes directory contains my complied servlets
archive.addClassPath(new File("target", "classes"));
// resources/sun-web.xml is my WEB-INF/sun-web.xml
archive.addMetadata(new File("resources", "sun-web.xml"));
// resources/MyLogFactory is my META-INF/services/org.apache.commons.logging.LogFactory
archive.addMetadata(new File("resources", "MyLogFactory"), "META-INF/services/org.apache.commons.logging.LogFactory");

deployer.deploy(archive.toURI())

Similarly, the scattered enterprise application (EAR type) can be deployed like this:

import org.glassfish.embeddable.*;
import org.glassfish.embeddable.archive.*;

Deployer deployer = glassfish.getDeployer();

// Create a scattered web application.
ScatteredArchive webmodule = new ScatteredArchive("testweb", ScatteredArchive.Type.WAR);
// target/classes directory contains my complied servlets
webmodule.addClassPath(new File("target", "classes"));
// resources/sun-web.xml is my WEB-INF/sun-web.xml
webmodule.addMetadata(new File("resources", "sun-web.xml"));

// Create a scattered enterprise archive.
ScatteredEnterpriseArchive archive = new ScatteredEnterpriseArchive("testapp");
// src/application.xml is my META-INF/application.xml
archive.addMetadata(new File("src", "application.xml"));
// Add scattered web module to the scattered enterprise archive.
// src/application.xml references Web module as "scattered.war". Hence specify the name while adding the archive.
archive.addArchive(webmodule.toURI(), "scattered.war");
// lib/mylibrary.jar is a library JAR file.
archive.addArchive(new File("lib", "mylibrary.jar"));
// target/ejbclasses contain my compiled EJB module.
// src/application.xml references EJB module as "ejb.jar". Hence specify the name while adding the archive.
archive.addArchive(new File("target", "ejbclasses"), "ejb.jar");

deployer.deploy(archive.toURI())

Finally, towards the end of your application, you would like to stop/dispose your embedded GlassFish:

import org.glassfish.embeddable.*;

/** Stop GlassFish */
glassfish.stop(); // you can start it again.

/** Dispose GlassFish */
glassfish.dispose(); // you can not start it again. But you can embed a fresh glassfish with GlassFishRuntime.bootstrap().newGlassFish()

More Examples:

If you checkout https://svn.java.net/svn/glassfish~svn/trunk/v3/tests/embedded you will find many more examples which cover embeddable web container APIs also.

Feedback:

If you have any feebback on the APIs, please send them to dev@glassfish.java.net or dev@embedded-glassfish.java.net