I bet the title got the attention of a few JBoss Application Server developers, but let me clarify something before I go on: My intention is not to rewrite JBoss AS in Scala. However, I think Scala makes it easier to build and test JBoss AS extensions/subsystems compared to Java. Let me explain:
JBoss Application Server 7+ is formed out of a MSC core and a bunch of subsystems built on top of it. To test these subsystems, a mix of steps are required including: compile the code, build the module(s) for this subsystem, change application server configuration, start the server and run your tests.
If you look at the JBoss Application Server code base, you'll find that all these steps are achieved with a mix of operations involving: Java compilation, Maven, Ant scripts...etc, which is a bit of pain.
When I started developing Escalante, one of my aims was to be able to test
my Escalante subsystems with minimal need from a build tool and in the
fastest possible way. The end result is that today I can just right click
one of the Escalante Arquillian tests (i.e.
, and it will run all the steps above without the need of a build tool!
How is that possible? Let me explain:
Building an Escalante subsystem
Escalante code is layered in such way that subsystems can be built purely
using Scala code. For this post, let's take
the Lift subsystem as example (For those unaware, Lift is a web application
development framework for Scala, more info in the FAQ). So for
Lift, we have a class called
which builds the JBoss module supporting the subsystem from scratch.
For that it uses:
- ShrinkWrap to build the JBoss module jar which includes classes in a number of packages and definition of the corresponding the JBoss AS Extension service provider:
- Scala XML integration to define XML directly in the code (without annoying Java formatting required to write an XML programmatically). XML is a requirement of the JBoss Application Server, and the Lift module uses XML to define itself and its dependencies. XML is also required in order to configure the extension and subsystem in the main app server configuration file:
Running Escalante Arquillian tests
With the subsystem built, it's time to figure out how to make sure the
JBoss Application Server instance is ready to serve our applications.
For this, Escalante has implemented some nifty
Arquillian callbacks in a class called
, which allow us to execute some code at different stages. This listener
class uses an
class that encanpsulates logic to do with setting up the application
Unzip JBoss AS before test set up
BeforeSetup, we can force the base JBoss Application
Server to be unzipped so that Arquillian has a JBoss Home to use:
testUnzipAppServer() method just unzips the server and changes file
permissions if necessary:
Set up modules before container start
BeforeStart, we can force Arquillian to install
the modules into the JBoss Application Server using the code mentioned above.
This way, by the time the server starts, all the extensions we want to install
are ready with their modules built and the configuration ready:
Tear down modules after container stop
This is a very important step because it's here where the app server is restored to its initial state in order for other tests to run cleanly. This involves restoring the original configuration:
Plug Arquillian with the listener
Once the code is written, we just need to write the corresponding service provider definition so that Arquillian picks it up:
Run the tests from the IDE
With this in place, you can now run your JBoss Application Server subsystem in-container tests directly from the IDE (of course, if you run it from Maven it will also work)!!
Reuse, reuse, reuse...
A very cool thing things about Scala is that it can work both as an standard programming language to build applications, but also as a scripting language, so this means that whatever code I've used to build the subsystems and set up the app server for the unit tests, it can be perfectly used when building an Escalante distribution.
With minimal changes, and the help of the Maven Scala plugin, I was able to create a simple Scala script that would build the entire Escalante distribution, which effectively builds the modules alongside their configurations, and installs the subsystems and extensions in the main configuration:
Configuring Maven Scala plugin to run this script is dead easy:
Pretty much everything I explained in this blog post could have been achieved using just Java (i.e. Maven has a Java exec plugin that could execute a Java class to build the distribution).
However, I think Scala makes it a lot more concise and cleaner to write all this up, particularly when it comes to embedding XML.
So, next time you're building a JBoss Application Server extension, give Scala a go! Using the code in this blog post you should be able to build JBoss Module jar archives required to test and run application server extension/subsystems programmatically, as well as adding their own configuration to the main app server configuration in a nice, reusable, way.
There are other benefits JBoss Application Server could get from using Scala as opposed to Java, but I'll leave those for future blog posts ;).
Finally, all the code I mentioned above is located in the Escalante Git repository, so you can clone it, open it in your favourite IDE and see all of this in action :)