mscharhag, Programming and Stuff;

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

  • Sunday, 13 May, 2018

    Templating with Rocker

    In this post we will have a quick look at Rocker, a statically typed and fast Java 8 template engine.

    Requireded Dependencies

    To get started with Rocker we need to add the following dependencies to our project:

    <dependency>
      <groupId>com.fizzed</groupId>
      <artifactId>rocker-runtime</artifactId>
      <version>0.24.0</version>
    </dependency>
    
    <!-- for hot-reloading support in development -->
    <dependency>
      <groupId>com.fizzed</groupId>
      <artifactId>rocker-compiler</artifactId>
      <version>0.24.0</version>
    </dependency>

    We also need the Rocker Maven plugin, which converts Rocker templates to Java code:

    <build>
      <plugins>
        <plugin>
          <groupId>com.fizzed</groupId>
          <artifactId>rocker-maven-plugin</artifactId>
          <version>0.24.0</version>
          <executions>
            <execution>
              <id>generate-rocker-templates</id>
              <phase>generate-sources</phase>
              <goals>
                <goal>generate</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>

    Creating the first templates

    We will start with a simple example containing two Rocker templates and a Java class.

    In the first template (main.rocker.html) we define the basic page structure:

    @args (String title, RockerBody content)
    
    <html>
      <head>
        <title>@title</title>
      </head>
      <body>
        @content
      </body>
    </html>

    This template has two parameters: The page title and a RockerBody element named content. The content parameter is basically a sub template that is added to the <body> tag.

    Now we create another template (basic.rocker.html) that defines the content that is passed to our first template:

    @args (String name)
    
    @views.main.template("Basic example") -> {
      <h1>Hello @name!</h1>
    }

    This template has a single name parameter that is written to a <h1> tag. We reference the first template (main.rocker.html) with @views.main and use the template(..) method to render it. "Basic example" will be passed as title parameter. The content parameter is defined within the curly braces.

    Rendering Rocker templates

    Rocker templates are converted to Java code. This can be done using the following Maven command:

    mvn generate-sources

    This generates a Java class for each template in the target/generated-sources/rocker directory.

    Now we can render our templates using Java code:

    public class Main {
    
      public static void main(String... args) throws Exception {
    
        // The template "basic.rocker.html" got converted to the class named "basic"
        // which is located in the "views" package
        
        String result = views.basic.template("John")
            .render()
            .toString();
    
        System.out.println(result);
      }
    }

    The output we get looks like this:

    <html>
      <head>
        <title>Basic example</title>
      </head>
      <body>
        <h1>Hello John!</h1>
      </body>
    </html>

    A bit of a problem with this approach is that you need to run mvn generate-sources everytime you make a change in your template files. Also note, that your Java code might not compile if the code generation fails because you have an issue in one of your templates.

    Another possible approach is to use hot reloading and reference the templates dynamically via file names.

    In this case the Java code looks like this:

    public class Main {
    
      public static void main(String... args) throws Exception {
    
        // Enable hot reloading
        RockerRuntime.getInstance().setReloading(true);
    
        // Reference via string instead of using generated code
        String result = Rocker.template("views/basic.rocker.html")
            .bind("name", "John")
            .render()
            .toString();
    
        System.out.println(result)
      }
    }

    The output we get is exactly the same.

    Expressions

    Assume we have a simple User class that contains the methods getFirstName() and getLastName(). In the following example we see how we can work with the User object in a Rocker template:

    @import com.mscharhag.rockerexample.*
    
    @args (User user)
    
    @views.main.template("Expressions") -> {
      <ul>
        <!-- first name -->
        <li>@user.getFirstName()</li>
    
        <!-- first three letters of first name -->
        <li>@user.getFirstName().substring(0, 3)</li>
    
        <!-- first name and last name -->
        <li>@user.getFirstName() @user.getLastName()</li>
    
        <!-- using a variable-->
        @name => {
          @user.getFirstName() @user.getLastName()
        }
        <li>@name</li>
    
      </ul>
    }

    Conditions

    Rocker supports the standard Java if-else flow structure as the following example shows:

    @import com.mscharhag.rockerexample.*
    
    @args (User user)
    
    @views.main.template("Conditions") -> {
      @if (user.getFirstName().length() > 10) {
        <p>Long first name</p>
      } else {
        <p>short first name</p>
      }
    }

    Loops

    Rocker templates support different forms of loops:

    @import com.mscharhag.rockerexample.*
    @import java.util.*
    
    @args (List<User> users)
    
    @views.main.template("Loops") -> {
      <ul>
        <!-- standard for loop -->
        @for (int i = 0; i < users.size(); i++) {
          <li>@users.get(i).getFirstName()</li>
        }
      
        <!-- standard 'for each' loop -->
        @for (User user : users) {
          <li>@user.getFirstName()</li>
        }
      
        <!-- for each loop with additional loop information
      
          <li>0: John, first: true, last: false</li>
          <li>1: Martin, first: false, last: false</li>
          <li>2: Anna, first: false, last: true</li>
        -->
        @for ((i, user) : users) {
          <li>@i.index(): @user.getFirstName(), first: @i.first(), last: @i.last()</li>
        }
      
      </ul>
    }

    The last loop is a special variation of Java's for-each loop. A second index parameter (named i in the example) can be used to access current iteration information.

    Conclusion

    Rocker can be definitively an option if you are looking for a Java template engine. According to the benchmark on the Rocker GitHub repository Rocker is a lot faster than other Java template engines like Freemarker or Velocity. The comprehensive documentation is another good point to mention.

    The fact that Rocker compiles to Java and allows you to pass data to views in a typesafe way is quite interesting. On one side this is useful because it helps to reduce bugs. On the other side the same feature annoyed me a bit, while I was writing the examples. Whenever I made code changes that affected Rocker templates (e.g. by changing the name of a method that was called within a Rocker template) the templates stopped compiling. In some situations this again stopped my Java code from compiling (because it was using the classes generated by Rocker). This is expected but it can break my preferred workflow of writing Java code first and fixing the templates later. Referencing templates via file names instead of using the generated classes solved this problem (but also throws away the type checking at compile time).

    You can find the code for the posted examples on GitHub.

  • Sunday, 5 March, 2017

    Be aware that bcrypt has a maximum password length

    bcrypt is a popular password hashing function these days. Other than standard hash functions (like SHA-515), bcrypt is designed to be slow and therefore very resistant to brute force attacks.

    However, when using bcrypt you should be aware that it limits your maximum password length to 50-72 bytes. The exact length depends on the bcrypt implementation you are using (see this stackexchange answer).

    Passwords that exceed the maximum length will be truncated.

    The following piece of code shows the password truncation using Spring Securities BCryptPasswordEncoder:

    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    
    // 72 characters
    String password1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    
    // 73 characters
    String password2 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
    
    String encodedPassword1 = passwordEncoder.encode(password1);
    boolean matches = passwordEncoder.matches(password2, encodedPassword1);
    
    System.out.println("encodedPassword1: " + encodedPassword1);
    System.out.println("matches: " + matches);
    

    When running this example, the output might look like this:

    encodedPassword1: $2a$10$A5OpVKgjEZzmy6UNsqzkjuG2xGET1wp3b/9ET5dz/tHQ3eRvyXSSO
    matches: true
    

    According to BCryptPasswordEncoder both passwords match (= are identical) even if they have a different length.

  • Wednesday, 27 April, 2016

    Java EE 8 MVC: Global exception handling

    In the previous previous posts we learned about various ways to access request information (e.g. query or path parameters) in Java EE MVC. This post shows how to apply global exception handling to an MVC application.

    Assume we have a controller method that might throw an IllegalArgumentException:

    @Controller
    @Path("illegal-argument")
    public class ExceptionController {
    
      @GET
      public String doWork() {
        // code that might throw an IllegalArgumentException
      }
    
    }
    

    We could now add a try/catch block to doWork() and wrap the piece of code that might throw the exception. However, this approach becomes tedious if it needs to be applied to multiple methods.

    In such a case we can register a global exception mapper. To do this, we habe to create a class that implements the generic ExceptionMapper interface.

    A simple ExceptionMapper for IllegalArgumentExceptions looks like this:

    @Provider
    public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {
    
      @Inject
      private Models models;
    
      @Override
      public Response toResponse(IllegalArgumentException exception) {
        models.put("message", exception.getMessage());
    
        return Response.status(Response.Status.BAD_REQUEST)
            .entity("/WEB-INF/jsp/error.jsp")
            .build();
      }
    }
    

    Now, whenever an IllegalArgumentException is thrown from controller methods, IllegalArgumentExceptionMapper will be used to convert the exception to an appropriate response. Here a simple error view (error.jsp) is rendered.

    If you want a generic ExceptionMapper that handles all types of exceptions, you simply have to implement ExceptionMapper<Exception>. If you have multiple ExceptionMapper implementations that are suitable to handle a thrown exception, the most specific ExceptionMapper is used.

    Quick Summary

    Adding global exception handling to an Java EE MVC application is quite simple. We only have to create a class that implements the ExceptionMapper interface with the exception type that should be handled.

    The full example code can be found on GitHub.

  • Sunday, 3 April, 2016

    Simplifying nested loops with Java 8 Lambdas

    This is just a quick tip for everyone who often has to work with multi dimensional arrays in Java 8 (or newer).

    In this case you might often end with code similar to this:

    float[][] values = ...
    for (int i = 0; i < values.length; i++) {
      for (int k = 0; k < values[i].length; k++) {
        float value = values[i][k];
        // do something with i, k and value
      }
    }

    If you are lucky you can replace the loops with for-each loops. However, often the indices are required for computations inside the loop.

    In such a case you can come up with a simple utility method that looks like this:

    private void loop(float[][] values, BiConsumer<Integer, Integer> consumer) {
      for (int i = 0; i < values.length; i++) {
        for (int k = 0; k < values[i].length; k++) {
          consumer.accept(i, k);
        }
      }
    }
    

    We can now loop over array indices like this:

    float[][] values = ...
    loop(values, (i, k) -> {
      float value = values[i][k];
      // do something with i, k and value
    });
    

    This way you can keep the looping code out of your main logic.

    Of course you should change the shown loop() method so it fits your personal needs.

     

  • Wednesday, 30 March, 2016

    Retry handling with Spring-Retry

    Whenever software components communicate with each other, there is a chance for temporary self-correcting faults. Such faults include the temporary unavailability of a service, momentary loss of network connectivity, or timeouts that arise when a service is busy. In such situations a proper retry handling can reduce the problems these faults might cause.

    In this post we will see how Spring Retry can be used to add robust retry logic to Spring applications. Spring Retry is probably not that well know because it is not listed on the Spring documentation overview. However, you can find it on the Spring Initializr page.

    Setup

    To use Spring Retry we need to add the following dependency to our project:

    <dependency>
      <groupid>org.springframework.retry</groupid>
      <artifactid>spring-retry</artifactid>
      <version>1.1.2.RELEASE</version>
    </dependency>

    Spring Retry makes use of AOP, so make sure Spring AOP is available:

    <dependency>
      <groupid>org.springframework</groupid>
      <artifactid>spring-aop</artifactid>
      <version>4.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.8</version>
    </dependency>
    

    If you are using Spring Boot, you can use spring-boot-starter-aop instead:

    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-aop</artifactid>
    </dependency>
    

    To enable Spring Retry we simply have to add @EnableRetry to our application configuration class:

    @EnableRetry
    @SpringBootApplication // or @Configuration if you are not using Spring Boot
    public class RetryExampleApplication {
      // ...
    }
    

    Adding retry handling with Annotations

    We are now ready to add retry handling to methods. To do so, we simply have to annotate the appropriate methods with @Retryable:

    @Service
    public class MyService {
    
      @Retryable
      public void simpleRetry() {
        // perform operation that is likely to fail
      }
    }	

    Methods annotated with @Retryable can be called like any other methods. However, whenever the execution of a retryable method fails with an exception, Spring will automatically retry to call the method up to three times. By default Spring uses a 1 second delay between method calls. Please note that the calling thread blocks during retry handling.

    The retry behavior can be customized in various ways. For example:

    @Service
    public class MyService {
    
      @Retryable(value = {FooException.class, BarException.class}, maxAttempts = 5)
      public void retryWithException() {
        // perform operation that is likely to fail
      }
    
      @Recover
      public void recover(FooException exception) {
        // recover from FooException
      }
    }
    

    Here we tell Spring to apply retry handling only if a Exception of type FooException or BarException is thrown. Other exceptions will not cause a retry. maxAttempts = 5 tells Spring to retry the method up to 5 times if it fails.

    With @Recover we define a separate recovery method for FooException. This allows us to run special recovery code when a retryable method fails with FooException.

    Adding retry handling with RetryTemplate

    Besides annotations Spring Retry offers a RetryTemplate that can be used to define retry handling in Java code. Like any other bean, a RetryTemplate can simply be configured in our configuration class:

    @EnableRetry
    @SpringBootApplication // or @Configuration if you are not using Spring Boot
    public class RetryExampleApplication {
    
      @Bean
      public RetryTemplate retryTemplate() {
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(5);
    
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(1500); // 1.5 seconds
    
        RetryTemplate template = new RetryTemplate();
        template.setRetryPolicy(retryPolicy);
        template.setBackOffPolicy(backOffPolicy);
    
        return template;
      }
      
      // ...
    }

    A RetryPolicy determines when an operation should be retried. SimpleRetryPolicy is a RetryPolicy implementation that retries a fixed number of times.

    A BackOffPolicy is a strategy interface to control back off between retry attempts. A FixedBackOffPolicy pauses for a fixed period of time before continuing. Some other default BackOffPolicy implementations are ExponentialBackOffPolicy (increases the back off period for each retry) or NoBackOffPolicy (no delay between retries).

    We can now inject the RetryTemplate to our service. To run code with retry handling we simply have to call RetryTemplate.execute():

    @Service
    public class RetryService {
    
      @Autowired
      private RetryTemplate retryTemplate;
    
      public void withTemplate() {
        retryTemplate.execute(context -> {
          // perform operation that is likely to fail
        });
      }
    
      // ...
    }
    

    RetryTemplate.exeucte() takes a RetryCallback<T, E> as parameter. RetryCallback is a functional interface so it can be implemented using a Java 8 Lambda expression (as shown above).

    Summary

    Spring retry provides an easy way to add retry handling to spring applications. Retry handling can be added using either annotations (@Retryable and @Recover) or by passing a RetryCallback to a RetryTemplate.

    You can find the full example source code on GitHub.