I want to share a trick for a combination I suspect a number of people are using: SBT and ScalaTest
When you’re writing tests, you may have occasion to segregate some tests from the others – perhaps your functional tests, integration tests, or ui tests, or just tests that run more slowly than the rest of your suite.
There are a number of ways to tackle this (one good way is with SBT sub-projects, which I’ll cover in another post), but another option is to “tag” your tests. The ScalaTest doc covers tagging here, but what’s not as clear is how you do this and still run your tests with SBT.
Let’s say you have tagged some tests with the tag “Ui”, so you’ve got test declarations that look like this:
describe("some thing I want to test") { it ("should do a thing", Ui) { .... } }
I only want to run this test (and all other tests tagged “Ui”) in one particular job on my CI server.
What I need to do is pass the -l and -n options to ScalaTest, but I want to do this only when a certain system property is passed to my SBT instance. E.g. if I have a property “ui”, I can pass it to SBT with “-Dui=true”. How do I get this property to set the right option for ScalaTest so that when ui is true, ONLY my Ui-tagged tests run, and when ui is false, all the other tests EXCEPT the Ui-tagged tests run?
Here’s what I did in my build.sbt file:
testOptions in Test ++= (if (System.getProperty("ui", "false") == "false") Seq(Tests.Argument("-oDF"), Tests.Argument("-l"), Tests.Argument("Ui")) else Seq(Tests.Argument("-oDF"), Tests.Argument("-n"), Tests.Argument("Ui")))
What this says is that I always want the arguments “-oDF” passed to Scalatest, but that when ui is false, I want “-l Ui” and when ui is true, I want “-n Ui”. I default ui to false, so if it’s not specified at all, thats the same as false.
Now I can simply set a system property for my Jenkins builds, and the right tests are run at the right time.
I thought this might be helpful to others, as it took a bit of digging to figure out the exact syntax.
Note that this appears only to work with Scalatest 1.7RC1 (or later, probably), and SBT 0.11.2 or later.
The teams I’m working with have recently had the chance to move towards a continuos delivery model, where deployments to production of our applications happen many times a day, potentially.
To do this safely, you of course need the confidence that your changes are not going to break production, so you need a set of comprehensive, reliable and performant tests.
Organizing these tests into the proper “gauntlet” for the change to pass through has produced what we’re now calling the “development pipeline”, as it does kind of resemble a pipe with valves in it.
Recently I’ve been working on a number of projects that deploy Scala web applications to Tomcat, our container of choice.
Now, I’ve been using Tomcat for a long time, and it’s always done a pretty good job for me. One quirk that has always existed, in one way or another, was that it is occasionally necessary to restart Tomcat, no matter how well-behaved and non-leaking my applications are. You can make this quite seldom with carefully tuned memory arguments to your JVM, especially including the options that allow garbage-collection and re-use of permgen space, but I’ve never been able to simply make it unnecessary to eventually restart Tomcat.
Sometimes, Tomcat will even go down “hard”, becoming unresponsive and unable to be killed through it’s normal admin process, which is even worse, as this makes automated redeployment unreliable and slow.
I don’t think any of this is particular to Tomcat, either – I’ve seen variations on the same kind of issues with a great many Java servlet containers over the years, to a lesser (Jetty) and greater (Weblogic) degree.
In the last while, I’ve been developing web service applications based on the execllent Akka framework, and Spray on top of it. Spray has recently added a very thin container replacement called “Spray-Can”, which you can read about in detail on the Spray site.
In combination with the SBT “assembly” plugin, I’ve found it’s possible to deploy my apps in an entirely different way. Although there is, technically, still a container, it feels quite containerless in practice.
I build my application into a single executable JAR file, as opposed to the .war format so familiar to Java developers.
When this jar is run, my application becomes available on the configured port (8080 by default, but whatever I set it to, even at runtime).
This allows me to create a very simple script to keep my app running at all times, and to easily facilitate downtime-free upgrades, even on a single machine. Let me detail this…
My /etc/init.d script simply runs my executable jar file in a loop: e.g. something like this:
while true do java -jar /apps/dir/myapp*.jar done
Then I place the initial version, say 1.0, in the /apps/dir and run my script. Up pops my app.
Now I have another /etc/init.d start a second copy of the app, either on the same machine on a different port or on a second machine entirely. (I’ve found the lower memory requirements of this allow at least 3 copies on a single machine, though, compared with a full container).
Now I use something like Apache with mod_rewrite/mod_proxy, or balance or, my personal favorite, pound on the front end, so the concern of where my app is visible as far as URLs is entirely removed from the app itself. The application itself comes up on the context root “/”, on, say, port 8080 and 8081. Then my pound config simply redirects URLs of the form /url/to/app to one of these two ports, with failover/load balancing. My app neither knows nor cares it’s on the URL /url/to/app, that’s pound’s concern. It can even be behind HTTPS for all it cares – pound (or apache) takes care of that too.
Now when I want to deploy, I simply copy a new jar into the proper location in /apps/dir, e.g. myapp-2.0.jar.
Now I send a “poison pill” to my app in the form of a URL that causes it to shut down. My pound router filters out this call from outside the local network, so client’s can’t send it, and I send it directly to the running app (e.g. on port 8080 or 8081). This causes the app to terminate and exit completely, cleaning up any connections it needs to on the way. The VM terminates, and the shell script immediately starts up the new version on the same port.
All this time the second node on 8081 is still going strong with the old version, of course, so the clients never notice the bump.
Now I do the same to node two. When I say “I” here, I’m of course referring to my trusty Jenkins server, which is doing all this for me automatically.
Now I have all of the advantages of my app, in a highly cluster-able lightweight fashion, without using a servlet container at all.
I used to do something similar with the lightweight winstone server (which Jenkins itself uses, incidentally), but for Spray apps, the servlet API is something I don’t need, and I can run a much higher performance multi-core Akka stack instead, with all the same “containerless” advantages.
I recommend you have a look!
This is a further post in the series I started about the Principles and Practices of Software Craftsmen.
In this post I’d like to explore a specific principle that flows pretty readily into a practice that I think is very common among software craftsmen:
Solving the Right Problem Craftsmen often have a different perspective on what they do as developers. They understand enough of how IT fits into the business picture to be aware of what is really needed when given a project or even a single story.
Part of the value of an experienced professional in software development is their ability to not only perform the exact task they’re set, but also to help determine if the problem is being solved in the right way. Feature definition is not just a business analyst or customer proxy rattling off a list of acceptance criteria, it’s a give-and-take negotiation. Part of that negotiation is cost-based – the developer can give detailed estimates on specific parts of a story, and the customer proxy can decide to change parts of the story to maximize the value they get for the effort expended.
In addition, however, the experienced craftsman has to have a context of the overall project, and the business advantage that is expected from the development effort. He can then blend this with the technical understanding of *how* it’s going to be done to help figure out if there is a better (e.g. faster, easier, higher quality, more maintainable) way to do accomplish the same thing.
Even beyond finding a better way, the true craftsman can determine if the problem being addressed is even the right problem.
Generally, the user has a good idea as to what they want to accomplish, but not necessarily how they want to accomplish it, or how the features for accomplishing it might be turned into actual working software. This is where your craft comes into play, helping to “translate” the users desires into actual requirements that make the best sense given the context of the existing system of what’s possible.
Sufficient experience often allows a craftsman to look at the requirements user is putting forward and to understand the underlying need for functionality. This may be very different than what you’re actually being told, and to gain experience is the guide for the craftsman to be able to steer the user from what they think they want to what they actually want. This is not at all the same as telling the user that he’s “wrong”, It’s more a matter of being technique being able to communicate with the user at their own level, and to help them explore the problem at hand more thoroughly in the context of what’s possible with software and automation, to arrive at a superior definition of the problem to be solved.
This is what I like to call “solving the right problems”, and it is generally a core principle of software press craftsmanship.
Don’t Grab the Wheel
One way to block this process, and one which I have seen happen frequently in actual practice, is for the customer, customer proxy, or other management, to oversteer technical choices that are not entirely within their domain.
Sometimes this is a trust issue, in the sense that management may not trust the developers, in this case the craftsman, to make the correct choices. Sometimes it is out of a misguided sense of fear, which manifests itself in a desire to have influence over choices that management feel would be “safer”. Frequently, this means selecting and “standardizing” on obsolete, unsuitable, and unproductive technologies and techniques.
The irony, of course, is that in the process of specifying these unsuitable technologies and techniques, the overall risk in the project goes up dramatically.
Software is unique and a bit strange in the fact that it’s the one industry where the customer generally tells the vendor not only what problem they want solved, but how to solve it, and frequently even with what tools to solve it with.
It is somewhat like going to your doctor with a tummyache and telling him “I want my arm amputated, and I want you to use this spoon to do it with”. Oh, and I want it immediately and I want to pay 4c for the service, and it better not hurt. Or going to a master carpenter and telling him “here’s a chunk of pine, make me a mahogany bannister for my staircase, and here’s a blunt spoon to do the carving with”. While both of these sound absurd, they are no less absurd than hiring a software craftsman and telling him he must develop on a laptop using PHP and MS-Access and deploy on a five-year-old Windows 95 box with insufficient memory. (Not knocking any specific technology here, just pointing out that it’s bad to not make use of your developers expertise).
To get the best out of your craftsman, let him (or her, as I keep pointing out) do the driving. There may be necessary constraints of course, so explain them – but don’t grab the wheel out of his hands.
I’ll keep this one very short and to the point: I’ve been working extensively with Scalatra and Scalate recently, and it’s been great. My only minor problem has been with the bundles testing capabilities with Scalatra, namely the ScalatraFunSuite.
It lets you very easily test your Scalatra filters or servlets, but the number of things you can assert on is a bit limited. You can check status (to ensure you get a 200 instead of a 404 or a 500, for instance), and you can assert things about the contents of the response body, such as if it contains an expected string. All well and good, but not enough for my test-driven proclivities.
So I did a bit of tinkering, and came up with a nice clean way to grab things such as cookies, response values being passed to the template, the name of the Scalate template being called, and so forth.
I want to be able to write a test like this:
test("edit the organization data") { get(ORGANIZATION_URL) { status should equal(200) assert(template.endsWith(OrganizationController.ORGANIZATION_TEMPLATE)) } }
For instance, where I assert that the template that got called was a certain template that I expect.
It turns out this isn’t very hard – just stick another Filter in the chain when you set up your test, like so:
addFilter(classOf[TestFilter], "/*") addFilter(new CommonFilter, "/*")
And yes, I am using a different method invokation on the second line – I do this intentionally, so I can control creation of the servlet class under test, as I use Guice-servlet to inject all it’s service dependencies, and at test-time, I do this with implicit parameter – but that’s a whole ‘nother post
Anyway, TestFilter, as you might imagine, gives me “hooks” that I can assert on later. It looks like this:
object TestFilter { var lastURI: String = null var values: Map[String, AnyRef] = Map() def template = values("scalateTemplates").asInstanceOf[List[String]].head val cookies = ListBuffer[Cookie]() } class TestFilter extends Filter { def destroy() {} def init(conf: FilterConfig) {} override def doFilter(request: ServletRequest, response: ServletResponse, filterChain: FilterChain) { val wrappedResponse = new ResponseWrapper(response.asInstanceOf[HttpServletResponse]) val httpRequest = request.asInstanceOf[HttpServletRequest] lastURI = httpRequest.getRequestURI filterChain.doFilter(request, wrappedResponse); val names = httpRequest.getAttributeNames while(names.hasMoreElements) { val name = names.nextElement.asInstanceOf[String] val value = httpRequest.getAttribute(name) println(name + ":" + value) values += (name -> value) } } class ResponseWrapper(val response: HttpServletResponse) extends HttpServletResponseWrapper(response) { override def addCookie(cookie: Cookie) { super.addCookie(cookie) cookies += cookie } } }
That’s all there is to it – now I can call my servlet under test just like in the first code snippet, and assert on values being sent to the template, on the name of the template, on cookies, and so forth.
That’s it! Hope this turns out to be useful to some other Scalatra aficionados out there!
As most of the readers here probably already know, the term “stack” when it comes to app development is typically meant to describe the entire software structure on which the application is built. For instance, LAMP is a common example, standing for Linux, Apache, MySQL and PHP.
Developers are often tweaking and re-selecting pieces of their stack – the newest thing comes along, we like to try it out. But usually we’ve got a “go-to” stack for getting real work done, and constrain our experiments to a separate area until we’re sure something has what it takes to get included in our favorite stack.
There’s usually two major types of components in our stack – the bits we actually deploy, and the bits we use to actually develop with – the latter includes pieces we usually don’t actually ship with the finished product.
For instance, a classic J2EE stack might consist of the “deployable” pieces: Oracle’s standard Java EE 6, Hibernate, JSPs (technically a part of J2EE in any case), and Tomcat as a servlet container.
And the development stack might includes Eclipse, Maven, and various plugins to make Maven do our bidding.
There are a number of attributes I wanted in my own personal favored stack. This included:
Easy management of dependencies: I like knowing and controlling exactly what bits go into my finished application, and unless I can control all of the dependencies accurately, I can’t achieve acceptable quality.
Fast cycle-time: I want a stack that during development provides me with a rapid cycle time. E.g. the time between making an edit and seeing the results in either an application or test to be as short as possible.
Easy testability: I need my stack to facilitate testing, as my normal mode of development is BDD/TDD, where I write code because a tests tells me to, by and large. I want my testing tools to support my choice of test frameworks as well.
Modern language support: My choice of language for my own development is Scala, so I need a stack that supports Scala well. I won’t go into my reasons for choosing Scala, that’s a topic I’ve covered in another blog post.
So, without further delay, here’s my favored stack. First, the deployable bits:
Scala: I’m currently using Scala 2.8.1. Scala allows me to use a REPL for easy experimentation, which helps with my fast cycle-time requirement as well. The 2.9 release of Scala makes the REPL even more capable, but I haven’t tinkered with it much yet. I’ve talked at length about why I choose Scala in other posts, but it’s not for lack of knowing and having seriously tried other languages and environments. I can’t say I’ve tried them all, but I’ve tried quite a lot, and Scala remains my top choice.
Scalatra: Scalatra is a lightweight non-intrusive web app framework that lets me create web applications quickly, easily, and with maximum flexibility. I can write both RIA-style applications with REST/AJAX/COMET functionality or non-RIA request/response style applications, while maintaining statelessness and supporting scalability.
Scalate: With strong integration with Scalatra, Scalate is a powerful template system, perfect for generating XHTML for web applications in an extremely DRY and expressive manner. It’s like an up-to-date version of Velocity, but with Scala goodness and much more powerful.
SBT: A long-time Maven aficionado, I was hard-pressed to consider a different build system. I was, however, honest about Maven’s shortcomings, of which there are quite a few. I tried SBT and went back to Maven several times. I was intrigued enough with the advantages to come back again for another try, though, and I’ve now mastered it enough, and am getting enough benefits, that I won’t switch back.
Casbah:Casbah is the “missing link” between the Java MongoDB drivers and Scala. It allows database objects for Mongo to be readily constructed with Scala’s expressive map syntax, and type-safe retrieval of fields, not to mention it’s advanced query support.
Squeryl: On the occasion I need to interact with relational databases, Squeryl has become my tool of choice – but I’ve also dabbled with a few alternatives. One alternative I won’t go back to under any circumstances is Hibernate, or even worse, Entity EJB’s.
OpenJDK: Open JDK is a capable and independent JVM that supports Scala well.
MongoDB: I’ve used relational databases for several decades, but now that I’ve worked with key/value systems such as Mongo, I seldom find a job that RDBMS is better suited for.
Winstone: The Winstone servlet container allows me to create a single simple executable jar that incorporates both my app and the servlet container necessary for it to run in a single super-lightweight package that is easy to deploy and manage. Given it’s light footprint, it allows me to run multiple servers on a single system and provide a cluster “in a box”.
Linux: For deployment, I choose Linux. I’ve never found a business situation that wasn’t better served by Linux than by Windows, ever. Enough said.
Now the development stack:
IntelliJ IDEA: IDE support for Scala is not fantastic yet, but it’s quite good and getting better. The best of the lot is IntelliJ IDEA with it’s Scala plugin. It’s not perfect, but it’s quite capable. I will admit I frequently find myself being tempted to use TextMate, Kod, or, more recently, Sublime instead, however, but the completion and refactoring tools keep me sticking with IntelliJ.
SBT & JRebel: SBT’s own support for continious deployment and testing is excellent, but when combined with the (free for Scala) JRebel tool, it’s downright unbeatable. I can work on a webapp, make code or UI changes, flip to my browser and hit refresh and see the result. I can tell SBT to keep running my tests every time they need to run, and immediately see any breaks as they occur.
Jetty: SBT uses a built-in Jetty servlet to auto-deploy webapps for continuous development, so Jetty is part of my stack as well.
Mac OSX: For development, I work on a Mac system much of the time. I do have a desktop Linux system, but the impressive portability and power of my MacBook Air is hard to compete with.
The above are my current weapons of choice for web application development. So, what’s in YOUR stack, and why?
I’ve been privileged to work with some very capable people over the years in the software field. One of the benefits of working with such capable people is that some of their principles and practices rub off if you hang around them long enough.
I’ve tried to keep my eyes open and remember some of these principles and their associated practices, and on the whole I think I’ve managed to do that pretty well. I don’t necessarily claim to practice them all, but I do remember them at least
Years before the term become common, these were the true craftsman (and craftswomen) of our industry.
Over a series of posts here I’m going to try to regurgitate, record and share some of these principals and practices, in the hopes of trying to document what sets apart a genuine software craftsman from the rest of the people in the business of making software.
I’ve tried to organize the posts around specific principles or specific practices.
Principles By Principle I mean some underlying belief or unwritten rule of conduct that software craftsmen hold true. It may not be something they’re even consciously aware of – although part of my goal in documenting this kind of thing is to create that consciousness, if it’ not already there.
Practices For practices I mean the activities that craftsman undertake in their day-to-day work that supports and actualizes the principles we talked about above. What do we do and what principle does that activity come from?
I’d also like to hear your tales from the trenches, and what you think are some of the best attributes of excellence. If you’re a software craftsman (and yes, when I say craftsman I’m always including craftswomen as well, but the DRY principle prevents me from writing it all the time), then tell me what you think the founding principles of our discipline are, and what practices you follow to uphold and promote these principles.
If you don’t feel like commenting here on the blog just drop me a line my email address anytime.
You never know, I might even write a book on the subject eventually!
I had planned this past weekend to attend a local conference and present a quick discussion on “Why Scala?”, or reasons why the Scala language might be worth the attention and time of any serious student of the programming craft.
Unfortunately, I ended up unable to attend, but I thought I’d post a link to my Prezi (a new style of presentation editor) here, in case anyone can make use of it.
Here’s the link: http://prezi.com/fb0vqbuqk33a/why-scala/
Feel free to make use of all or part of it as you see fit. Hopefully another opportunity will come up to try it out and refine it to an interested group in the future.
I’ve recently been doing a lot of my own projects in Scala, and, as many other developers have learned, have been finding it harder and harder to “revert” back to Java when Java is mandated for a specific project.
Don’t get me wrong, I still use a lot of other languages, and languages come and go – I’ve learned not to get too attached. Yesterday (literally) I was coding in Ruby, today in Scala, Java and a lick of Python (well, Jython, technically).
Still, I find myself more and more reaching for Scala as my preferred weapon. So I started asking myself why that is, and thought I’d share the answers I’ve come up with so far. I’d be pleased to hear anyone other experiences as well, as I’m pretty sure this is not a complete list. It’s also not in any particular order, just the order I’ve remembered them.
REPL The REPL for Scala is a huge plus for me. I can quickly experiment with a few lines of code, either with or without the rest of my project on the classpath, and interactively work my way towards a solution. The closest in Java was by writing a throw-away unit test in my IDE, and that’s clumsy by comparison. The REPL is also an excellent learning tool, as anyone who’s used a language with one can attest.
Actors Actors are a library, not an in-built feature of Scala per se, but both “regular” Actors and alternatives such as Akka provide much of the power of languages like Erlang, while retaining all the other benefits of Scala. It’s difficult to grasp just how much power this can mean to a development project until you’ve worked with them a while, then they’re very hard to live without.
Speed of Evolution Scala evolves significantly faster than Java (or many other languages, for that matter). I won’t go into the many reasons why, they’ve been explored elsewhere, but this is a huge plus for me compared to the glacial pace of Java language evolution.
Open Source Scala is actually open source. Not nearly or mostly or kinda or somewhat. Not it’s libraries, or everything except it’s mobile version, or all the bits someone doesn’t think they can make money off of. It’s released under a very open license, rather like a BSD license, with basically no restrictions. Here’s the license itself, so have a read. It won’t take more than a moment.
By contrast, here’s the page discussing the licenses for Java. Bring lunch. And a lawyer, preferably.
JVM and CLR I don’t use the CLR, and in general despise everything ever produced by Microsoft, but it’s interesting and valuable in some situations to note that Scala doesn’t only run on the JVM, but also the CLR.
Scripting Ant is an obsolete build system and a worse cross-platform scripting language. Shell is OK, but showing it’s age a bit. Scala runs on every platform I care about, and is every bit as easy as shell to script with, so I’m finding I use it more and more for both quick-and-dirty scripts where I might have used shell before, and for things that will live longer, such as deployment and installation.
Expressiveness You can say a lot, quickly, with Scala. It’s not just terse and brief, but highly expressive. Examples abound out there, so I won’t waste space trying to prove it here, but in general I find I’m writing perhaps one fifth as many lines to do any given job when compared with Java. It’s at least on par with Ruby.
Not just speed of writing the code, although that’s good. It’s more about speed of reading the code. I can read good Scala and understand it significantly faster than I can wade through the equivalent code in Java.
Community I can’t deny Java has a huge and helpful community as well, but Scala’s community compared to that of other “newcomer” languages is very diverse and helpful. It’s not a reason to pick Scala over Java, but it might be enough to pick Scala over, say, Python or Ruby, in some cases.
Functional/OO Blend Scala brings the capabilities of functional languages like Erlang, Haskell, and others to an approachable platform that lets you incorporate these concepts as you’re ready for them, as opposed to an “all or nothing” approach, as a Java programming moving to, say, OCaml might feel. It encourages immutability, but gently and easily, giving you time to learn the power of functional development, while allowing the many advantages of object-orientation to be retained at the same time. No other languages does this quite as well as Scala, in my view.
Options Had enough of NullPointerException ruining your day? Have a look at Option in Scala. It’s not a silver bullet, but it’s a heck of a lot better than Null
Productivity The expressiveness of Scala means I can get a lot done, quickly, yet still have high-quality functional and performant code that I can read and maintain when I’m finished. Scala is approachable and easy to learn, and you don’t have to learn all the fancy stuff it can do at first – you can just write what looks like extremely expressive Java, then get into the cool stuff as you go.
Not Oracle I have very little faith in Oracle’s stewardship of Java, to be honest, and I don’t think Oracle can sue me for using Scala. IANAL, however, and they may try
One of my primary reasons for this worry is Oracle’s about-face on the issue of open source Java. Do a google on the “Apache Harmony Project” for the gory details.
Traits Multiple inheritance without the pain, basically. Interfaces and abstract classes with all the warts of both taken away. This is one area where Scala doesn’t just top Java, it blows it out of the water.
Advanced Type System Scala’s type system starts with the pure object-orientation principle (everything is an object, there are no primitives), and goes much, much further. Case classes alone are worth the price of admission, and they’re only the tip of the iceberg. See High Wizardry in the Land of Scala for a taste of what the type system in Scala can do.
Java compatability Conversely, Java itself is a reason for my preference for Scala. Instead of Ruby or Haskell or OCaml, if I choose Scala I basically get the entire JVM ecosystem available to me – and that’s a lot. I get OSGi, JDBC, all the drivers for every SQL and NoSQL database you’ve every heard – the works. Except with a language that’s decades ahead of plain Java in other areas.
Tool support Not compared to Java, which of course has amazing tool support, but tool support for Scala is now up to the point where it’s quite acceptable, even good in some places. I prefer IntelliJ IDEA with the Scala plugin, but good support also exists for Scala now in most of the major IDEs, and more come along every day, it seems.
Collections Scala’s collection classes are a long way ahead of Java’s, even when you add libraries like Google Collections to Java, and allow you an easy way to go back and forth to existing Java libraries, especially in Scala 2.8.
DSLs Scala’s flexible syntax makes internal DSLs almost trivial, a huge boon when working with many frameworks. My own little DSL for Vaadin UI development puts a whole new aspect on creating UI’s, I’ve found, and tools like Squeryl and others put this DSL capability to incredible use, things that just aren’t easily possible in Java.
If you’re interested in learning more about Scala, try my resource page. It’s chock-full of links to many excellent Scala resources on the web.
I am pleased to report that the campaign goes well thus far.
We met the enemy at the border of Weblogic, and battle was joined, SVN commits clashing with intractable lengths of binary spaghetti at every turn.
Our original plan was to crush all remote beans entirely, liberating the entire application from this particular scourge. Much progress has been made towards this goal, although the enemy is powerful and resourceful.
We can confirm that at least five of our opponents fell early in the glorious battle, with minimal losses on our side, despite the heavy resistance. At several points in the battle the WTF/minute meter was rising to dangerous levels. One particularly brave refactor was rolled back in a blaze of glory, still muttering “stay in target directory… stay in target directory”…
Our initial attempt at penetration of the enemy’s lines was at the JMX pass. Despite valiant attempts by our brave tests, we were eventually defeated in this attack by proprietary “extensions” to what should have been well-accepted standards. The enemy knows no shame, and will stoop to perverting even innocent RMI for it’s nefarious purposes. In fact, they dredged up what should have been long-forgotten and discarded protocols to throw us off the track, even resorting to JMX over IIOP, with proprietary client libraries, which was too much for us – we could not withstand that level of firepower. We had to find another way.
We were repelled by the evil machinations of the enemy’s classpath conflicts at the battle of the EAR, but were able to outflank them and retreat to a previous revision number with minimal losses. We then regouped and attacked again in the region of the remote stateless session bean, and only one of the enemy escaped our wrath. We will be watching this one remaining combatant carefully, and at his first slipup he is sure to be doomed as well. We have assigned our best integration test to watch his every move.
Despite attempts to deceive our troops with obscure and fiendish JNDI naming practices, we were able to ensnare many of the enemy in our powerful web of functional tests, where they can do no further harm.
At least four entire modules of the enemy’s forces did not survive the encounter!
We have won this conflict for now, yet many challenges still lie ahead in future battles. The enemy used many clever tactics this time, but we have not yet encountered their ultimate weapon: the greatly-feared container-managed entity bean! Weapons of mass deprecation of this nature must not be allowed to continue to intimidate future generations. Massive as these weapons are, they are slow and no match for our lightweight DDD techniques – we will lure them into shallow memory and watch them go aground, tangled in their own distributed transactions.
For now, though, our troops have withdrawn to the safety of our own home OSGi modules, where order, structure and modularity reign supreme.
Stay tuned for future reports….