ModeShape

An open-source, federated content repository

JBoss DNA, a unified repository

DZone has posted an interview with Sacha Labourey, CTO of Red Hat Middlware, in which he discusses the upcoming JBoss AS 5 and some of the new and updated JBoss enterprise services. He mentions JBoss DNA and the importance and benefits of having a unified repository, starting with changes in JBoss AS 5:

“We have completely decoupled the metadata management from the application server. It’s something we call the profile service, and this profile service, as you can imagine, is fully pluggable. It could be simply a set of files, it can be a database, it can be a JCR repository. And the idea here is to end up with a unified way to store metadata for one node or a cluster or a farm of JBoss instances, and very quickly provision new instances.”

Having a unified repository not only provides a better way to manage configuration information, but it also integrates access to other systems and other information that are needed by the middleware and the business components:

“I think, in the future, it’s going to be increasingly important to further split some of the notions, which today are still linked way too much as part of a monolithic entity. I think, metadata is something that will be very important. What I call metadata, you know, it’s a non-fancy name to describe everything that is being done in the various repositories out there.

When I look at the way that you configure an operating system, or the way you populate an LDAP tree, the way you get access to the topology of your network, everything you need to manage; when I look at the configuration of an application server on ESB, or when I look at the various steps which need to go in an application before being validated and being able to go to production, all of that is just metadata, whatever fancy name you want to put on that.

Being able to extract all of that information as part of a unified metadata repository, I think is going to be a great step forward to enable the kind of provisioning we will need in the next years. Today, I think, we go through way too many ad hoc and manual processes to get there. We’re not going to get the kind of economy of scale by doing so. We need to radically go to another level.”

This gets to the heart of why a unified repository is needed, and why we’re trying to crack that nut with JBoss DNA. There are too many places where metadata exists to use one-off and ad hoc ways to get at that information. And since that information changes all the time, you can’t suck it into a monolythic repository – you have to provide real-time access, which is exactly what we’re doing with JBoss DNA federation: use JCR to access to the wealth of metadata and content from all kinds of systems. But more on that in a future post.

I’ve just touched on the aspects of Sacha’s interview that related to JBoss DNA. If you have some time, watch the interview to get the whole JBoss middleware picture.

Advertisements

Filed under: features, federation, jcr, repository

To check or not to check (parameters) – Part Deux

In one of my recent posts, I talked about checking method parameters using a utility that throws IllegalArgumentException when a parameter was deemed invalid. The whole point of this check is to prevent a more convoluted exception from certainly happening later on, and using the IllegalArgumentException to give the developer some useful message about what’s allowed or not allowed.

The post generated some good comments. For example, my post didn’t really make too clear that checking method parameters is not a replacement for checking the validity of input data (e.g., data provided by a user, say via a form, or data provided to a database). There are a lot of neat frameworks for doing that, including Commons Validator and Hibernate Validator to name two.

I wanted to follow up on my previous discussion, though, and discuss checking method parameters using Java assertions. In general, this is a bad idea. For one thing, checking arguments with a static utility method (e.g., ArgCheck.isNotNull(...)) should be very fast. Second, assertions can be disabled, and doing so shouldn’t change the behavior of the code. (This is why I’d argue that continuous integration should be run with and without assertions.)

The major requirement for using assert is that removing the assertion should not change the flow of the code – called control flow invariance. This means that using assert for checking parameters

Filed under: techniques

Internationalization in JBoss DNA

It’s pretty important to be able to create applications that support multiple languages, and most libraries should provide some kind of support for this. The first step is making your code support internationalization, but then you need to localize the application for each language (or locale). We’ve included internationalization (or “i18n”) in JBoss DNA from the beginning, but we haven’t done much with localization (or “L10n”), and have only one (default) localization in English.

Java really does a crappy job at supporting internationalization. Sure, it has great Unicode support, and it does provide a standard mechanism for identifying locales and looking up bundles given a locale. But where is the standard approach for representing an internationalized message ready for localization into any locale? ResourceBundle.getString()? Seriously?

What I want is something analogous to an internationalized String capable of holding onto the replacement parameters. Each internationalized string should be associated with the key used in the resource bundles. I want to localize an internationalized string into the default locale, or into whatever locale you supply, and even into multiple locales (after all, web applications don’t support just one locale). And I should be able to use my IDE to find where each internationalized string is used. I should be able to test that my localization files contain localized messages for each of the internationalized strings used in the code, and that there are no duplicate or obsolete entries in the files. I also don’t want that many resource files (one per package – like Eclipse used to do – sucks); one per Maven project is just about right.

I’m not asking for much.

Meet the players

There are quite a few existing internationalization (aka, “i18n”) open source libraries, including JI18n, J18n, Apache Commons I18n, just to name a few. Too many of these try to be too smart and do too much. (Like automatically localizing a message identified by a Java annotation into the current locale, or using aspects to do things automatically.) This stuff just tends to confuse IDE dependency, search, and/or debuggers. We found nothing we liked, and lots of things we didn’t like. Internationalization shouldn’t be this hard.

Sweet and to the point
So we did what we don’t like to do: we invented our own very simple framework. And by simple, I mean there’s only one I18n class that represents an internationalized string with some static utility methods (and an abstract JUnit test class; see below). To use, simply create an “internationalization class” that contains a static I18n instances for the messages in a bundle, and then create a resource bundle properties file for each of these classes. That’s it!

So, let’s assume that we have a Maven project and we want to create an internationalization class that represents the internationalized strings for that project. (We could create as many as we want, but one is the simplest.) Here’s the code:

public final class DnaSubprojectI18n {

// These are the internationalized strings ...
public static I18n propertyIsRequired;
public static I18n nodeDoesNotExistAtPath;
public static I18n errorRemovingNodeFromCache;

static {
// Initializes the I18n instances
try {
I18n.initialize(DnaSubprojectI18n.class);
} catch (final Exception err) {
System.err.println(err); // logging depends on I18n, so we can't log
}
}
}

Notice that we have a static I18n instance for each of our internationalized strings. The name of each I18n variable corresponds to the key in the corresponding property file. Pretty simple boilerplate code.

The actual localized messages are kept same package as this class, but since we’re using Maven the file goes in src/main/resources):

  propertyIsRequired = The {0} property is required but has no value
nodeDoesNotExistAtPath = No node exists at {0} (or below {1})
errorRemovingNodeFromCache = Error while removing {0} from cache

Again, pretty simple and nothing new.

Using in your code
At this point, all we’ve done is defined a bunch of internationalized strings. Now all we need to do to use an internationalized string is to reference the I18n instance you want (e.g., DnaSubprojectI18n.propertyIsRequired). Pass it (and any parameter values) around. And when you’re ready, localize the message by calling I18n.text(Object...params) or I18n.text(Locale locale, Object...params). The beauty of this approach is that IDE’s love it. Want to know where an internationalized message is used? Go to the static I18n member and find where it’s used.

The logging framework used in JBoss DNA has methods that take an I18n instance and zero or more parameters. (Debug and trace methods just take String, since in order to understand these messages you really have to have access to the code, so English messages are sufficient.) This static typing helps make sure that all the developers internationalize where they’re supposed to.

With exceptions, we’ve chosen to have our exceptions use Strings (just like JDK exceptions), so we simply call the I18n.text(Object...params) method:

  throw new RepositoryException(DnaSubprojectI18n.propertyIsRequired.text(path));

We’ll probably make this even easier by adding constructors that take the I18n instance and the parameters, saving a little bit of typing and delaying localization until it’s actually needed.

Testing localizations
Testing your internationalization classes is equally simple. Create a JUnit test class and subclass the AbstractI18nTest class, passing to its constructor your DnaSubprojectI18n class reference:

public class DnaSubprojectI18nTest extends AbstractI18nTest {
public DnaSubprojectI18nTest() {
super(DnaSubprojectI18n.class);
}
}

That’s it. The test class inherits test methods that compare the messages in the properties file with the I18n instances in the class, ensuring there aren’t any extra or missing messages in any of the localization files. That’s a huge benefit!

One more thing …
Remember when I said there was only one class to our framework? Okay, I stretched the truth a bit. We also abstracted how the framework loads the localized messages, so there’s an interface and an implementation class that loads from standard resource bundle property files. So if you want to use a different loading mechanism for your localized messages, feel free.

Props to John Verhaeg and Dan Florian for the design of this simple but really powerful framework.

Filed under: techniques, testing, tools

Mockito 1.5

Mockito 1.5 has been released with several nice enhancements. Perhaps one of the most useful is the ability to spy on non-mock objects. In other words, you can verify that methods are called on the non-mock object. So, for example (from the release notes):

   List list = new LinkedList();
   List spy = spy(list);

   //wow, I can stub it!
   stub(spy.size()).toReturn(100);

   //wow, I can use it and add real elements to the list!
   spy.add("one");

   //wow, I can verify it!
   verify(spy).add("one);

I haven’t wanted to do this too often, but there was an occasion or two.

Another improvement is supposed to result in more readable code. Instead of

   stub(obj.someMethod()).toReturn(result);

it is now possible to write:

   doReturn(result).when(obj).someMethod();

Notice that the code is exactly the same length, so it’s clearly up to you whether you think it’s more or less readable. In addition to doReturn(), there’s also doThrow(), doAnswer(), and doNothing().

Check out the Mockito documentation for examples and details on how to use.

Filed under: techniques, testing, tools

To check or not to check (parameters)?

Some topics in software development are all about preferences and personal choices, and so it is with checking method parameters. When is it worth the extra developer time and execution time to check that the parameters of a method adhere to the expectations of the implementation?

What would you want to happen if you passed in a bad value to a method in some library? Would you want some cryptic exception thrown from the bowels of the library? No, chances are you’d rather get an immediate IllegalArgumentException telling you why your value is bad. Plus, you’d like to read in the JavaDocs what is considered a good (or bad) value for each parameter, and what happens when bad values are used.

Not all code has the luxury of a well-defined public API, where developers can focus on providing meaningful messages and documentation for a limited set of “public” methods. Open source libraries rarely have much control over what classes can be used. And maybe we don’t have to document much at all – can’t the developer using the library just look at the source?

My view is that developers should spend a little extra time to make life easier for their customers. This means good documentation and meaningful parameter checks for (most) methods that will or are likely to be used by clients. If you don’t make your source available to your customers, then your documentation probably needs to be “great”, not just “good”.

So what do we do on JBoss DNA? Well, we don’t really have a well-defined “public API” – we want our customers and users to be able to use JBoss DNA in ways that make sense for them, and that may include extending the behavior by writing a new implementation of an interface, using a small component by itself. In short, they’ll probably use our software in ways we don’t anticipate. Our philosophy is to try to be as helpful as possible, because a little bit of work on our part can make it a lot easier for our customers. So most of the time we’ll check the parameters, but in times where we don’t (because of performance, because a method is protected or private, or because there’s a good reason not to) we’ll still document what the method expects.

To make our lives easier, we’ve created a utility to help us to write simple and readable code that checks parameter values and throws meaningful exceptions when a value isn’t valid. Since JBoss DNA is internationalized, all exception messages should be internationalized, and this utility does this, too. So, we can write code like this:

    /**
     * Set the configuration for this component.
     * @param config the new configuration
     * @throws IllegalArgumentException if <code>config</code> is null
     */
    public void setConfiguration( Configuration config ) {
        ArgCheck.isNotNull(config, "config");
        ...
    }

This trivial example shows a couple of things. First, the call to ArgCheck.isNotNull is pretty readable. (In hindsight, CheckArg.isNotNull(config,"config") may have been a better choice. There are other patterns that are even more readable, but then you start trading off performance for readability.) Other examples of ArgCheck methods include isPositive, isNotEmpty, hasSizeOfAtLeast, isGreaterThan, and containsNoNulls. Of course, there are many more.

Second, the ArgCheck methods will internationalize the exception message, so we pass the variable name (which should match the JavaDoc) as the second parameter to isNotNull(...) so that the exception message is meaningful. In this case, the English localization for the message would be “The config parameter may not be null”.

Third, the JavaDoc uses @throws to document the condition when an IllegalArgumentException will be thrown, and we chosen to not duplicate that in the corresponding @param. (Then, in cases where we don’t check the parameter, we don’t put a @throws and we do put the assumption in the @param. For example, “@param config the new configuration; may not be null.“)

When do we not use ArgCheck? We don’t often check parameters in protected methods, since we often have much more control over how the methods are called. And we never need to check parameters of private methods. And some public methods are called so frequently that even the overhead of checking the arguments is not worth it, but in these cases we also try to explicitly say this in the methods’ JavaDoc.

So, in general, we check a lot of our method parameters. What do you do?

Filed under: techniques

Capture thread-safety intent via annotations

Alex points out the difficulties of knowing whether a class can be used within a concurrent manner, and what we as developers can do when designing and documenting code for thread safety.

I whole heartedly agree with his suggestion to use JCIP annotations. We use them on the JBoss DNA project, and several of us have commented that using the annotations helped us think more about the thread-safety of the code we’re writing.

This, I think, is yet another benefit of using JCIP annotations: they help you better code because they’re a constant reminder of what you intend for the class’ behavior in a concurrent world.
After all, nobody likes those nasty Schroedinbugs and Heisenbugs.

Filed under: techniques

ModeShape is

a lightweight, fast, pluggable, open-source JCR repository that federates and unifies content from multiple systems, including files systems, databases, data grids, other repositories, etc.

Use the JCR API to access the information you already have, or use it like a conventional JCR system (just with more ways to persist your content).

ModeShape used to be 'JBoss DNA'. It's the same project, same community, same license, and same software.

ModeShape

Topics