Skip to main content

GlassFish v3 just got embeddable

Posted by kohsuke on April 28, 2008 at 2:34 PM PDT

Embeddable GFv3

I've always liked Jetty's ability to run inside an existing JVM, just as a library of another application. This enabled Jetty to be used in many situations, like mvn jetty:run for
debugging a webapp without even running an application server on its own. IMO this contributed
to a part of Jetty's usefulness. Almost every Maven documents today use Jetty for
web app development, or doing site:run, etc.

So naturally, we wanted to do the same for GlassFish v3, and I'm happy to report that
it got to the point that it holds the water. I mean, I can now run Hudson in this embedded GFv3.

Here's how it works — GlassFish v3 can be run as an OSGi appliation as Sahoo reported earlier, but in fact it can also be run without any kind of classloader isolation system at all. Sure, you won't get the isolations, but this means you can just drop a bunch of GFv3 jars in your classpath and run it like that.

So I added a little bit of API around that to make things pretty, and now you have the embeddable GFv3 API, which can be used like this:

GlassFish glassfish = new GlassFish();
// create smallest possible HTTP set up listening on port 8080
glassfish.minimallyConfigure(8080);

GFApplication app = glassfish.deploy(new File("path/to/simple.war"));

...

app.undeploy();
glassfish.stop();

Imagine the possibilities...

Thanks to the extensibility of GFv3, when you embed GFv3 in your JVM, you can plug into any of its extensibility points and tweak the behaviors in ways that you can't do with externally launched GFv3. You could also pick any flavor of GFv3 you want; if you just need the barebone servlet container and get smaller footprint, you can do that. But if you also need EJB functionality or some of our scripting offerings, that's cool with us, too. This is where we have an edge over Jetty, I think.

This is still a work in progress, but just imagine what we can do with this kind of stuff. How about testing your web services end-to-end without ever requring your developers to install GlassFish and set up database and all that. It also gives you interesting deployment options.

Oh, did I mention the start up time? One good thing about using a single classloader to load everything is that classloading overhead becomes much smaller. On my system, the server now starts in 300ms or so, complete with a deployment of a webapp. How many seconds does it take for your application server to start?

Maven-glassfish-plugin

I also wrote Maven glassfish plugin to wrap this as a Maven plugin. This allows you to do mvn glassfish:run to run the web appliation that you are developing on Maven (the equivalent of mvn jetty:run.)

I'm also thinking about quickly putting together Ant tasks.

Conclusions

170x93_Speaker_v4.gif

As I wrote, this is still a work in progress, but please tell us what you think about where we are going.

Finally, I'll be co-speaking more about this in the upcoming JavaOne technical session "TS-5921 GlassFish Project v3 as an Extensible Server Platform." If you are coming to JavaOne, I hope you'll come to the session.

Related Topics >>

Comments

Hi, This is a great new for us, too. But I cannot manage to deploy an EJB jar archive. Is it possible or did I miss some information ?

Hello kohsuke, We're very excited about your plugin over here at Harvard. It's the reason we're likely to switch over from JBoss. I think it'll help developers move to JEE. A "Jetty for JEE5" is something that's long overdue. We had an issue in that the link you published in this article doesn't describe org.glassfish maven-glassfish-plugin 1.0-alpha4, which launches an embedded GlassFish. It seems to point to the older org.glassfish.maven.plugin.maven-glassfish-plugin 2.1 that deploys to an installed glassfish. I can't seem to find any documentation on the plugin. I certainly hope Sun embraces it and makes it a fully supported product. I think it's one of the most useful things to come out of the Glassfish project. It allows our graphic designer to edit the application look and feel without an IDE or Java knowledge and makes development much faster for the team. Thanks again and keep up the great work. Steven Harvard Children's Hospital Informatics Program

hi is there any samples on how embedding EJB in desktop apps ? thx

hi koshuke, I'm trying to use the maven glassfish plugin you wrote in order to deploy my webapp to a remote glassfish instance. Unfortunately, I didn't find any documentation about that. It is really possible to do that? Thank you in advance for your response, JF.

hi koshuke, "I can now run Hudson in this embedded GFv3." Can you details some steps that you took to do this ? A lot of users will be interested in doing this. I would be interested in embedding a rails app using embeddable glassfish and warbler/jRuby. Also, did you have to remove stuff from glassfish ? Thank you, BR, ~A

How does this plugin relate to the old maven glassfish plugin: groupId: org.glassfish.maven.plugin artifactId: maven-glassfish-plugin version: 2.1 Does it support the same configuration parameters, for example the resources and jdbcDataSource tags? Also, do you know why it got stuck in a different spot in the maven deployment tree rather than just being a new set of 3.x versioned plugins (tracking glassfish versions?) Where can I find the plugin docs? I really want to use this but my searches are turning up bunk. Thanks, Kris

sashafirsov -- note that you can do all that with regular GF instances, but if the embedded GF made it easier for you to do it, that's wonderful!

Kohsuke, Surprisely, embedding could serve a good job in Unix secure environment. I want to have few domains to be served on same server by different GF instances which will have own Unix credentials. I.e. run as separate users w/ own FS access rights, CPU quota, etc. Looks like Apache w/ ProxyPass will serve this goal. May be you know the "legal" way of applying Unix user app limitations per-domain? Thanks! Sasha

Apparently https://maven-glassfish-plugin.dev.java.net/ was overwritten by a different plugin, so we no longer have the online documentation of how to use this plugin. So I posted a complete Maven demo project at http://github.com/kohsuke/maven-glassfish-plugin-demo/

And The ServerSide.com

Yes. There's a distribution of this where the whole thing is bundled into two jars, and it's quite easy to reduce that count to one.

I probably should add a mojo to maven-glassfish-plugin to do the uberjar-ing; unfortunately Maven assembly's "jar-with-dependencies" won't work nicely with this because certain files (like /META-INF/services/*) need to be merged, instead of overwritten.

Do you have a way to wrap everything up into one jar as Hudson does with Winstone? We're using Winstone right now for some stuff, but finding it severely limited in terms of performance and memory usage and we'd like touse something else. But I've been to lazy to write a plugin for Jetty or something else which wraps up my applicaiton.

Dan,

You should try the jetty-runner (new addition to jetty). It runs your webapp straight from the command line, eg:
java -jar jetty-runner.jar my/webapp.war

Kohsuke, This is an interesting development, downloading now to try it out!

regards Jan

Is this project dead? There is no GlassFish class in glassfish-embedded-all-v3-b02-06_03_2009.jar

sorry, my xml tags got washed away in the last post, but you probably got the idea anyway.

hello kohsuke. great work with this plugin! thanks alot. glassfish:run works great on a simple project, but i have problem loading classpath resources with my maven2 spring/jpa project my question is regarding where glassfish embedded server picks up configuration files. i use maven filters to enable different build environments for our application and use f.eks mvn glassfish:run -Denv=development and then apply filters in pom.xml like so: src/main/filters/environment/${env}.properties src/main/resources true and my properties in f.ex myapp-dao-beans.xml are defined like this: This works great with jetty:run and tomcat:run, but with glassfish:run i get org.springframework.web.context.ContextLoader initWebApplicationContext SEVERE: Context initialization failed exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [myapp-dao-beans.xml]: [java.lang.String] to required type [int] for property 'initialSize'; nested exception is java.lang.NumberFormatException: For input string: "${db.initialSize}" So it seems like glassfish:run tries to load my properties from src/main/resources instead of the filtered resources from target/classes. Do you know how to configure glassfish to load the correct properties when initializing the webapplication context? Any feedback is appreciated. -+petrusnilsen+-

kohsuke - OK, thanks. I'll give it a try. Your example didn't show how to separate the virtual domains and I assumed the worse. Thanks again.

guillaumelaforge -- see documents on the web site and the download section for more details. I also intend to prepare a complete self-contained example in Ant and Maven.

buzzheavyyear -- I thought classes like GlassFish and GFApplication are similar to org.apache.catalina.startup.Embedded. So what I'm showing here is exactly what you are asking.

ltackmann -- yes, you can deploy servlets loaded in your current classloader without ever assembling that to a war. I pasted the relevant part of the maven plugin source code below so that you can see the capability. List<URL> classpath = new ArrayList<URL>(); try { for( Artifact a : (Set<Artifact>)project.getArtifacts() ) { classpath.add(a.getFile().toURI().toURL()); } // resources, so that changes take effect in real time for (Resource res : (List<Resource>)project.getBuild().getResources()) { classpath.add(new File(res.getDirectory()).toURI().toURL()); } // main artifacts classpath.add(new File(project.getBuild().getOutputDirectory()).toURI().toURL()); } catch (MalformedURLException e) { throw new MojoExecutionException("Failed to convert to URL",e); } ScatteredWar war = new ScatteredWar( project.getArtifactId(), resourcesDirectory, webXml, classpath ); GFApplication app = glassfish.deploy(war);

Also, thanks for the link. I think convenience classes like this is very useful, and we should have the equivalent for GlassFish. With the embeeded GFv3, you take the JVM launch back in your control, so this gives you excellent oppporunity like setting up class file instrumentation for code coverage and etc. That would probably make a good article.

Finally, an EJB guy sits next to my office, so I'll ask him about your unit test annotation for EJB and see what he says.

smartini -- Yes, sir! Thank you for asking the question. The maven-glassfish-plugin doesn't deploy a fully assembled war. Instead, it picks up classes from target/classes, jars from all over your local Maven repositories, and web resources from another place. This is a must-have during development so that you get live feedback for your changes.

This is a big step in the right deirection, but in order for this to be really usable it needs to be able to instrument the web application from the current class path instead of requiring a war, similar to what can be done in Jetty (see example here).

I have not yet tried the GlassFish way but I assume it works with tools like cubertura to instrument the entire applications for use in code coverage reports ?.

Anyways nice to see that GlassFish is propelling forward with stuff like this. I do however think that we need a standard way to write unit tests which depends on embedded servers i.e.: public class MyTest extends EJBTest { @EJB private UserManager userManager @PersistenceContext(name = "MyPU") private EntityManager entityManager; // write tests using what ever unit test framework you desire : } this should be doable without depending on a specific framework and each vendor can implement it anyway he like

Great ! Will it be possible to point to a development dir (with exploded war) ? And to publish more distinct webapp at the same time (useful for complex applications composed of more webapp) ? Thanks and good work. Bye, Sandro

It would be great if someone could come up with a class similar to Tomcats org.apache.catalina.startup.Embedded so that you can effectively embed a server and easily deploy/undeploy wars, create virtual hosts etc

What set of jars are needed to run GF that way?

This made it into JavaLobby