A Look Inside the JBoss Embedded Project
DZone recently caught up with Andrew Lee Rubinger, core developer at JBoss who is working on the company's EJB 3 implementation and is also heading the Embedded and Bootstrap subprojects at JBoss. Embedded JBoss allows you to run JBoss within the same JVM as a plain Java program or a JUnit test -- having the ability to deploy to a more 'lightweight' runtime provides numerous benefits on both the testing and integration fronts.
At the end of the interview, Andrew provides a brief demonstration of the new Embedded APIs inside the JBoss application server and how to use these to manage a range of lifecycle operations such as deploying an artifact directly into the server, testing to make sure that it works and then bringing the server down cleanly.
Andrew is also author of the upcoming book by O'Reilly Media, "Enterprise JavaBeans 3.1".
The complete transcript of the interview has been provided below.
DZone: Andrew, can you tell us a little bit about some of the work you're currently doing at JBoss?
Andrew Lee Rubinger: Sure. Well, I came from the community. I was an application developer for quite some time working in EJB‑land; first, the EJB 2 stuff and then later with EJB 3. Now I'm primarily doing a lot of the EJB 3 development in our implementation at JBoss as well as trying to find ways to make it lot easier to test user application code.
DZone: What is the JBoss Embedded project?
Andrew: We wanted to build upon our success with the application server itself. The application server's job, very simply put, is to abstract out a lot of the concerns that an application developer should not worry about. They should not worry about clustering, they should not worry about transactions, they should not worry about any of the nitty‑gritty details that a computer needs in order to operate efficiently. They should be worrying about their application code, which is sending emails and persisting records to databases. Again, the job of the application servers is to provide as many services they can in a very transparent fashion while allowing the developer to spend the majority of their time writing application logic. The Embedded project is an extension of this where we say, "Ok, instead of requiring a stand alone application to provide the runtime, you can provide your own runtime and we're going to give you hooks for a deployment configuration and lifecycle API into the application server."
DZone: What are some of the challenges associated with testing in a stand alone application environment?
Andrew: The same as for testing in any remote process really. Interaction with a remote process is much more difficult. You're seeing it as like a confined box from the outside and you don't have a way of really hooking into the internals unless they're directly exposed to you. Even simple things like deployment, and start and stop become a little bit difficult when you have a remote application.
DZone: Is testing really the only scenario in which I would need an in‑process application server?
Andrew: No, certainly not. If you have your own runtime and you want to be running JBoss, there's some JBoss based services. Then you can certainly use the embedded launcher to start them in your own runtime and bring it up straight from there. It's a good migration point.
DZone: Can you give us an overview of some of the current features provided by the JBoss Embedded project.
Andrew: Sure. From the onset the stated goal of the JBoss Embedded project has been scoped very, very small. It should be just to start and allow for deployments into the application server from an existing runtime which could be from like a test environment, like a JUnit or a TestNG. That's our very core point right there. In addition to the core goals that we have in the Embedded project, we also have a bunch of extensions that are going to make the process a lot easier. One of them is a project called ShrinkWrap which is supplemented by the efforts of two community developers already. ShrinkWrap is a declarative archives project. It allows you to use Java code to assemble Java archives and WARs and EARs straight from code and it does it in a very abstract fashion.
What you do is you can take your resources like your classes, and your EJB descriptors and what not and put them into a virtual archive essentially and then ship that off for deployment into the embedded server.
DZone: How do virtual archives shorten the testing life cycle?
Andrew: As a developer you're probably making up all of your classes in your code and you're assembling them right there. It takes time to switch out of that mode of writing code and then going into making a build script, either like an ANT script or some sort of Maven assembly‑packaging step to actually make the formal archive which is going to be in probably a JAR format. What we do with the virtual archives is we just allow you to say, "Add this class and that thing and put them together and that's going to be our archive and we're going to fake it". The application server will see it as if it were the real thing.
DZone: What can we expect to see in future releases of JBoss Embedded?
Andrew: Well, as it is now, we've hit our number one goal and we are aiming to release it alongside the next community version of the application server. Looking forward what we want to do is extend it and make it as versatile as possible, which may mean that the user can start the application server in a variety of ways. At the moment it requires a JBoss traditional distribution which is: JBoss is downloaded from our community site and then unzipped into a location called JBOSS‑‑HOME and then we point to that and use it. In the future we want to have a single JAR distribution so that everything that you need is contained into this one JAR, all of the runtime artifacts and what not and they can just point to that, put it In their classpath and go.
Another way of doing it is to have it be pulled in automatically via a Maven dependency. So, we'd like a bunch of different run modes that we're really considering pushing out to the community. Whatever makes it easiest for them to test and gives the widest variety of options to launch the application server is what we're going to do with this project.
In addition to that we have a Maven 2 plug‑in wrapper, on the boards which will start up the application server and deploy whatever you need into it and then shut it down all alongside your Maven test cycle. It will be a matter of including this into your project's POM as opposed to actually having to write any of the embedded code.
DZone: How would you differentiate the various run modes within the Embedded project?
Andrew: It's all a matter of where the AS distribution lies. If you already have one installed on your system and you want to use that, it's already configured in some way, that may be the best way to do it. So point to a JBOSS‑‑HOME and go. A much simpler way is to just let Maven pull it all in. Maybe you're not using Maven, so you want to use the single JAR distribution to get everything in one neat little package.
DZone: When will JBoss Embedded find its way into the Enterprise platform for JBoss and commercial product line?
Andrew: This actually points to a real strength of the split between the projects and the products. Right now we're at the project stage here we can do all sorts of feature development that we want and change APIs and really let the community fuel how they best need this project to take shape and after it stabilizes for a while, we're going to lock down the API. We're going to just know that this thing works. At that point, the product‑management team may take a look at it and be like, "Hey, you know what? This is really something that's going to be of use not only to our community people but to our paid product support." And then they'll look to bring it in. At the moment, it's kind of on their radar and they're considering it for the EAP 6 timeline.
DZone: Do you have any general words of advice for JBoss developers out there?
Andrew: At the moment, I really find that the majority of users are not making the best use of the unit tests. While we need to be providing better integration test scenarios, like we're going to do with Embedded right here, I'm also finding that people are not really taking advantage of making straight POJOs out of their EJBs, just as regular Java objects, and, instead of getting injection, manually placing it in some of the dependent fields that they need and running the business logic. That's really what they should be doing, and also, thinking about testing when you're doing your design so that you can work in that fashion. EJB was built with that intent in mind, and I haven't seen it in practice in the field too much.
DZone: So, Andrew, I think our audience would love to get a brief demonstration of how this all works. Can you tell us a little bit about the demonstration you're about to give?
Andrew: Sure. Well, we're going to pull this straight from the test suite for JBoss Embedded itself. It's very simple. We bring up the Application Server, we assemble a virtual archive with a bunch of EJBs and we invoke upon them locally, which you can't do in a remote process. So we're going to do like a local invocation and then we'll bring down the application server.
Andrew: So today we're going to be looking at the new Embedded APIs for the JBoss Application Server. Our focus will be testing and the name of the game is going to be "managing lifecycle operations" ‑‑ that is, start and stop ‑‑ deploying an artifact directly into the server, testing to make sure that it works OK and then bringing the server down cleanly. I'm going to do this from right inside the IDE. Today we're using Eclipse and, by extension, the JUnit plug‑in.
What we have right here is a server test case that's going to contain all of our test logic as well as the setup and we also have a bunch of support classes, like EJB 3 beans and servlets. Those will be used in the test itself.
So why don't we first start by opening up the server test case and taking a look right in here. It's a simple POJO and it's annotated with our JUnit extensions. At the very top here we have a class member, which is going to be our interface to the server itself.
Scrolling down we'll see a bunch of constants that are used in testing, which we will ignore for now and get down to just the meat, which is the lifecycle of the test itself. We start off with a BeforeClass() method, and its responsibility is going to be to create a new server, start it up and then we'll also set a JNDI naming context while we're at it. We'll use that to look up our EJB 3 beans. Similarly to a startup, we have a shutdown and when this test is ready to finish up, we'll bring down the server.
Moving around to the test itself, today we're going to be showing just a simple EJB 3 session‑bean invocation. So that'll be in our TestSLSB() method, where we first need to assemble an archive. We're going to use the ShrinkWrap project to do that. What this does is it gives us a declarative API to point to a bunch of resources, create an archive from it and deploy that archive directly into the server. You don't need a build step at all.
You also see that if you want to get a verbose output, you can do that right here, and this will log out to the console the contents of our archive. We'll see that later. Deployment's really easy: we just call Server.Deploy() and pass it.
Onto the test itself. Now all we have to do is a traditional JNDI lookup, invoke upon the bean itself and then make sure that the unification resulted in the result that we were expecting. Assuming that all passes OK, we'll get on to undeploy right here, and it'll take the archive right out of the server.
Now it's time to actually run the test. We're going to do that by first making a run configuration that'll pull up this little box here and we'll go over, pick a JUnit [test], and hit "New". We've got to do a couple things first, before we're able to actually run our test. First thing to do is to go over to the environment tab. We're going to set an environment variable.
When this is launched, we're first going to point to our JBoss home. This is going to point to our installation of the Application Server. Grab and copy that right into there. And next, we're going to go on over into the arguments. We need to bump our PermGen size so that we don't get out‑of‑memory errors when we start up the server. And that'll do it. So we save this up and hit "Run". The thing we'll notice immediately is that the server's starting up in our console window, which should look familiar, only this time right in the IDE.
Now, the Embedded APIs are just that: they're only an API into the server. So we're not going to notice that there's any trimming of the runtime or anything like that. This is a traditional installation and right now we're bringing up the full default configuration. It's going to be the server container, the EJB container, JMS, Hibernate and all of that.
So, if we go on into the JUnit tab, we'll see, when our tests start to execute, they'll actually pop right in there and they'll start to turn green... hopefully, if we've done everything correctly.
Back in the console window, it'll let us know when we're about ready to start executing... and it looks like things are fully deployed and already executing. So, once the server's up, you'll see that things are going along pretty quickly: one second, two seconds and that's for a full deployment, the test, and to shut it all down.
When everything's done, we'll be left with a nice green bar right there and we can go ahead and examine the server output. If you scroll on up, you might even be able to find the ShrinkWrap logging output, which will show us the contents of our archives. We have that right here. And that'll about do it for a full development‑and‑test life cycle, right in the server, and executed straight from the IDE. Happy testing, everybody.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)