mscharhag, Programming and Stuff;

A blog about programming and software development topics, mostly focused on Java technologies including Java EE, Spring and Grails.

  • Friday, 6 February, 2015

    Creating Android Apps with Groovy 2.4

    A few days ago Groovy 2.4 was released. One of the major news is that Groovy now officially supports Android application development. To see how this works I used Groovy to create a small ToDo list example application for Android. In this post I will show which steps are required to create an Android application with Groovy and how Groovy can simplify Android application development.

    The following screen shows the example application written in Groovy. You can find the full source code on GitHub.
     

    Groovy app screenshot

     

    Running Groovy on Android

    First we need Android Studio which already contains the latest Version of the Android SDK. Over last year the default Android environment changed from Eclipse and Ant to Android Studio (build on IntelliJ) and Gradle. To run Groovy on Android we will need a Gradle Plugin, so make sure you are not using the old Eclipse/Ant based development tools.

    We create a new Android project in Android Studio and add the following lines to our build files:

    Top level build file (<project>/build.gradle):

    buildscript {
      ..
      dependencies {
        ..
        classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.5'
      }
    }


    App build file (<project>/app/build.gradle):

    apply plugin: 'com.android.application'
    
    // apply Groovy Android plugin after the standard Android plugin
    apply plugin: 'groovyx.grooid.groovy-android'
    
    dependencies {
      ..
      compile 'org.codehaus.groovy:groovy:2.4.0:grooid'
    }

    Source and documentation of the Groovy Android Gradle Plugin can be found on GitHub.

    This is all configuration we need, now we can move straight to Groovy code.

    Please note that Groovy code files need to be placed in src/main/groovy instead of src/main/java. Adding Groovy files to src/main/java will not work!

    Developing Android apps in Groovy works exactly the same way as in Java. Because of Groovy's  Java interoperability, you can use and extend Android classes like you would do in Java.

    Improving the Groovy experience in Android Studio

    Android Studio already contains the Groovy plugin. So, you get Groovy syntax support out of the box.

    However, you might miss the option to create new Groovy classes from the context menu. Luckily this can be easily configured in Android Studio. You simply have to create a new File Template (Settings > File and code templates) and add the following template code:

    #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
    class ${NAME} {
    }

     

    androidstudio groovy file template setup (1)


    Now you can quickly create new Groovy classes using the context menu:

    androidstudio groovy file template setup (2)


    You might also look into this plugin which fixes the issue that you get no auto completion when overriding super class methods in Groovy. Thanks to @arasthel92 who told me about this plugin.

    Running Groovy applications

    Running Groovy apps is identical to running Java apps. We can simply press the run (or debug) button in Android Studio and deploy the application to a connected (or emulated) device.
    The cool thing is that the Groovy debugger works out of the box. We can debug running Groovy applications from Android Studio.

     

    androidstudio debug groovy app


    The great parts

    The cool thing about Groovy is that it reduces the lines of code you need to write a lot. Its dynamic nature also lets you get rid of all the type casts that are typically required when working with Android.

    One example of this can be found in ToDoListActivity.onResume(). In this method the data of an Android ListAdapter is modified. With Java this would look like this:

    ArrayAdapter<ToDo> adapter = (ArrayAdapter<ToDo>) getListAdapter();
    ToDoApplication application = (ToDoApplication) getApplication()
    adapter.clear()
    adapter.addAll(application.getToDos());
    adapter.notifyDataSetChanged()

    With Groovy we can simply rewrite it like this:

    listAdapter.clear()
    listAdapter.addAll(application.toDos)
    listAdapter.notifyDataSetChanged()

    Groovy's closures are another feature that comes very handy when working with Android.

    To add a click listener to a button you write something like this in Java

    Button button = (Button) findViewById(R.id.newTodoButton);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      void onClick(View v) {
        ...
      }
    });

    With Groovy it is just

    def button = findViewById(R.id.newTodoButton)
    button.onClickListener = {
      ...
    }

    See CreateNewTodoActivity for a complete example.

    Be aware of runtime errors

    Dynamic languages typically tend to increase the number of errors you find at runtime. Depending on the app you are building this can be a serious issue. Larger Apps can have a significant deployment time (the app needs to be packaged, copied via USB to the device, installed and started on the device).
    Groovy's @CompileStatic annotation can be used to tackle this issue. It can be used to compile parts of your Groovy code statically to reduce runtime errors:

    @CompileStatic
    class ToDoListActivity extends ListActivity {
      ..
    }

    The downside of @CompileStatic is that you can (obviously) no longer use Groovy's dynamic features. 

    Quick summary

    It is very easy to get Groovy running on Android. Because of Groovy's interoperability with Java it is also very easy to mix Groovy and Java in the same application. The Groovy integration in Android Studio is actually better than I have expected (however, some manual tweaks are still required).

  • Saturday, 20 December, 2014

    Looking into Java's new Money and Currency API (JSR 354)

    JSR 354 defines a new Java API for working with Money and Currencies, which might be included in Java 9 (see comments). In this post we will look at the current state of the reference implementation: JavaMoney.

    Like my post about the Java 8 Date/Time API this post will be mainly driven by code that shows the new API.

    But before we start, I want to quote a short section from the specification that pretty much sums up the motivation for this new API:

    Monetary values are a key feature of many applications, yet the JDK provides little or no support. The existing java.util.Currency class is strictly a structure used for representing current ISO 4217 currencies, but not associated values or custom currencies. The JDK also provides no support for monetary arithmetic or currency conversion, nor for a standard value type to represent a monetary amount.

    If you use Maven, you can easily try the current state of the reference implementation by adding the following dependency to your project:

    <dependency>
      <groupId>org.javamoney</groupId>
      <artifactId>moneta</artifactId>
      <version>0.9</version>
    </dependency>

    All specification classes and interfaces are located in the javax.money.* package.
    We will start with the two core interfaces CurrencyUnit and MonetaryAmount. After that, we will look into exchange rates, currency conversion and formatting.

    CurrencyUnit and MonetaryAmount

    CurrencyUnit models a currency. CurrencyUnit is very similar to the existing java.util.Currency class, except it allows custom implementations. According to the specification it should be possible that java.util.Currency implements CurrencyUnit. CurrencyUnit instances can be obtained using the MonetaryCurrencies factory:

    // getting CurrencyUnits by currency code
    CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR");
    CurrencyUnit usDollar = MonetaryCurrencies.getCurrency("USD");
    
    // getting CurrencyUnits by locale
    CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN);
    CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);

    MontetaryAmount represents a concrete numeric representation of a monetary amount. A MonetaryAmount is always bound to a CurrencyUnit. Like CurrencyUnit, MonetaryAmount is an interface that supports different implementations. CurrencyUnit and MonetaryAmount implementations must be immutable, thread safe, serializable and comparable.

    // get MonetaryAmount from CurrencyUnit
    CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR");
    MonetaryAmount fiveEuro = Money.of(5, euro);
    
    // get MonetaryAmount from currency code
    MonetaryAmount tenUsDollar = Money.of(10, "USD");
    
    // FastMoney is an alternative MonetaryAmount factory that focuses on performance
    MonetaryAmount sevenEuro = FastMoney.of(7, euro);

    Money and FastMoney are two MonetaryAmount implementations of JavaMoney. Money is the default implementation that stores number values using BigDecimal. FastMoney is an alternative implementation which stores amounts in long fields. According to the documentation  operations on FastMoney are 10-15 times faster compared to Money. However, FastMoney is limited by the size and precision of the long type.

    Please note that Money and FastMoney are implementation specific classes (located in org.javamoney.moneta.* instead of javax.money.*). If you want to avoid implementation specific classes, you have to obtain a MonetaryAmountFactory to create a MonetaryAmount instance:

    MonetaryAmount specAmount = MonetaryAmounts.getDefaultAmountFactory()
        .setNumber(123.45)
        .setCurrency("USD")
        .create();

    Two MontetaryAmount instances are considered equal if the implementation classes, the currency units and the numeric values are equal:

    MonetaryAmount oneEuro = Money.of(1, MonetaryCurrencies.getCurrency("EUR"));
    boolean isEqual = oneEuro.equals(Money.of(1, "EUR")); // true
    boolean isEqualFast = oneEuro.equals(FastMoney.of(1, "EUR")); // false

    MonetaryAmount has various methods that allow accessing the assigned currency, the numeric amount, its precision and more:

    MonetaryAmount monetaryAmount = Money.of(123.45, euro);
    CurrencyUnit currency = monetaryAmount.getCurrency();
    NumberValue numberValue = monetaryAmount.getNumber();
    
    int intValue = numberValue.intValue(); // 123
    double doubleValue = numberValue.doubleValue(); // 123.45
    long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100
    long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45
    int precision = numberValue.getPrecision(); // 5
    
    // NumberValue extends java.lang.Number. 
    // So we assign numberValue to a variable of type Number
    Number number = numberValue;

    Working with MonetaryAmounts

    Mathematical operations can be performed with MonetaryAmount:

    MonetaryAmount twelveEuro = fiveEuro.add(sevenEuro); // "EUR 12"
    MonetaryAmount twoEuro = sevenEuro.subtract(fiveEuro); // "EUR 2"
    MonetaryAmount sevenPointFiveEuro = fiveEuro.multiply(1.5); // "EUR 7.5"
    
    // MonetaryAmount can have a negative NumberValue
    MonetaryAmount minusTwoEuro = fiveEuro.subtract(sevenEuro); // "EUR -2"
    
    // some useful utility methods
    boolean greaterThan = sevenEuro.isGreaterThan(fiveEuro); // true
    boolean positive = sevenEuro.isPositive(); // true
    boolean zero = sevenEuro.isZero(); // false
    
    // Note that MonetaryAmounts need to have the same CurrencyUnit to do mathematical operations
    // this fails with: javax.money.MonetaryException: Currency mismatch: EUR/USD
    fiveEuro.add(tenUsDollar);

    Rounding is another important part when working with money. MonetaryAmounts can be rounded using a rounding operator:

    CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD");
    MonetaryAmount dollars = Money.of(12.34567, usd);
    MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd);
    MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35

    Here 12.3456 US Dollars are rounded with the default rounding for this currency.

    When working with collections of MonetaryAmounts, some nice utility methods for filtering, sorting and grouping are available. These methods can be used together with the Java 8 Stream API.

    Consider the following collection:

    List<MonetaryAmount> amounts = new ArrayList<>();
    amounts.add(Money.of(2, "EUR"));
    amounts.add(Money.of(42, "USD"));
    amounts.add(Money.of(7, "USD"));
    amounts.add(Money.of(13.37, "JPY"));
    amounts.add(Money.of(18, "USD"));

    We can now filter amounts by CurrencyUnit:

    CurrencyUnit yen = MonetaryCurrencies.getCurrency("JPY");
    CurrencyUnit dollar = MonetaryCurrencies.getCurrency("USD");
    
    // filter by currency, get only dollars
    // result is [USD 18, USD 7, USD 42]
    List<MonetaryAmount> onlyDollar = amounts.stream()
        .filter(MonetaryFunctions.isCurrency(dollar))
        .collect(Collectors.toList());
    
    // filter by currency, get only dollars and yen
    // [USD 18, USD 7, JPY 13.37, USD 42]
    List<MonetaryAmount> onlyDollarAndYen = amounts.stream()
        .filter(MonetaryFunctions.isCurrency(dollar, yen))
        .collect(Collectors.toList());

    We can also filter out MonetaryAmounts smaller or greater than a specific threshold:

    MonetaryAmount tenDollar = Money.of(10, dollar);
    
    // [USD 42, USD 18]
    List<MonetaryAmount> greaterThanTenDollar = amounts.stream()
        .filter(MonetaryFunctions.isCurrency(dollar))
        .filter(MonetaryFunctions.isGreaterThan(tenDollar))
        .collect(Collectors.toList());

    Sorting works in a similar way:

    // Sorting dollar values by number value
    // [USD 7, USD 18, USD 42]
    List<MonetaryAmount> sortedByAmount = onlyDollar.stream()
        .sorted(MonetaryFunctions.sortNumber())
        .collect(Collectors.toList());
    
    // Sorting by CurrencyUnit
    // [EUR 2, JPY 13.37, USD 42, USD 7, USD 18]
    List<MonetaryAmount> sortedByCurrencyUnit = amounts.stream()
        .sorted(MonetaryFunctions.sortCurrencyUnit())
        .collect(Collectors.toList());

    Grouping functions:

    // Grouping by CurrencyUnit
    // {USD=[USD 42, USD 7, USD 18], EUR=[EUR 2], JPY=[JPY 13.37]}
    Map<CurrencyUnit, List<MonetaryAmount>> groupedByCurrency = amounts.stream()
        .collect(MonetaryFunctions.groupByCurrencyUnit());
    
    // Grouping by summarizing MonetaryAmounts
    Map<CurrencyUnit, MonetarySummaryStatistics> summary = amounts.stream()
        .collect(MonetaryFunctions.groupBySummarizingMonetary()).get();
    
    // get summary for CurrencyUnit USD
    MonetarySummaryStatistics dollarSummary = summary.get(dollar);
    MonetaryAmount average = dollarSummary.getAverage(); // "USD 22.333333333333333333.."
    MonetaryAmount min = dollarSummary.getMin(); // "USD 7"
    MonetaryAmount max = dollarSummary.getMax(); // "USD 42"
    MonetaryAmount sum = dollarSummary.getSum(); // "USD 67"
    long count = dollarSummary.getCount(); // 3

    MonetaryFunctions also provides reduction function that can be used to obtain the max, min and sum of a MonetaryAmount collection:

    List<MonetaryAmount> amounts = new ArrayList<>();
    amounts.add(Money.of(10, "EUR"));
    amounts.add(Money.of(7.5, "EUR"));
    amounts.add(Money.of(12, "EUR"));
    
    Optional<MonetaryAmount> max = amounts.stream().reduce(MonetaryFunctions.max()); // "EUR 7.5"
    Optional<MonetaryAmount> min = amounts.stream().reduce(MonetaryFunctions.min()); // "EUR 12"
    Optional<MonetaryAmount> sum = amounts.stream().reduce(MonetaryFunctions.sum()); // "EUR 29.5"

    Custom MonetaryAmount operations

    MonetaryAmount provides a nice extension point called MonetaryOperator. MonetaryOperator is a functional interface that takes a MonetaryAmount as input and creates a new MonetaryAmount based on the input.

    // A monetary operator that returns 10% of the input MonetaryAmount
    // Implemented using Java 8 Lambdas
    MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {
      BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);
      BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));
      return Money.of(tenPercent, amount.getCurrency());
    };
    
    MonetaryAmount dollars = Money.of(12.34567, "USD");
    
    // apply tenPercentOperator to MonetaryAmount
    MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567

    Some standard API features are implemented as MonetaryOperator. For example, the rounding features we saw above are implemented as MonetaryOperator.

    Exchange rates

    Currency exchange rates can be obtained using an ExchangeRateProvider. JavaMoney comes with multiple different ExchangeRateProvider implementations. The two most important implementations are ECBCurrentRateProvider and IMFRateProvider. ECBCurrentRateProvider queries the European Central Bank (ECB) data feed for getting current exchange rates while IMFRateProvider uses International Monetary Fund (IMF) conversion rates.

    // get the default ExchangeRateProvider (CompoundRateProvider)
    ExchangeRateProvider exchangeRateProvider = MonetaryConversions.getExchangeRateProvider();
    
    // get the names of the default provider chain
    // [IDENT, ECB, IMF, ECB-HIST]
    List<String> defaultProviderChain = MonetaryConversions.getDefaultProviderChain();
    
    // get a specific ExchangeRateProvider (here ECB)
    ExchangeRateProvider ecbExchangeRateProvider = MonetaryConversions.getExchangeRateProvider("ECB");

    If no specific ExchangeRateProvider is requested a CompoundRateProvider will be returned. CompoundRateProvider delegates exchange rate requests to a chain of ExchangeRateProviders and returns the result from the first provider that returns an adequate result.

    // get the exchange rate from euro to us dollar
    ExchangeRate rate = exchangeRateProvider.getExchangeRate("EUR", "USD");
    
    NumberValue factor = rate.getFactor(); // 1.2537 (at time writing)
    CurrencyUnit baseCurrency = rate.getBaseCurrency(); // EUR
    CurrencyUnit targetCurrency = rate.getCurrency(); // USD

    Currency conversion

    Conversion between currencies is be done with CurrencyConversions that can be obtained from ExchangeRateProviders:

    // get the CurrencyConversion from the default provider chain
    CurrencyConversion dollarConversion = MonetaryConversions.getConversion("USD");
    
    // get the CurrencyConversion from a specific provider
    CurrencyConversion ecbDollarConversion = ecbExchangeRateProvider.getCurrencyConversion("USD");
    
    MonetaryAmount tenEuro = Money.of(10, "EUR");
    
    // convert 10 euro to us dollar 
    MonetaryAmount inDollar = tenEuro.with(dollarConversion); // "USD 12.537" (at the time writing)

    Note that CurrencyConversion implements MonetaryOperator. Like other operators it can be applied using MonetaryAmount.with().

    Formatting and parsing monetary amounts

    MonetaryAmounts can be parsed/formatted from/to string using a MonetaryAmountFormat:

    // formatting by locale specific formats
    MonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMANY);
    MonetaryAmountFormat usFormat = MonetaryFormats.getAmountFormat(Locale.CANADA);
    
    MonetaryAmount amount = Money.of(12345.67, "USD");
    
    String usFormatted = usFormat.format(amount); // "USD12,345.67"
    String germanFormatted = germanFormat.format(amount); // 12.345,67 USD
    
    // A MonetaryAmountFormat can also be used to parse MonetaryAmounts from strings
    MonetaryAmount parsed = germanFormat.parse("12,4 USD");

    With AmountFormatQueryBuilder custom formats can be created:

    // Creating a custom MonetaryAmountFormat
    MonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat(
        AmountFormatQueryBuilder.of(Locale.US)
            .set(CurrencyStyle.NAME)
            .set("pattern", "00,00,00,00.00 ¤")
            .build());
    
    // results in "00,01,23,45.67 US Dollar"
    String formatted = customFormat.format(amount);

    Note that the ¤ symbol (\u00A) is used as currency placeholder inside the pattern string.

    Summary

    We looked at many parts of the new Money and Currency API. The implementation already looks quite solid (but definitely needs some more documentation). I hope we will see this API included in Java 9 :-)

    You can find all the examples shown here on GitHub.

  • Monday, 10 November, 2014

    Injecting domain objects instead of infrastructure components

    Dependency Injection is a widely used software design pattern in Java (and many other programming languages) that is used to achieve Inversion of Control. It promotes reusability, testability, maintainability and helps building loosely coupled components. Dependency Injection is the de facto standard to wire Java objects together, these days.
    Various Java Frameworks like Spring or Guice can help implementing Dependency Injection. Since Java EE 6 there is also an official Java EE API for Dependency Injection available: Contexts and Dependency Injection (CDI).

    We use Dependency Injection to inject services, repositories, domain related components, resources or configuration values. However, in my experience, it is often overlooked that Dependency Injection can also be used to inject domain objects.

    A typical example of this, is the way the currently logged in user is obtained in Java many applications. Usually we end up asking some component or service for the logged in user.
    The code for this might look somehow like the following snippet:

    public class SomeComponent {
    
      @Inject
      private AuthService authService;
      
      public void workWithUser() {
        User loggedInUser = authService.getLoggedInUser();
        // do something with loggedInUser
      }
    }

    Here a AuthService instance is injected into SomeComponent. Methods of SomeComponent now use the AuthService object to obtain an instance of the logged in user.

    However, instead of injecting AuthService we could inject the logged in user directly into SomeComponent.
    This could look like this:

    public class SomeComponent {
    
      @Inject
      @LoggedInUser
      private User loggedInUser;
      
      public void workWithUser() {
        // do something with loggedInUser
      }
    }

    Here the User object is directly injected into SomeComponent and no instance of AuthService is required. The custom annotation @LoggedInUser is used to avoid conflicts if more than one (managed) bean of type User exist.

    Both, Spring and CDI are capable of this type of injection (and the configuration is actually very similar). In the following section we will see how domain objects can be injected using Spring. After this, I will describe what changes are necessary to do the same with CDI.

    Domain object injection with Spring

    To inject domain objects like shown in the example above, we only have to do two little steps.
    First we have to create the @LoggedInUser annotation:

    import java.lang.annotation.*;
    import org.springframework.beans.factory.annotation.Qualifier;
    
    @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface LoggedInUser {
    
    }

    Please note the @Qualifier annotation which turns @LoggedInUser into a custom qualifier. Qualifiers are used by Spring to avoid conflicts if multiple beans of the same type are available.

    Next we have to add a bean definition to our Spring configuration. We use Spring's Java configuration here, the same can be done with xml configuration.

    @Configuration
    public class Application {
    
      @Bean
      @LoggedInUser
      @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
      public User getLoggedInUser() {
        // retrieve and return user object from server/database/session
      }
    }

    Inside getLoggedInUser() we have to retrieve and return an instance of the currently logged in user (e.g. by asking the AuthService from the first snippet). With @Scope we can control the scope of the returned object. The best scope depends on the domain objects and might differ among different domain objects. For a User object representing the logged in user, request or session scope would be valid choices. By annotating getLoggedInUser() with @LoggedInUser, we tell Spring to use this bean definition whenever a bean with type User annotated with @LoggedInUser should be injected.

    Now we can inject the logged in user into other components:

    @Component
    public class SomeComponent {
    
      @Autowired
      @LoggedInUser
      private User loggedInUser;
      
      ...
    }

    In this simple example the qualifier annotation is actually not necessary. As long as there is only one bean definition of type User available, Spring could inject the logged in user by type. However, when injecting domain objects it can easily happen that you have multiple bean definitions of the same type. So, using an additional qualifier annotation is a good idea. With their descriptive name qualifiers can also act as documentation (if named properly).

    Simplify Spring bean definitions

    When injecting many domain objects, there is chance that you end up repeating the scope and proxy configuration over and over again in your bean configuration. In such a situation it comes in handy that Spring annotations can be used on custom annotations. So, we can simply create our own @SessionScopedBean annotation that can be used instead of @Bean and @Scope:

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public @interface SessionScopedBean {
    
    }

    Now we can simplify the bean definition to this:

    @Configuration
    public class Application {
    
      @LoggedInUser
      @SessionScopedBean
      public User getLoggedInUser() {
        ...
      }
    }

    Java EE and CDI

    The configuration with CDI is nearly the same. The only difference is that we have to replace Spring annotations with javax.inject and CDI annotations.

    So, @LoggedInUser should be annotated with javax.inject.Qualifier instead of org.springframework.beans.factory.annotation.Qualifier (see: Using Qualifiers). The Spring bean definition can be replaced with a CDI Producer method. Instead of @Scope the appropriate CDI scope annotation can be used.bAt the injection point Spring's @Autowired can be replaced with @Inject.

    Note that Spring also supports javax.inject annotations. If you add the javax.inject dependency to your Spring project, you can also use @Inject and @javax.inject.Qualifier. It is actually a good idea to do this because it reduces Spring dependencies in your Java code.

    Conclusion

    We can use custom annotations and scoped beans to inject domain objects into other components. Injecting domain objects can make your code easier to read and can lead to cleaner dependencies. If you only inject AuthService to obtain the logged in user, you actually depend on the logged in user and not on AuthService.

    On the downside it couples your code stronger to the Dependency Injection framework, which has to manage bean scopes for you. If you want to keep the ability to use your classes outside a Dependency Injection container this can be a problem.

    Which types of domain objects are suitable for injection highly depends on the application you are working on. Good candidates are domain objects you often use and which not depend on any method or request parameters. The currently logged in user is an object that might often be suitable for injection.

    You can find the source of the shown example on GitHub.

  • Tuesday, 14 October, 2014

    Matching Latin characters with regular expressions in Java

    Recently I needed to check user input for non Latin characters. My first impression was that this cannot be done with regular expressions. It turned out that I was completely wrong.

    Standard regular expression character classes like [a-zA-Z] or \w (word character) are not suitable for matching Latin characters, they are far too restrictive. For example, these classes exclude characters like öòóô or äáàâ which are used in many western and central European languages.

    Luckily Java's java.regex.Pattern supports matching Unicode characters with \p. Various arguments can be passed with curly braces to \p. To match only Latin characters \p{IsLatin} can be used:

    "öôóò".matches("\\p{IsLatin}+"); // matches
    "Σήμε".matches("\\p{IsLatin}+"); // greek characters do not match

    \p supports a wide range of Unicode scripts. It can be used to match Greek, Cyrillic, Braille and more.
    Some examples:

    "Σήμε".matches("^\\p{IsGreek}+$");
    "ждля".matches("^\\p{IsCyrillic}+$");
    "⠇⠏⠙⠟".matches("^\\p{IsBraille}+$");
    "ᚊᚎᚑᚕᚙ᚛".matches("^\\p{IsOgam}+$"); // Chrome might not show these characters..

    Have a look at Character.UnicodeScript for the full list of supported scripts.

  • Wednesday, 1 October, 2014

    Checking for null values in Java with Objects.requiresNonNull()

    Checking method/constructor parameters for null values is a common task problem in Java. To assist you with this, various Java libraries provide validation utilities (see Guava Preconditions, Commons Lang Validate or Spring's Assert documentation).
    However, if you only want to validate for non null values you can use the static requiresNonNull() method of java.util.Objects. This is a little utility introduced by Java 7 that appears to be rarely known.

    With Objects.requiresNonNull() the following piece of code

    public void foo(SomeClass obj) {
      if (obj == null) {
        throw new NullPointerException("obj must not be null");
      }
      // work with obj
    }

    can be replaced with:

    import java.util.Objects;
    
    public void foo(SomeClass obj) {
      Objects.requireNonNull(obj, "obj must not be null");
      // work with obj
    }