Juraj Blahunka

A Java enthusiast

© 2014. Juraj Blahunka All rights reserved.

Inject JBoss 7 system properties into your Java EE application

How do you make your Java EE application configurable? Do you use Maven profiles? Properties file? Environment properties? If you have developed with JBoss 7 before, you have probably already heard about JBoss 7 System Properties.

They are usually specified in configuration file of mode specific directory, for example standalone, they are persistent (live through server restarts) and can be configured, most usually via jboss-cli.

One of the great things about Java EE application development is its flexibility. Why not use this flexibility to inject these properties into runtime?

In following lines you will see:

CDI annotations to the rescue

First, we need to define, how would our default access pattern look. Let's leverage the @Inject annotation with a custom @Qualifier:

@Inject
@SystemProperty("example.foo")
String foo;

Now, let's define the @SystemProperty annotation:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
public @interface SystemProperty {

    /**
    * Full name of the system property, for example "user.home"
    */
    @Nonbinding String value();

}

Note, that we do not define default "" next to our value(), since the property name should be always defined. Therefore we automatically disallow usage of empty system property @SystemProperty().

And how will the System property get from JBoss to our little @SystemProperty annotated variable? Let's define a provider, who uses the @Produces annotation and provides our application with concrete system properties:

public class SystemPropertyProvider {

    @Produces
    @SystemProperty("")
    String findProperty(InjectionPoint ip) {
        SystemProperty annotation = ip.getAnnotated()
            .getAnnotation(SystemProperty.class);

        String name = annotation.value();
        String found = System.getProperty(name);
        if (found == null) {
            throw new IllegalStateException("System property '" + name + "' is not defined!");
        }
        return found;
    }

}

Demonstration

After we have defined our deliver mechanism, we probably want to use our new @SystemProperty annotation. Let's define an example REST resource:

@Path("example")
public class ExampleResource {

    @Inject
    @SystemProperty("example.foo")
    String foo;

    @Inject
    @SystemProperty("example.bar")
    String bar;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String printSomeSystemProperties() {
        return "foo=" + foo + ", bar=" + bar;
    }

}

Deploy to JBoss 7 and hit http://localhost:8080/inject-jboss-system-properties/example. But what happened? We are getting an exception:

java.lang.IllegalStateException: System property 'example.foo' is not defined!
    sk.blahunka.jbossinject.properties.SystemPropertyProvider.findProperty(SystemPropertyProvider.java:15)

We forgot about our properties, to define them, we will use the good old jboss-cli. On windows, fire up the jboss-cli.bat executable and type in:

connect

/system-property=example.foo:add(value="Special Foo Value")
/system-property=example.bar:add(value="Why is Foo so special?")

Then hit refresh in your browser and voila, our properties were injected:

foo=Special Foo Value, bar=Why is Foo so special?

You can fork the inject-jboss-system-properties project on GitHub.