A few weeks ago I had an opportunity to go to The Server-Side Java Symposium, an annual event for Java aficionados held in Las Vegas, Nevada. What happened there will not stay there, however.
I found a few interesting things out, and I’m going to try to share them over the course of a few blog posts, in case anyone out there is interested, and so I can find them later for myself as well
TSSJS is not about vendors, it’s about technical info, so there were only a few “booths” from the handful of commercial sponsors of the event, one of which was, inevitably, Oracle. Given the Sun acquisition, a question on the mind of many developers has been “what’s Oracle going to do for/with/to Java?”.
It’s a legitimate concern, and indeed a complex question with a number of complex answers – but one of my reasons for being in Vegas was to get some of the answers.
The keynote presentation at TSSJS was by James Gosling, the “father” of Java. As everyone no doubt reading this already knows, he’s subsequently left Oracle, for undisclosed reasons. That, to me, lessens the impact of his remarks somewhat, as I suspect he knew by the time we heard him speak in Vegas that he’d be on the way out the door, but he still had a lot of interesting things to say.
About 800 people were in the room, I estimated, to hear the keynote. Interestingly enough, Gosling’s position at Oracle was “Client Software Group” VP. I generally don’t think of Java as having much to do with “client” software, personally, so that in itself was informative.
He had an image of the Java mascot (the little delta-shaped guy) wearing a snorkle in a fish tank, a play on the “Soracle” name mash-up.
In any case, the keynote touched on what’s happening in the Java world. He emphasized the wide spectrum of devices on which Java is found, and how networking ties all of these devices more and more into a cohesive whole.
Some stats were mentioned: there are about 15 million downloads per week of Java, and something like 10 billion (with a “B”) Java-enabled devices of one sort or another out there in the wild, perhaps 1 billion of which are Java-enabled desktops. By any metric, Java is a huge success, and is in many ways more popular in the rest of the world, especially Europe, than it is in North America.
100 million of those devices are are TV devices, and on top of all it are about 2.6 billion Java-enabled cell phones.
Conclusion: It’s not going away, soon or quickly
A site like the Apple App Store existed for Java apps 7 years before Apple’s app store – but it was in Japan.
There are 5.5 billion smart card devices Java-enabled out there – the V3 standard actually has a servlet container in it – U.S. military dog-tags apparently now use this standard.
The Amazon Kindle is a Java device, under the skin.
Gosling proffered a definition of success: being completely invisible, people just get stuff done.
There are something like 6.5 million professional Java developers out there, 800 thousand of which are in India. Most colleges have a Java course requirement, modifying the old saw of “write once, run anywhere” to include “learn once, work anywhere”.
After this deluge of interesting stats, Gosling moved on to discuss the next big thing in Java, in his opinion: Java EE 6, the foundation for next-generation enterprise software. The spec was approved November 30th, 2009.
There are two major flavors of JEE6 – the “full” profile, with everything, and the “web” profile, with EJB3 “Lite” and just the most frequently used specs, not the more obscure stuff.
A major emphasis in next-generation Java development is modularity: making hard problems easier by breaking them into a number of less-hard problems. Major endorsement here for OSGi.
As far as Gosling’s concerned, the correct amount of XML required is exactly none Many developers in the room agreed with him, and it’s now possible with JEE6 and it’s powerful annotations.
Much of the benefit of dependency injection and resolution that Spring provides has been baking into the core Java EE platform now, and much of the pain of EJB has gone away. In fact, one of the most painful parts of EJBs, CMP Entity Beans, is no longer supported by the spec at all, in favor of JPA.
Glassfish V3 is the JEE6 reference implementation, and it’s OSGi-based.
Then it was demo time: Gosling (with some help from a couple of developer types) fired up Netbeans and Glassfish and did some show and tell of the coolness of JEE6.
We saw a webapp deployed – with no web.xml, no WEB-INF directory at all, everything annotation-based and dependency-injected at the proper times. We saw a stateless EJB auto-deployed to via an OSGi bundle into the container in less than a second, direct from the IDE. No boilerplate, no config, no reams of XML files to bolt it all together, just code and go.
We saw that same app preserve session state even when it was redeployed, which was very cool (a counter was showing the number of hits to the page – code was changed and redeployed, and the counter kept incrementing – and no, it wasn’t stored in a client-side cookie, it was in the session).
I noticed that all the Oracle guys were using Macs, incidentally
Gosling notes that JEE6 shouldn’t just be one version number past JEE5 – it’s more like JEE 60 in comparison
Saw the @Schedule annotation, where a bean can be scheduled for execution with cron-like ease, but all within a JVM.
Gosling noted that Felix was the web container under the skin of Glassfish.
We saw the @Observes annotation being used – a way to register listeners without any code or configuration. It was noted that Swing could benefit enormously by this pattern.
Then we saw a demonstration of Glassfish’s web console. The “web profile” of JEE6 doesn’t include JMS by default, so the example shown was adding that support by installing a new bundle in the running container. Two clicks and it was done. A GUI admin console can be added for any bundle, including your own bundles.
Gosling then wrapped up with an overview of some of his personal projects, and then took some questions. He also mentioned a new “app store” for Java that’s in the works, to be coming on “store.java.com”. It’s in the final stages of work now, apparently.
That was the end of the first keynote of TSSJS. In the next few posts I’ll talk about some additional sessions that my associate and I attended, and some of the other good stuff we learned.
In my ongoing tinkering with the Vaadin web framework, I had a need to build a country and state/province dropdown, much like you see on almost every e-commerce site out there.
Unlike the typical pair of these fields, however, I wanted mine to work correctly – that is, for the list of provinces or states to reflect the currently selected country automatically.
Simple as this sounds, it’s an exercise I’ve done many many times in too many different frameworks and technologies to count, and it’s never quite as easy it as seems like it ought to be. As you can see, many sites give up, and simply have a combined list of all states and Canadian provinces, or some such hack. I’ve never actually seen one that changes the name of the “State” field to “Province” when Canada is selected as the country, for instance.
So I set out to try this in Vaadin, and was pleasantly surprised.
Let’s assume we’re building a Form object in Vaadin. We can add our “country” drop down select box by saying this:
Select country = new Select("Country:"); country.addItem("[Unspecified]"); country.addItem("United States"); country.addItem("Canada"); country.addItem("Afganistan"); form.addField("country", country);
Of course, we’d probably want our list of countries to come from some other data source, like a property file or static list, but this gives you the idea.
Now we add our “state” drop-down:
final Select state = new Select("State:"); form.addField("state", state);
Now we must decide whether to populate the state with actual U.S. States or Canadian provinces….
country.addListener(new Property.ValueChangeListener() { public void valueChange(Property.ValueChangeEvent valueChangeEvent) { String selectedCountry = valueChangeEvent.getProperty().getValue().toString(); if (selectedCountry.equals("United States")) { state.setCaption("State:"); state.removeAllItems(); state.addItem("Alabama"); state.addItem("Texas"); state.addItem("Idaho"); } else if (selectedCountry.equals("Canada")) { state.setCaption("Province:"); state.removeAllItems(); state.addItem("Alberta"); state.addItem("Saskatchewan"); state.addItem("Manitoba"); } state.requestRepaint(); } });
So our fields before we select a country look like this:
Now we’ve got a “state” field that will change it’s title to “Province:” if the country we select is Canada, and populate itself with the appropriate list of the provinces.
But switch right back to “State” and populate the dropdown accordingly if we change our minds and select United States again…
Not too difficult, and very easy to understand and extend to other situations (or countries).
As with all Vaadin, it’s pure Java, fully testable (at the Unit level, as well as at the functional level). In fact for the “real” version of this (which reads it’s countries and such from property files), I was even able to easily TDD it, which often isn’t the case in UI technologies.
In my experience, the future of modularity on the JVM is OSGi.
Many developers don’t seem to recognize the need for it, but other bloggers have covered this in great detail (see my Resources page for some links), so I’m not going to try to “sell” OSGi here at all – I assume you’re already sold, and looking at how to put OSGi to good use in your development and deployment process.
Extending my recent experiments with the Vaadin framework, I decided I wanted to have a Vaadin front-end talking to a set of OSGi services on the back end. Initially, these will be running within the same OSGi container, which in this case is FUSE 4, the commercially supported variant of Apache ServiceMix.
One of my goals was to acheive a loose coupling between the Vaadin webapp and the backing services, so that new services can readily be added, started, stopped, and updated, all without any impact on the running Vaadin app. I also wanted to maintain the convenience of being able to run and tinker with the UI portion of my app by just doing a “mvn jetty:run”, so the app needed to be able to start even if it wasn’t inside the OSGi container.
Fortunately, doing all this is pretty easy, and in the next series of articles I’ll describe how I went about it, and where the good parts and bad parts of such an approach became obvious.
In this part, we’ll start by describing the Vaadin app, and how it calls the back-end services. In later parts, I’ll describe the evolution of the back-end services themselves, as I experimented with more sophisticated techniques.
Vaadin Dependency I’m building all my apps with Apache Maven, so the first step was to create a POM file suitable for Vaadin. Fortunately, Vaadin is a single jar file, and trivial to add to the classpath. My POM needed this dependency:
<dependency> <groupId>vaadin</groupId> <artifactId>vaadin</artifactId> <version>6.1.3</version> <scope>system</scope> <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/vaadin-6.1.3.jar</systemPath> </dependency>
Here I’m using the trick of specifying a systemPath for my jar, instead of retrieving it on demand from a local Nexus repository or from the internet, but that’s just one way of doing it – the main thing is to get this one Vaadin jar on your path.
web.xml Next I proceeded to tweak my web.xml to have my top-level Vaadin application object available on a URL. The main Vaadin object is an extension of a Servlet, so this is also very easy – here’s my web.xml in it’s entirety:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Admin</display-name> <servlet> <servlet-name>Admin</servlet-name> <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class> <init-param> <param-name>application</param-name> <param-value>Admin</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Admin</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
In this situation my “Admin” class is in the default package, which is not generally a good practice, but you get the idea.
Menu and MenuDispatcher I then used the “Tree” class in Vaadin to build myself a nice tree-style menu, and added that to the layout on my main page. My main page has some chrome regions for a top banner and other assorted visual aids, then a left-side area where the menu lives, and a “main” area, where all the real action in the application will happen.
A class I called MenuDispatcher “listens” for events on the menu (e.g. the user clicking something), and does the appropriate action when a certain menu item is clicked.
Here’s the interesting bits from the MenuDispatcher – as you can see, it’s constructed with a reference to the “mainArea” layout when it’s first initialized.
public class MenuDispatcher implements ItemClickEvent.ItemClickListener { private VerticalLayout mainArea; public MenuDispatcher(VerticalLayout mainArea) { this.mainArea = mainArea; } public void itemClick(ItemClickEvent event) { if (event.getButton() == ItemClickEvent.BUTTON_LEFT) { String selected = event.getItemId().toString(); System.out.println("Selected " + selected + " from menu"); if (selected.equals("create dealer")) { createDealer(); } else if (selected.equals("edit dealers")) { editDealer(); } ... } System.err.println("Selected " + event.getItemId()); } } private void createDealer() { mainArea.removeAllComponents(); Component form = new CreateDealerForm(); mainArea.addComponent(form); mainArea.setComponentAlignment(form, Alignment.MIDDLE_CENTER); mainArea.requestRepaint(); } private void editDealer() { ... } ... }
Again, this code can be made more sophisticated – I’m thinking a little Spring magic could make adding new forms and such very convenient, but this gets us started.
Submitting the Form The “CreateDealerForm” object referred to in the Dispatcher then builds a Vaadin “Form” class, much like the example form built in the “Book of Vaadin”. The only interesting part of my form was that I chose not to back it with a Bean class, which is an option with Vaadin forms. If you back with a bean, then you essentially bind the form to the bean, and the form fields are generated for you from the bean.
If I wanted to then send the corresponding bean to the back-end service, then binding the bean to the form would be a good way to go. Instead, however, I don’t want my back-end services to be sharing beans with my UI application at all. I’ll explain why and how later on in more detail.
The interesting part of my form, then, is how I handle the submission of the form:
Assuming I have a button on my form, defined like so:
Button okbutton = new Button("Submit", dealerForm, "commit");
I can add a listener to this button (again, using Vaadin’s magic ability to route the Ajax events to my Java code) like thus:
okbutton.addListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { Map<String, Object> parameters = new HashMap<String, Object>(); for (Object id: dealerForm.getItemPropertyIds()) { Field field = dealerForm.getField(id); parameters.put(id.toString(), field.getValue()); } System.out.println("*** Calling dealer service via dispatcher"); ServiceClient.call("dealer", "save", parameters, null, null); getWindow().showNotification("Dealer Saved"); } });
I’m using an anonymous inner class to listen to the event, and the “buttonClick” method gets called when the user says “Submit”.
The next steps are where the form meets the back-end service: First, I iterate over the form and build a map containing all the field values. The map is keyed with a string, for the name of the field or property, and the value in the map is the value the user entered. Note that these values are already typed – e.g. a checkbox can have a boolean, a TextField can have a string, a calendar field can have a java.util.Date. We retain these types, and wrap everything up in a map.
Now (after a quick println so I can see what’s going on), I call a static method on class called ServiceClient, sending along the name of the service I want to call, the operation on that service, and the parameter map I just built from my form.
The last line just shows a nice “fade away” non-modal notification to the user that the dealer he entered has been saved (assuming the call to ServiceClient didn’t throw an exception, which we’re assuming for the moment for simplicity).
So, now we have our “call” method to consider, where the map of values we built in our Vaadin front-end gets handed off to the appropriate back-end service.
Calling the Service
The only job of the ServiceClient object is to route a call from somewhere in our Vaadin app (in this case, the submission of a form) to the proper back-end service, and potentially return a response.
We identify our back-end services by a simple string, the “service name” (our first argument). The second argument to call tells us the “operation” we want from this service, as a single service can normally perform several different operations. For instance, our dealer service might have the ability to save a dealer, get a list of dealers, find a specific dealer, and so forth.
In Java parlance, a service operation might correspond to a method on the service interface, but we’re not coupling that tightly at this point – our service, after all, might not be written in Java for all we know at this point, and I prefer to keep it that way.
This is the “loose joint” in the mechanism between the UI and the back-end. To keep the joint loose, we don’t send a predefined Bean class to the back-end service to define the parameters to the service operation, we send a map, where that map contains a set of key/value pairs. The keys are always Strings, but the values can be any type – possibly even another map, for instance, which would allow us to express quite complex structures if required, in a type-independent fashion.
Let’s have a look at ServiceClient:
public class ServiceClient implements BundleActivator { private static DispatchService dispatchService = null; public void start(BundleContext context) throws Exception { ServiceReference reference = context.getServiceReference(DispatchService.class.getName()); if (reference == null) throw new RuntimeException("Cannot find the dispatch service"); dispatchService = (DispatchService) context.getService(reference); if (dispatchService == null) throw new RuntimeException("Didn't find dispatch service"); } public void stop(BundleContext context) throws Exception { System.out.println("Stopping bundle"); } public static List<Map<String, Object>> call(String serviceName, String operation, Map<String, Object> params, String versionPattern, String securityToken) throws Exception { if (dispatchService == null) { System.out.println("No OSGi dispatch service available - using dummy static data"); return StaticDataService.call(serviceName, operation, params, versionPattern, securityToken); } return dispatchService.call(serviceName, operation, params, versionPattern, securityToken); } }
Let’s go through that class piece by piece. First, you’ll notice that the class implements the BundleActivator interface – this tells the OSGi container that it is possible to call this class when the OSGi bundle containing it is started and stopped. During the start process, you can have the class receive a reference to the BundleContext. This is somewhat analagous to the Spring ApplicationContext, in that it gives our class access to the other services also deployed in OSGi. The Spring DM framework lets you do this kind of thing more declaratively, but it’s good to know how the low-level works before engaging the autopilot, I always find.
In order to allow BundleActivator to be found, we need another couple of things on our classpath, so we add this to our POM:
<dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_core</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_compendium</artifactId> <version>1.0</version> </dependency>
This defines the BundleActivator interface and other OSGi requirements which we use.
As you can see, we use our reference to the OSGi context to get a ServiceReference to an interface called “DispatchService”. We’ll examine dispatch service in detail in my next posting, but for now you can see we hold on to our reference as an instance variable.
When the call to the “call” method happens, our DispatchService reference is already available if we’re running inside an OSGi container, all wired up and ready to go. To give us flexibility, though, we also allow for the case where dispatch service is null, meaning we’re not running inside and OSGi container.
Instead of crashing and burning, however, we simply redirect our call to a “StaticDataService” class, which does just what you might expect. For every call it understands, it returns a static “canned” response. This allows us to build and test our UI without actually having written any of the back-end services, and to continue to run our Vaadin app with a simple “mvn jetty:run”, when all we’re working on is look and feel, or logic that only affects the UI.
This means my “cycle time” to test a change in the UI code is a matter of seconds – when I do a “mvn jetty:run” my code is compiled and up and running in my browser in about 5 seconds, and that’s on my 5 year-old macbook laptop, so there’s no penalty for not having a dynamic language in the mix here, from my point of view.
If DispatchService is not null, however, then we’re running “for real” inside an OSGi container, so we use our stored reference to the dispatch service to “forward on” our call. The dispatch service works it’s magic, which we’ll examine in a later post, and returns a List of Map objects with our response. This list might only contain one Map, of course, if the service was a simple one.
The response is then returned to the caller elsewhere in the Vaadin application, to do whatever is necessary from a UI point of view – perhaps populate a form or table with the response data.
As we’ll see in detail in my next post, the dispatch service in this case acts as a “barrier” between the UI-oriented code in our Vaadin app and our domain-specific application logic contained in our services. It is responsible for mapping our generic map of parameters into whatever domain beans are used by our back-end services, and for figuring out which of those services should be called, and which operation on that service is required. Those services then return whatever domain-specific objects they return, and the dispatcher grinds them into non-type-bound maps, or lists of maps, if there is a whole series of returns.
This means our Vaadin app only ever has to talk to one thing: the dispatcher. We only change our Vaadin code for one reason: to change the UI, never in response to a change of service code, even if the beans and classes of that service change significantly.
Next time we’ll look at the dispatch service and the first of our application-specific domain-aware services, and see how they come together.
The Apache Group have recently released version 4 of the ServiceMix ESB. (Enterprise Service Bus), and I had a chance to work with it a bit over the weekend.
As we develop more and more services, the plumbing is starting to get complicated. We’re starting to ask questions like what versions of what services do we have? What dependencies do we have between services? How can/should we deploy services? Should we use REST or JMS for this service? How can we easily manage and monitor all these services in a fully clustered, scalable and high-availability environment?
In short, how can we develop powerful scalable services fast and not worry about the plumbing?
We’re not the only people to have asked these questions – and one powerful answer is to use an ESB.
ESB’s have come a long way, and the JBI standard and OSGi finally get together in this version of ServiceMix, and some pretty powerful magic happens as a result.
Just about every organization that writes sophisticated applications, particularly Java applications, have run into some of the problems that an ESB provides solutions for – the same is true of OSGi.
As Anthony Juckel put it on his blog, “Any sufficiently complicated Java program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of OSGi.“. This is quite true, in my experience, and can even be extended to include ESB’s, in that if you’ve got a number of JVM services interacting on a network to solve a problem, you’ve got some kind of an ESB going on, whether you call it that or not.
A common practice recently is to write software that provides “services”, then to combine these services into a complete system – in other words, we write services, but we compose systems (from these services). The awkward part comes (well, one awkward part) when we try to write the service in such a way that it can be used in many different ways – in other words, to maximize the potential for re-use – while at the same time trying to do the simplest thing that can possibly work.
No matter what service mechanism we choose, we lock ourselves in to some degree. If we write our service to use JMS (Java Messaging System), so we can support nice events and queues and other asynchronous goodness, we can’t easily then use our service from, let’s say, a client that looks for a REST service. If we choose SOAP, we can’t easily talk to our service from a client (which could be another service) that wants to post an event, instead of call a SOAP interface.
Normalized Messages The Java JBI (Java Business Integration) standard answers this problem: it provides a single message-oriented interface for services, called the Normalized Message. This Normalized Message contains some header info, some properties, and XML payload, and optionally, binary attachments. It is not specific to any one protocol – in other words, it’s not SOAP, it’s not REST, it’s not JMS, it’s not SMTP, it’s not any of those.
JBI is a JSR for defining Java Business Integration, a way to cut through the complexity of different types of communications mechanisms for component message-passing (e.g. things such as REST, JMS, SOAP, RPC, email, FTP, HTTP, file system, and so on).
ServiceMix is one of several choices – once we have services written to the JBI standard, we can deploy them in any JBI-compliant ESB. Glassfish’s OpenESB is another option, for example.
Instead of worrying about the plumbing of the specific protocol we want to use, we can concentrate on writing our business logic, then rely on the ESB to “wire up” the messages between our service-providing components – whether they’re local (e.g. running in the same ESB, in which case it’s a simple in-memory message), or distributed, on another box in our cluster, or halfway around the world. The ESB provides adapters for each of the different protocols – so we can take our one service and talk to it via REST, JMS, SOAP, Email, carrier pigeon (ok, maybe not the last one – but you could write an adapter!).
This means I can write my service without even knowing what kind of protocol I’m going to be talking to it with – maybe it receives some messages via JMS, some via REST calls, a couple of SOAP services, and one in a while via an email. All that is the problem of the ESB – I just write one simple method in one simple interface to swallow the appropriate NormalizedMessage, do my processing whatever it is, and spit back out another NormalizedMessage.
This can significantly speed up the development of new services, by taking decisions about the plumbing away from the process of writing the correct business logic. We don’t even need to decide up-front if our service will be used by other services or not – we can wire it up as required.
The other important thing about a Normalized Message is that it refers to services by an identifier, but not by a specific location – in other words, a message from a client might say “I need this service to process this message”, but it’s up to the bus to figure out how to get the message to the service – this provides the opportunity to decouple services from each other. Let’s say you need to write a service that takes some kind of business message and sends an email. You don’t have to worry about passing your service information to let it find the email service at all – you just send the message to a service name (maybe “email”), and the ESB figures out the rest.
This means you can swap the email service out for another service that provides the same mechanism without worrying about the details.
JBI and OSGi Together ServiceMix is one example of such an ESB, which marries the modularization advantages of OSGi with the above-described benefits of an ESB. This means each of our components can run in it’s own classpath space, with no interference with other components – even other components that might use different versions of the same jars. How many times have you discovered you’ve got 3 different versions of log4j on your classpath? This can lead to all sorts of weird and wonderful problems that only occur in certain circumstances, and are all-but-impossible to fix. By providing true modularization, OSGi solves this problem properly. Other solutions that I’ve seen applied in the past lead directly to the quote about every complex system having a half-baked OSGi implementation inside them
ServiceMix also provides a whack of existing components in two different JBI flavors: Service Engines and Binding Components. Services Engines are the ones that do the actual business logic, and Binding Components are the adapters, the pieces that route messages to and from various protocols. Many common tasks can be achieved by configuring the existing pieces, without writing a line of code.
When it is necessary to write some code, ServiceMix includes adapters to make that even easier as well – for instance, it provides a Service Engine to allow any POJO (plain old java object) to be used as a service, without that object having to actually implements the interface for handling NormalizedMessages directly. It doesn’t get any easier than that to write a service – just write the bean, plug in a bit of configuration, and you’re done – instance REST (JMS, email, SOAP, etc etc) service!
Spring integration is built into ServiceMix, so SE’s can have their dependencies injected automagically on deployment.
SE’s can be hot-deployed and hot-removed. Multiple versions of a single SE can be running without conflict, so “hot” upgrades can be done easily. You can have one version of a service that requires version 1.1 of another service running at the same time as some other service that requires 1.2 of the same service. This is flexibility in deployment, as it means that there’s no need to “drag along” other services when upgrading if you don’t want/need to.
Services can easily be managed and monitored via the administrative capabilities of the bus.
Binding Components Binding components are how we talk outside the backbone – they take messages from the backbone and transmit or receive via an external protocol to non-ESB services – e.g. via REST, JMS, HTTP, file system, etc etc. There are dozens of existing binding components to support just about every protocol we’d care about.
Of course, all this power comes with a price: you have to learn to manage and deploy your ESB of choice, and even the simplest ESB is still a fairly complex beast. ServiceMix is no exception. The good news, however, is that it’s possible to pretty much ignore much of the available complexity in order to get started small, then learn more as you need it to start to leverage the power available.
A caveat, however: It’s important to use an ESB the way it’s intended, and not try to shoehorn things that don’t fit into it’s structure. If you find yourself struggling to write services, or having to write a lot of Binding Components, chances are you’re making inappropriate design decisions, or that you haven’t separated the concerns of a Service Engine from a Binding Component fully. This is not uncommon, as in many environments these two concerns are handled by a single component. If you’re using to writing REST services, for instance, with things such as JRA or Jersey, you’ll find it very odd to separate the processing from the “presentation” (even when that presentation is simply into XML or JSON to the REST client).
Once this technique becomes second nature, however, the true power of an ESB becomes clearer.
A whole fleet of buses… Multiple ESB instances can be deployed and clustered, providing highly scalable and fault-tolerant system. The communication between ESB instances is handled entirely by the ESB itself – nothing about our components needs to be aware that they’re working in a clustered environment.
From my latest look at ServiceMix and it’s new release, I suspect I’ll be taking a deeper dive in the near future.
(Thanks to Craig Walls for pointing out that excellent quotation – and for all his help in understanding OSGi!)
I’ve blogged a few times about how Maven and it’s associated tools and plugins is much more than a build tool, it’s a project information and management framework, so it’s no secret that I’m a fan.
One of the lesser-known things about Maven’s project management abilities is in it’s release plugin – the ability for Maven to co-ordinate and manage your release process in a reliable, simple, and fully-automated way. That’s what I’d like to explore here.
If we’re developing in an environment that supports a fully deterministic build process, including dependencies (binary and source), then we need to be able to version all our build artifacts, whether they are jar files, war files, or any other kind of file. During the development process, we need to be able to assemble applications quickly without compiling any more than we need to, and without being forced to release modules that are still moving targets. This is accomplished in Maven by use of the “SNAPSHOT” versions of modules. A module, let’s say “app”, that produces a jar file, is at any point at some specific version, let’s say “1.1″. Once we create the artifact for 1.1, our next creation of that jar must not re-use 1.1, it must be something else, as changes are incorporated.
If we’re not ready to release 1.2 (and we probably aren’t if we just released 1.1, we need an “intermediary” between 1.1 and 1.2. This is 1.2-SNAPSHOT. By seeing the “SNAPSHOT” we know we’re dealing with a version that may and probably will change. Internally, Maven translates the “-SNAPSHOT” to a date/timestamp and serial-number combination that allows you to track quite precisely each SNAPSHOT version as it changes, if you want, but generally you just want “the latest” (like HEAD from Subversion), and this is just called “SNAPSHOT”.
When we want to release a new stable version, however, we want to reverse this process – we need to produce a new non-SNAPSHOT of our artifact, then immediately switch to the next SNAPSHOT version so that development can continue without interruption. In the case of our example, we’re going to produce app-1.2.jar, then immediately begin working on 1.3-SNAPSHOT.
During development, we may also want to specify our dependencies as SNAPSHOT versions as well, so if we have a dependency that is also in development, we can work on “the latest” version as well. Once we’re ready to release, though, this changes – we want only stable and reproducible code in our release, so we need to “resolve” all SNAPSHOT dependencies to a specific version, then we can switch our own module to a release version, probably tag the code at that point in SVN, and create the releaseable artifact. We probably also want to deploy that artifact to a staging area, ready to be deployed into our production environment.
Maven’s release plugin does all of this for us, and more, in a reliable and fail-safe way.
Run in two phases, the plugin’s goal “prepare” does all of the verification work for us. It:
The goal “perform” actually performs the release, doing all the steps required to produce and publish a versioned artifact to our staging area (often a system such as Nexus), where it can be accessed as required to deploy to other environments.
The perform process:
There are other goals for recovering a failed release, doing “dry runs” of a deploy without actually changing anything, and even moving the deployed artifact into the target environment.
So why might you choose Maven’s deployment process over a custom-built scripted process?
There’s a few things you might consider when making such a choice:
In short, rolling your own process for deployment is a much more expensive and risky proposition than using a reliable and well-established tool such as Maven to do it for you.
I wanted to pen (sic) a few words today in praise of a piece of OSS software I use a lot: http://synergy2.sourceforge.net/.
For anyone using more than one machine in their day-to-day efforts of churning bytes into software, this is Good Stuff ™.
In a nutshell, it lets you take a single keyboard and mouse-like-thing (in my case, a Kensington trackball) and “share” them across multiple boxen, but with a twist: It also lets you associate the monitors of several boxen together to make the collective set look like one big system.
For instance: I sit here in front of (or more like “within”) six monitors, of various types and resolutions. I have my one keyboard (a genuine antique IBM model M of which I am inordinately proud) and trackball, and can take my cursor with a flick of the wrist from my MacBook Pro’s built-in monitor on the left and whisk it across the two monitors of my Sun Ultra40 in the middle to stop on the X11 window of the SuSE machine on my far right! I can then use the browser on the SuSE box to look something up, copy a URL, whip it back to the right-hand monitor of my Mac and paste it in. This is cool, especially once you get used to it.
At first it threatens to make your head explode, especially when you try to drag a window from OS X to Solaris (which it can’t do), until it becomes second nature.
Not without it’s minor bugs, it crashes once in a long while – but that just serves to highlight how dependent on it I am, as I sit there stunned for a moment hammering my mouse cursor on the left side of the Sun’s monitor wondering why it won’t move to the next system
If you’re more adventurous than I you can even “stack” monitors veritically ( like this) until you’re surrounded even further, ala the Lawnmower Man, perhaps.
Good stuff – I recommend it.