Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Monday, February 18, 2019

Java date-time timezone formats

Java has excellent date-time formatting with the arrival of java.time (JSR310) in Java 8. I point out that release as it came with a usable, safe API. (Let us never speak of Calendar again).

However, I never recall how to format timezone. There are so many options, and it is easy to get is "almost right", but not exactly right.

Problem

I'd like to append a "Z" character on the end of a UTC timestamp. OK, let's look at the options, showing only those for timezone/offset:

Symbol Meaning Presentation Examples
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
v generic time-zone name zone-name Pacific Time; PT
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
Z zone-offset offset-Z +0000; -0800; -08:00

One thing to be wary of: formatting characters can be doubled, tripled, or quadrupled, and it changes the result. Further, some characters have special rules on repeating (eg, "VV", and "O" vs "OOOO").

The best way to understand what to use is to try them all:

final var when = ZonedDateTime.of(
        LocalDate.of(2011, 2, 3),
        LocalTime.of(14, 5, 6, 7_000_000),
        ZoneId.of("UTC"))
        .toInstant();
for (final String tzFormat
        : List.of("VV", "v", "z", "zz", "zzz", "zzzz", "O", "OOOO", "X", "XX", "XXX",
        "XXXX", "x", "xx", "xxx", "xxxx", "Z", "ZZ", "ZZZ", "ZZZZ")) {
    System.out.println(
            tzFormat + " - " + DateTimeFormatter
                    .ofPattern("yyyy-MM-dd'T'HH:mm:ss" + tzFormat)
                    .withZone(ZoneId.of("UTC"))
                    .format(when));
}

Producing:

VV - 2011-02-03T14:05:06UTC
v - 2011-02-03T14:05:06UTC
z - 2011-02-03T14:05:06UTC
zz - 2011-02-03T14:05:06UTC
zzz - 2011-02-03T14:05:06UTC
zzzz - 2011-02-03T14:05:06Coordinated Universal Time
O - 2011-02-03T14:05:06GMT
OOOO - 2011-02-03T14:05:06GMT
X - 2011-02-03T14:05:06Z
XX - 2011-02-03T14:05:06Z
XXX - 2011-02-03T14:05:06Z
XXXX - 2011-02-03T14:05:06Z
x - 2011-02-03T14:05:06+00
xx - 2011-02-03T14:05:06+0000
xxx - 2011-02-03T14:05:06+00:00
xxxx - 2011-02-03T14:05:06+0000
Z - 2011-02-03T14:05:06+0000
ZZ - 2011-02-03T14:05:06+0000
ZZZ - 2011-02-03T14:05:06+0000
ZZZZ - 2011-02-03T14:05:06GMT

What an exciting list! "zzzz" is rather wordy, and it's unclear what "ZZZZ" is doing. Actually, the whole list is even more iteresting for timezones other than UTC.

Solution

Since the goal is to append a "Z", the simplest choice is: yyyy-MM-dd'T'HH:mm:ssX.

Addendum

Why didn't I just use DateTimeFormatter.ISO_INSTANT, which is documented to produce the "Z"? I want a timestamp that is to only seconds-precision, and the format for "ISO_INSTANT" includes milliseconds.

Friday, January 18, 2019

Spring REST testing

After too much Internet searching, I was unable to find an easy solution to repeated duplication in my Spring MockMVC tests of REST controller endpoints. For years now, the endpoints we write have typically sent or received JSON. This is what I mean:

mockMvc.perform(post("/some/endpoint")
        .contentType(APPLICATION_JSON_UTF8)
        .accept(APPLICATION_JSON_UTF8)
        .content(someRequestJson))
        .andExpect(status().isCreated())
        .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
        .andExpect(header().string(LOCATION, "/some/endpoint/name-or-id"))
        .andExpect(content().json(someResponseJson));

All the repeated "APPLICATION_JSON_UTF8"s, in every controller test!

If there is an existing Spring testing solution, I'd love to hear about it. Rather than wait, I wrote up a small extension of @WebMvcTest to default these values.

First, an annotation for Spring to use in setting up a MockMvc (javadoc elided):

@Documented
@Import(JsonMockMvcConfiguration.class)
@Retention(RUNTIME)
@Target(TYPE)
@WebMvcTest
public @interface JsonWebMvcTest {
    @AliasFor(annotation = WebMvcTest.class)
    String[] properties() default {};

    @AliasFor(annotation = WebMvcTest.class)
    Class[] value() default {};

    @AliasFor(annotation = WebMvcTest.class)
    Class[] controllers() default {};

    @AliasFor(annotation = WebMvcTest.class)
    boolean useDefaultFilters() default true;

    @AliasFor(annotation = WebMvcTest.class)
    ComponentScan.Filter[] includeFilters() default {};

    @AliasFor(annotation = WebMvcTest.class)
    ComponentScan.Filter[] excludeFilters() default {};

    @AliasFor(annotation = WebMvcTest.class)
    Class[] excludeAutoConfiguration() default {};
}

Note it is a near exact lookalike of @WebMvcTest (minus the deprecated parameter). The important bits are:

  1. Marking this annotation with @WebMvcTest, a kind of extension through composition.
  2. Adding @Import to bind custom configuration to this annotation.
  3. Tying the same-named annotation parameters to @WebMvcTest, so this annotation is a drop-in replacement of that one.

Next a configuration class, imported by the annotation, to customize MockMvc:

@Configuration
public class JsonMockMvcConfiguration {
    @Bean
    @Primary
    public MockMvc jsonMockMvc(final WebApplicationContext ctx) {
        return webAppContextSetup(ctx)
                .defaultRequest(post("/")
                        .contentType(APPLICATION_JSON_UTF8)
                        .accept(APPLICATION_JSON_UTF8_VALUE))
                .alwaysExpect(header().string(
                        CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
                .build();
    }
}

Some points about this class:

  • @Primary is not necessary for Spring, but helped IntelliJ — perhaps I got lucky with Spring without @Primary, and IntelliJ highlighted a real problem.
  • It took quite a while to get defaultRequest(...) working. I was unable to (re)implement the relevant interfaces, and eventually found that passing any MockHttpServletRequestBuilder sufficed. Spring "merges" (overlays) the actual request builder from the test over this default, replacing POST and "/" with whichever HTTP method and path the test uses (eg, GET "/bob"). Only the header customization is used.

Example usage:

@JsonWebMvcTest(SomeController.class)
class SomeControllerTest {
    @Autowired
    private MockMvc jsonMockMvc;

    @Test
    void shouldCheckSomething()
            throws Exception {
        jsonMockMvc.perform(post("/some/endpoint")
                .content(someRequestJson))
                .andExpect(status().isCreated())
                .andExpect(header()
                        .string(LOCATION, "/some/endpoint/new-name"))
                .andExpect(content().json(someResponseJson));
    }
}

See the Basilisk project for source code and sample usage. (Basilisk is a demonstration project for my team illustrating Spring usage and conventions.)

Wednesday, January 09, 2019

Magic Bus returns

During my first stint at ThoughtWorks, I paired with Gregor Hohpe on implementing messaging patterns while he worked with Bobby Woolf on Enterprise Integration Patterns (EIP). To this day, this remains one of my favorite technical books. In conversation I was always struck by Gregor's meticulous "napkin diagrams" as he illustrated the point he was making.

One output from that pairing was to experiment with using messaging patterns within a single program, not just between programs. So I wrote the "Magic Bus" library in Java, using reflection, to connect publishing and subscribing components within a web services backend.

While working a new project, I find myself diagramming one of our backend services using EIP's notations for messaging patterns. And I recalled "Magic Bus".

I thought I had long ago lost the source code, but found some JVM .class files in a forgotten directory. IntelliJ to the rescue! Using JetBrain's excellent Fernflower decompiler, I recovered a later stage of "Magic Bus" after I had converted it to typesafer generics and dropped reflection.

That code is now in public GitHub, brought up to Java 11, and cleaned up.

If I recall correctly, I originally dropped "Magic Bus" after Guava's Event Bus came along. What makes "Magic Bus" different from Event Bus? Not too much, actually. The main feature in "Magic Bus" lacking in Event Bus is subscribing to message handler exceptions: in Guava one instead registers a global callback to handle exceptions.

Monday, January 07, 2019

Hard-won JDK offset knowedge

It took far more research time than I expected. The goal: Output an OffsetDateTime with offset for Zulu (OTC) timezone as +00:00.

I have a project where a 3rd-party JSON exchange expected timestamps in the format 01-02-03T04:05:06+00:00. We're using Jackson in a Java project. All the default configuration I could find, and trying all the "knobs" on Jackson I could find, led to: 01-02-03T04:05:06Z. Interesting, as any non-0 offset for timezone produced: 01-02-03T04:05:06+07:00 rather than a timezone abbreviation: Zero offset is special.

Finally, circling back to the JDK javadocs yet again, I spotted what I had overlooked many times before:

Offset X and x: This formats the offset based on the number of pattern letters. One letter outputs just the hour, such as '+01', unless the minute is non-zero in which case the minute is also output, such as '+0130'. Two letters outputs the hour and minute, without a colon, such as '+0130'. Three letters outputs the hour and minute, with a colon, such as '+01:30'. Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'. Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'. Six or more letters throws IllegalArgumentException. Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero, whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.

The key is to use lowercase 'x' in the format specification. So my problem with Jackson became:

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssxxx")
    private final OffsetDateTime someOffsetDateTime;

And the result is the desired, 01-02-03T04:05:06+00:00.

Now I can return to more interesting problems.

Friday, November 09, 2018

What are exceptions?

What are exceptions?

Essentially, exceptions are a form of structured, non-local goto with stack unwinding. "Structured" here means "higher level than the machine" (a matter of taste/opinion), and "non-local" means "beyond a single function/method".

What this means is that you can replace code like (in "C"):

int bottom()
{
    int things_go_wrong = -1; // For illustration

    if (things_go_wrong) goto error;
    return 0;

error:
    return -1;
}

int
middle()
{
    if (-1 == bottom()) goto error;
    return 0;

error:
    return -1;
}

void
top()
{
    if (-1 == middle()) {
        handle_failure();
    }
}

With code like (in Java):

public class A {
    void botton() {
        boolean thingsGoWrong = true; // For illustration

        if (thingsGoWrong) throw new ThingsWentWrong("So wrong!");
    }

    void middle() {
        bottom();
    }

    void top() {
        try {
            middle();
        } catch (ThingsWentWrong e) {
            handleFailure();
        }
    }
}

(An example in Scheme.)

"Unwinding" here means the compiler or runtime treats intermediate calls (the stack) the same as if returning normally (for example, the stack pointer is moved back; and in a language like C++, destructors are executed), and program execution resumes in the catch block.

It is "structured" in the sense that it is not the same as a direct goto to the resume point. This is not possible in standard "C" or C++ (or in Java), which only suppport local labels within functions. The equivalent in "C" and C++ is to use setjmp and longjmp for a non-local goto, and forget all about deallocating memory or calling destructors. (As odd as this sounds, it is needed for call-with-continuation, an important feature in LISP-like languages).

Takeaway

All human endeavors build on the work of those who came previous. Exceptions are no exception. They are the result of 1960s and 1970s programmers wanting an easier way to deal with exceptional conditions. This is not completely identical with "errors", which may sometimes be better represented with a simple boolean true/false return. Like any sharp instrument, do not abuse it.

Sunday, September 23, 2018

Removing Joda from Spring Boot

Automated Acceptance Criteria

Removing Joda from Spring Boot

The problem

We recently migrated a medium-sized Java project to Spring Boot 2 from version 1. One of the challenges was migrating to the JDK date-time library from Joda. It turns out that Spring Boot 2 has excellent native support for JDK date-times, as does Jackson (JSON) and Hibernate (database), the default technologies offered by Spring Boot 2 for these features.

The migration itself went smoothly, which is unsurprising given the fantastic work of Stephen Colebourne in designing JDK date-time support based on his authorship of Joda.

So we looked at disabling Joda completely in our Gradle build. The most concise approach we found was:

configurations {
    compile.exclude group: 'joda-time'
}

This removed Joda completely from configurations (classpaths) related to Java. However, this had unintended side effects:

  • During tests, we needed Joda in the runtime classpath for a 3rd-party library, OpenSAML
  • During boot run (running the app), we needed Joda in the classpath for another 3rd-party library, SpringFox

We easily found a workaround for SpringFox, but not for OpenSAML.

(If you're curious, yes, we do intent to migrate from OpenSAML 2 (desupported in 2016) to OpenSAML 3; however, we would like spring-security-saml2-core support first.)

A solution in progress

The exclusion in the compile configuration does exactly what we need: Joda disappears! But what to do about SpringFox and OpenSAML?

For the Spring Boot runtime classpath, there is another concise solution, though finding it was rather troublesome, and it is not well-documented by Pivotal or in Stack Overflow.

First, we setup another classpath of our own making named bootRuntime:

configurations {
    // Other parts of "configurations", including the Joda exclusion from above

    bootRuntime // Synthetic configuration for deps needed *only* to launch app
}

Then we added Joda to that synthetic classpath relying on Spring Boot plugin's definition for the version of Joda to use:

dependencies {
    // Other parts of "dependencies"

    bootRuntime 'joda-time:joda-time'
}

Lastly, we taught Spring Boot to include this synthetic classpath when launching our app (this was the trickiest part):

bootJar {
    bootInf {
        from configurations.bootRuntime
        into 'lib'
    }
}

bootRun {
    classpath += configurations.bootRuntime
}

This adds Joda to the runtime classpath for both the single "fat jar" built by Spring (bootJar), and when launching the app on the command line with gradle (bootRun).

Unless you are a heavy Gradle user, from ... into ... syntax may be unfamiliar: this copies the jars in the synthetic configuration into the fat jar at the location Boot expects to find them. The "'lib'" is literally a directory location within the jar. Useful magic, but a bit obtuse. The outcome:

$ jar tf build/libs/the-project.jar | grep joda-time
BOOT-INF/lib/joda-time-2.9.9.jar

As a matter of fact, Joda is the very last file in the boot jar, a suggestion that it was added by our bootInf section after the Boot plugin built the jar.

(Our workaround is intentionally small. If we're unable to make it work, we'll switch to brute-force library exclusions in our dependencies lists. The goal is to prevent accidental import from Joda, for example, of LocalDate.)

Remaining work

For running the boot app, this solution is great: it is small, readable, easy to maintain, and it works. However, for tests which exercise our user authentication with OpenSAML, it fails. Joda is not in the test classpath, and we cannot use or mock OpenSAML methods which use Joda types.

Barring another magical solution like bootRuntime, we'll fall back on manually excluding Joda from each dependency, and adding it back in to the test classpath. A pity given how pithy the solution is with exclusion from the compile configuration.

Tuesday, May 01, 2018

JaCoCo, Gradle, and exclusions

The setup

My team is working on a Java server, as part of a larger project project, using Gradle to build and JaCoCo to measure testing code coverage. The build fails if coverage drops below fixed limits (branch, instruction, and line)—"verification" in JaCoCo-speak.

We follow the strategy of The Ratchet: as dev pairs push commits into the project, code coverage may not drop without group agreement, and if coverage rises, the verification limits rise to match. This ensures we have ever-rising coverage, and avoid new code which lacks adequate testing.

The problem

At a work project, we're struggling to get JaCoCo to ignore some new, configuration-only Java classes. These classes have no "real" implementation code to test, are used to setup communication with an external resource, yet are high line-count (static configuration via code). So they drag down our code coverage limits, and there is no effective way to unit test them sensibly. (They are best tested as system tests within our CI pipeline using live programs and remote resources.)

JaCoCo has what seems at first blush a sensible way to exclude these configuration classes from testing:

jacocoTestVerificationCoverage {
    violationRules {
        rule {
            excludes ['hm.binkley.labs.saml.SomeConfig']
            limit {
                counter = 'LINE'
                minimum = 0.90
            }
        }
    }
}

Unfortunately, this does nothing. There is no warning or error, and coverage continues to include the whole code base.

A solution

After a lot of experimenting and StackOverflow research, this answer from Juan Vimberg worked exactly as we needed. Following his approach:

final def excludedClasses = ['hm.binkley.labs.saml.SomeConfig']

jacocoTestVerificationCoverage {
    violationRules {
        rule {
            limit {
                counter = 'LINE'
                minimum = 0.90
            }
        }
    }

    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it, excludes: excludedClasses.collect {
                it.replace('.', '/') + '.class'
            })
        })
    }
}

The list of excluded classes is extracted so the same trick can be used in the generated reports:

jacocoTestReport {
    executionData test, databaseTest
    reports {
        html.enabled = true
        xml.enabled = true
        csv.enabled = false
    }
    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it, excludes: excludedClasses.collect {
                it.replace('.', '/') + '.class'
            })
        })
    }
}

Something to consider: using wildcards (hm.binkley.labs.saml.*) may take additional work.

Why?

Why does this work, and the "obvious" way does not?

JaCoCo has more than one notion of scoping. The clearest one is the counters: branches, classes, instructions, lines, and methods.

Not as well documented is the scope of checks: bundles, classes, methods, packages, and source files. These are not mix-and-match. For example, exclusions apply to classes. Lyudmil Latinov has the best hints I've found on how this works.

Tuesday, September 19, 2017

Help for JDBC with Java streams

We wanted to use JDBC with Java Streams, but encountered several difficulties. Fortunately we found solutions with rather small bits of code.

Checked exceptions

The main obstacle was the JDBC API throwing SQLException for all API methods used in our code. SQLException is a checked exception, so must be declared in our method signatures, or caught otherwise. However the Streams API only accepts methods which declare to throw no checked exceptions, so something simple like this will not compile:

stream(results).
        map(row -> row.getString("label")).  // checked exception
        forEach(this::processLabel);

The call to ResultSet.getString(String) throws a checked exception. The usual approach is to wrap the call, and handle the exception in the wrapping method:

method String streamGetLabel(final ResultSet results) {
    try {
        return results.getString("label");
    } catch (final SQLException e) {
        throw new UncheckedIOException(e);
    }
}

(Here UncheckedIOException is an unchecked exception wrapper we wrote for SQLException, similar to UncheckedIOException in the JDK for IOException.)

Then the stream becomes:

stream(results).
        map(this::streamGetLabel).
        forEach(this::processLabel);

This is OK, however needing to write a wrapper method for each time we wanted to use JDBC in a stream became tedious.

Solution

First we wrote a SAM (more on SAM interfaces/classes) interface as a lookalike for the JDK Function interface: this is what Stream.map(Function) wants.The lookalike is different in that it throws SQLException:

@FunctionalInterface
public interface SQLFunction<T, R> {
    R apply(final T t) throws SQLException;

    // Other default methods - no more abstract methods
}

Then we used this in a closed Function implementation to wrap and delegate to the lookalike, and throw UncheckedSQLException if the lookalike throws SQLException:

@RequiredArgsConstructor(staticName = "applyUnchecked")
public final class UncheckedSQLFunction<T, R>
        implements Function<T, R> {
    private final SQLFunction<T, R> wrapped;

    @Override
    public R apply(final T t) {
        try {
            return wrapped.apply(t);
        } catch (final SQLException e) {
            throw new UncheckedSQLException(e);
        }
    }
}

(Here we use the excellent Lombok library to generate our constructor, and give us a static convenience method, "applyUnchecked".)

Finally some static importing, and our example streams use becomes:

stream(results).
        map(applyUnchecked(row -> row.getString("label"))).
        forEach(this::processLabel);

Or with more help:

stream(results).
        map(getString("label")).
        forEach(this::processLabel);

We wrote similar lookalikes and wrappers for Predicate and Consumer. It would be easy enough to write them for other Java functional interfaces, such as BiFunction.

Streaming result sets

The next difficulty we tackled was how to loop over ResultSet, and use them with Streams.

(A side note: ResultSet is not a set but a list: rows are ordered, and they can duplicate each other in their column data. However, they were named after the SQL concept of sets, not the Java one.)

Fundamentally, a ResultSet is not an iterator, but is close:

Iterator ResultSet Returns  
hasNext() next() boolean  
next() this ResultSet (Yes, the ResultSet itself is the equivalent)

Solution

To provide a ResultSet as an iterator:

final List<String> values = new ArrayList<>();
        for (final ResultSet row : iterable(results)) {
            values.add(row.getString("value"));
        }

Moreso, to provide one as a stream:

final List<String> values = stream(results).
                map(getString("value")).
                collect(toList());

Any SQL failures are thrown as unchecked exceptions. The stream has the characteristics: immutable, nonnull, and ordered.

Transactions

We found JDBC transactions to be tricky. Fundamentally they are tied to a connection; there is no proper nesting. (To simulate nesting, use separate connections. Even then, there is no guarantee of ordering from the database engine.) And they have a baroque API, relying on diddling of the "auto-commit" setting with care needed to restore its setting after the transaction concludes. Several bugs ensued before we switched to using small helper interfaces and methods.

Further, some programming languages do not distinguish void from other return types (e.g., Unit type): Java is not one of them. Likewise for user vs primitive types (Boolean vs boolean). Hence, there are separate transaction blocks for consumers, functions, and predicates.

Solution

One example explains them all. Consider functions and the SQLFunction lookalike interface:

@RequiredArgsConstructor(staticName = "applyTransacted")
public final class TransactedFunction<T, R>
        implements SQLFunction<T, R> {
    private final Connection connection;
    private final SQLFunction<T, R> wrapped;

    @Override
    public R apply(final T in)
            throws SQLException {
        connection.setAutoCommit(false);
        try {
            final R out = wrapped.apply(in);
            connection.commit();
            return out;
        } catch (final SQLException e) {
            connection.rollback();
            throw e;
        } finally {
            connection.setAutoCommit(true);
        }
    }
}

(The pattern is the same for other collection operations.)

With a helper and static importing:

final Integer value = applyTransacted(connection, in -> 0).apply("string");

Or when the transaction fails:

applyTransacted(connection, in -> {
        throw new SQLException("Something went wrong");
    }).apply("string");

Some convenience

Many places in these examples are improved with helper functions, or for transactions, with currying (similar to the builder pattern). Hence, the wide use of Lombok static constructors. Transactions are another example as they need a Connection for begin/commit/rollback.

Solution

A simple helper curries connection for transactions:

@RequiredArgsConstructor(staticName = "with")
public final class WithConnection {
    private final Connection connection;

    public <T> Predicate<T> testTransacted(final SQLPredicate<T> wrapped) {
        return UncheckedSQLPredicate.testUnchecked(
                TransactedPredicate.<T>testTransacted(connection, wrapped));
    }

    public <T, R> Function<T, R> applyTransacted(
            final SQLFunction<T, R> wrapped) {
        return UncheckedSQLFunction.applyUnchecked(
                TransactedFunction.<T, R>applyTransacted(connection,
                        wrapped));
    }

    public <T> Consumer<T> acceptTransacted(final SQLConsumer<T> wrapped) {
        return UncheckedSQLConsumer.acceptUnchecked(
                TransactedConsumer.<T>acceptTransacted(connection, wrapped));
    }
}

Example use:

final Optional<Integer> value = Stream.of(0).
        filter(with(connection).testTransacted(in -> true)).
        findFirst();

(Yes, we might also describe the code as partial application. The "object-oriented" implementation confuses matters with the hidden this reference.)

Conclusion

There is nothing we did that was difficult or complex: simple one-liner interfaces, simple wrapper implementations of Java funcional interfaces, some rote JDBC best practices. The main difficulty was conceptual: seeing the duplication of many, small wrapper methods, and pulling out their commonality. This is a good pattern to keep in mind throughout your code.

UPDATE:

And the source: Java helpers for JDBC and Streams.

Friday, August 11, 2017

How to write clean Java

I cannot tell you how to write good Java, but I can help you write clean Java. As usual, automation is key. It's all about the tooling.

The best thing about good tooling is that they work together: each covers a different area, does not impeded another tool, and fixing one complaint a tool reveals often fixes complaints from other tools.

This advice applies to any programming language, not just Java. Java, having the most mature ecosystem, is instructive.

The tools

Use good source control
Git is your best choice. Use either trunk-based development with feature toggles (feature flags), or gitflow patterns, depending on your needs and organization. Require full builds and testing before pushing to a shared repository; hooks can help together with your build tool.
Use good build automation
Maven or Gradle are your best choices; either is excellent. Teach the tool to be strict and fail builds if anything is not just right. Treat your build configuration as code, part of the same repository and held to the same hygiene standards. Keep your local build fast.
Use a good editor
IntelliJ is the best choice. Use inspections, intentions, and reformatting obsessively: code diffs should only show real changes, not whitespace or formatting. Use plugins to ease integrating IntelliJ with other tooling.
Keep your style consistent
Checkstyle is your best choice; other choices are needed for non-Java JVM languages. Fail your build if checkstyle complains. Keep your IntelliJ formatting and Checkstyle rules consistent. Generally, choose either Sun or Google coding standards, and be leary of deviating from them; if unsure, pick Sun.
Fully test your code
JaCoCo works well. Fail your build if coverage drops below a threshhold; rachet up the threshhold as coverage improves. Start low and aim for a 95%+ threshhold. Follow the Test Pyramid; save your end-to-end tests for CI, or run locally only once before pushing commits.
Be zealous in looking for problems
FindBugs, PMD, or Error Prone are your best choices (pick one); other choices may work better for non-Java JVM languages. Fail your build if your choice complains. Be judicious in disabling complaints (for example, FindBugs "experimental" checks, should likely be disabled).
Use code generation
Lombok is your first choice. Add others as needed (or build domain-specific code generators). Generated code does not need test coverage, style checks, or bug detection if the generator is clean and well-tested: trust it.

Update

Dan Wallach reminded me of Error Prone, added above.

Monday, May 02, 2016

Do not test Java getters and setters

An excellent project from Osman Shoukry to automate testing of Java getters and setters—that is when you have getters and setters to test. There's the rub: do not write getters or setters.

For starters they violate encapsulation, exposing your objects innards to others. Ok, but there are frameworks which require them, even in 2016. What to do?

Generate them:

@Getter
@Setter
@RequiredArgsConstructor
public final class SampleBean {
    private final String left;
    private String right;
}

With what result?

public final class SampleBean {
    private final String left;
    private String right;

    @java.lang.SuppressWarnings("all")
    @javax.annotation.Generated("lombok")
    public String getLeft() {
        return this.left;
    }

    @java.lang.SuppressWarnings("all")
    @javax.annotation.Generated("lombok")
    public String getRight() {
        return this.right;
    }

    @java.lang.SuppressWarnings("all")
    @javax.annotation.Generated("lombok")
    public void setRight(final String right) {
        this.right = right;
    }

    @java.beans.ConstructorProperties({"left"})
    @java.lang.SuppressWarnings("all")
    @javax.annotation.Generated("lombok")
    public SampleBean(final String left) {
        this.left = left;
    }
}

This code need never be tested. Test the generator, not the generated code. If the generator is correct, so is the generated code. In this case, Lombok is heavily tested.

As an alternative to the constructor taking field values, Jesse Wilson has interesting advice.

Tuesday, March 01, 2016

Hand-rolling builders in Java

I showed off a hand-rolled example Java builder pattern today. It has some benefits over existing builder solutions, but is more work than I like:

  1. All parts of the builder are immutable; you can pass a partially built object for another object to complete (I'm looking at you, Lombok)
  2. It's syntactically complete; that is, code won't compile without providing all arguments for the thing to build
  3. It's easy to generalize; in fact, I'm thinking about an annotation processor to generate it for you (but not there quite yet)
@EqualsAndHashCode
@ToString
public final class CartesianPoint {
    public final int x;
    public final int y;

    public static Builder builder() {
        return new Builder();
    }

    private CartesianPoint(final int x, final int y) {
        this.x = x;
        this.y = y;
    }

    public static final class Builder {
        public WithX x(final int x) {
            return new WithX(x);
        }

        @RequiredArgsConstructor
        public static final class WithX {
            private final int x;

            public WithY y(final int y) {
                return new WithY(y);
            }

            @RequiredArgsConstructor
            public final class WithY {
                private final int y;

                public CartesianPoint build() {
                    return new CartesianPoint(x, y);
                }
            }
        }
    }
}

That was a lot to say! Which is why most times you don't hand-roll builders. Usage is obvious:

@Test
public void shouldBuild() {
    final CartesianPoint point = CartesianPoint.builder().
            x(1).
            y(2).
            build();
    assertThat(point.x).isEqualTo(1)
    assertThat(point.y).isEqualTo(2);
}

Adding caching for equivalent values is not hard:

public static final class Builder {
    private static final ConcurrentMap
            cache = new ConcurrentHashMap<>();

    public WithX x(final int x) {
        return new WithX(x);
    }

    @RequiredArgsConstructor
    public static final class WithX {
        private final int x;

        public WithY y(final int y) {
            return new WithY(y);
        }

        @RequiredArgsConstructor
        public final class WithY {
            private final int y;

            public CartesianPoint build() {
                final CartesianPoint point = new CartesianPoint(x, y);
                final CartesianPoint cached = cache.
                        putIfAbsent(point, point);
                return null == cached ? point : cached;
            }
        }
    }
}

Thursday, February 25, 2016

Java 8 shim method references

So I'm working on Spring Boot autoconfiguration for Axon Framework. I run into a nice interface in Axon framework that is unfortunately too specific. So I generalize. The original, pared down:

public interface AuditDataProvider {
    Map<String, Object> provideAuditDataFor(CommandMessage<?> command);
}

Aha! A SAM interface, interesting. So I craft my look-a-like:

public interface AuditDataProvider {
    Map<String, Object> provideAuditDataFor(Message<?> command);
}

Not much difference. Note the method parameter is Message rather than CommandMessage. This works fine as the implementation I have in mind uses getMetaData(), defined in Message and inherited by CommandMessage—so the original Axon interface is overspecified, using a more specific parameter type than needed.

(Keep this in mind: most times use the most general type you can.)

Ah, but other parts of the Axon framework ask for an AuditDataProvider (the original code, above) and I'm defining a new, more general interface. I cannot extend the original with mine; Java correctly complains that I am widening the type: all CommandMessages are Messages, but not all Messages are CommandMessages.

Java 8 method references to the rescue!

public interface MessageAuditDataProvider {
    Map<String, Object> provideAuditDataFor(final Message<?> message);

    default AuditDataProvider asAuditDataProvider() {
        return this::provideAuditDataFor;
    }
}

Because I accept a supertype in my new interface relative to the original, my method reference works simply and cleanly.

Sunday, February 21, 2016

Followup: Feature Toogles for Spring

The original technique in Spring Techniques: Feature toggles for controller request handler methods works well in the small but failed for our large project. We have too many snowflakes, customized replumbing of Spring and Boot, and destructive interference forced another path. So we went with AOP, the magical fallback in such situations, a pity.

But help is on the way!

The Togglz project is close to an official solution for the 2.3.0 release (no timeline announced). I am pleased with the solution taken and contributed a small bit. Here's the documentation commit. Please try 2.3.0-RC1 when it goes to Maven Central.

Modern maven

I've pushed my first release of Modern-J, a maven archetype (project starter), to github. Mostly this is for myself, to have a decent maven archetype for starting spikes and projects.

One thing I learned about maven is dealing with version mismatch in dependencies. The technique is not to modify <dependency> blocks with exclusions but to add a <dependencyManagement> block:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

(My POM sets "junit.version" to 4.12.)

This resolves the dependency mismatch between current JUnit (4.12) and the JUnit for System-Rules (4.11), a wonderful JUnit @Rule I hope to see eventually bundled with JUnit itself.

UPDATE: Hat tip to Qulice who beat me there first, though I'm not as strict.

Sunday, February 14, 2016

Java generic exception specifiers

I'm not sure it's widely appreciated that throws clauses can take generic parameters, just as return type or arguments. You can leverage this to improve your error handling. Note the helpful type inference provided by the compiler:

public final class ErrorHandlingMain {
    public static void main(final String... args) {
        final Result<String, RuntimeException> fooResult
                = success("foo");
        final Result<String, Exception> barResult
                = failure(new IOException("bar")); // Note #1

        out.println(fooResult.get());  // Note #2
        out.println(get(fooResult));   // Note #3
        try {
            out.println(barResult.get());  // Note #4
        } catch (final Exception e) {
            out.println(e);
        }
        try {
            out.println(get(barResult));
        } catch (final Exception e) {
            out.println(e);
        }
    }

    public static <T, E extends Exception>
    T get(final Result<T, E> result)
            throws E {
        return result.get();
    }

    @FunctionalInterface
    public interface Result<T, E extends Exception> {
        T get()
                throws E;

        static <T> Result<T, RuntimeException>
        success(final T value) {
            return () -> value;
        }

        static <T, E extends Exception> Result<T, E>
        failure(
                final E exception) {
            return () -> {
                throw exception;
            };
        }
    }
}

(Unusual formatting to help with screen width.)

  1. Note type widening from IOException to Exception. Reversing those types won't compile.
  2. Compiler sees RuntimeException, does not require try/catch.
  3. Likewise for static methods.
  4. Compiler sees Exception, requires try/catch.

Sunday, January 10, 2016

Spring Techniques: Feature toggles for controller request handler methods

Maria Gomez, a favorite colleague, asked a wonderful question, "How can I have feature toggles on Spring MVC controller request handler methods?" Existing Java feature toggle libraries focus on toggling individual beans, or using if/else logic inside methods, and don't work at the method level.

Given a trivial example toggle:

@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface Enabled {
    boolean value();
}

I'd like my controller to work like this:

@RestController
@RequestMapping(PATH)
public class HelloWorldController {
    public static final String PATH = "/hello-world";

    private static final String texanTemplate = "Howdy, %s!";
    private static final String russianTemplate = "Привет, %s!";
    private final AtomicLong counter = new AtomicLong();

    @Enabled(true)
    @RequestMapping(value = "/{name}", method = GET)
    public Greeting sayHowdy(@PathVariable("name") final String name) {
        return new Greeting(counter.incrementAndGet(),
                format(texanTemplate, name));
    }

    @Enabled(false)
    @RequestMapping(value = "/{name}", method = GET)
    public Greeting sayPrivet(@PathVariable("name") final String name) {
        return new Greeting(counter.incrementAndGet(),
                format(russianTemplate, name));
    }
}

(Greeting is a simple struct turned into JSON by Spring.)

To make the example a little more sophisticated, I'd like to use a "3rd-party library" to decide on which features to activate (think "Togglz" or "FF4J", say):

@Component
public class EnabledChecker {
    public boolean isMapped(final Enabled enabled) {
        return null == enabled || enabled.value();
    }
}

Originally I investigated Spring's RequestCondition classes, thinking I could do the same as @RequestMapping(... match conditions ...). However, this is tricky! Spring uses these conditions to decide which method to invoke for each HTTP request, not when deciding which methods should be treated as the handler for a given HTTP path. Taking this route, Spring complains at wiring time of duplicate handlers for the same request path.

The right way is to control the initial wiring of request handler methods, not decide later. First extend RequestMappingHandlerMapping (what a mouthful!):

public class EnabledRequestMappingHandlerMapping
        extends RequestMappingHandlerMapping {
    @Autowired
    private EnabledChecker checker;

    @Override
    protected RequestMappingInfo getMappingForMethod(final Method method,
            final Class<?> handlerType) {
        final Enabled enabled = findAnnotation(method, Enabled.class);
        final boolean mapped = checker.isMapped(enabled);
        return mapped ? super.getMappingForMethod(method, handlerType) : null;
    }
}

Note this is not directly a bean (no @Component). We need one more bit, to override the factory method that creates these handler mappings:

@Configuration
public class EnabledWebMvcConfigurationSupport
        extends WebMvcConfigurationSupport {
    @Override
    protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
        return new EnabledRequestMappingHandlerMapping();
    }
}

And Bob's your uncle. EnabledWebMvcConfigurationSupport ensures the returned ReqeustMappingHandlerMapping is injected, and so the "3rd-party library" is available to consult.

Full code in Github.

Wednesday, December 23, 2015

Looking for problematic logging with JUnit

Stefan Birkner's System Rules is one of my favorite JUnit extension libraries. I commonly use it to verify System.out and System.err, for example validating audit trail logging.

Growing tired of the same boilerplate, I rolled some simple rules into an aggregated JUnit @Rule, called NiceLoggingRule. It enforces:

  • No logging to System.err
  • No WARN or ERROR logging to System.out

A more sophisticated version would let the user decide on more than "log level" as to what is an acceptable log line, but it gives a good demonstration of writing complex JUnit rules:

public final class NiceLoggingRule
        implements TestRule {
    private static final Pattern NEWLINE = compile("\n");

    private final SystemOutRule sout = new SystemOutRule().
            enableLog().
            muteForSuccessfulTests();
    private final SystemErrRule serr = new SystemErrRule().
            enableLog();

    private final Pattern logLinePattern;
    private final Predicate<String> problematic;
    private final RuleChain delegate;

    public NiceLoggingRule(final String logLinePattern,
            final Predicate<String> problematic) {
        this.logLinePattern = compile(logLinePattern);
        this.problematic = problematic;
        delegate = outerRule(NiceLoggingStatement::new).
                around(sout).
                around(serr);
    }

    @Override
    public Statement apply(final Statement base,
            final Description description) {
        return delegate.apply(base, description);
    }

    private final class NiceLoggingStatement
            extends Statement {
        private final Statement base;
        private final Description description;

        private NiceLoggingStatement(final Statement base,
                final Description description) {
            this.base = base;
            this.description = description;
        }

        @Override
        public void evaluate()
                throws Throwable {
            base.evaluate();
            checkSystemErr(description);
            checkSystemOut(description);
        }

        private void checkSystemErr(final Description description) {
            final String cleanSerr = serr.getLogWithNormalizedLineSeparator();
            final List<String> errors = NEWLINE.splitAsStream(cleanSerr).
                    collect(toList());
            if (!errors.isEmpty())
                fail("Output to System.err from " + description + ":\n"
                        + cleanSerr);
        }

        private void checkSystemOut(final Description description) {
            final String cleanSout = sout.getLogWithNormalizedLineSeparator();
            final List<LogLine> problems = NEWLINE.splitAsStream(cleanSout).
                    map(LogLine::new).
                    filter(LogLine::problematic).
                    collect(toList());
            if (!problems.isEmpty())
                fail(problems.stream().
                        map(Object::toString).
                        collect(joining("",
                                "Problems to System.out from " + description
                                        + ":\n", "")));
        }
    }

    private final class LogLine {
        @Nonnull
        private final String line;
        @Nonnull
        private final String level;

        private LogLine(@Nonnull final String line) {
            final Matcher match = logLinePattern.matcher(line);
            if (!match.find()) // Not match! Ignore trailing CR?NL
                fail(format(
                        "Log line does not match expected pattern (%s): %s",
                        logLinePattern.pattern(), line));
            this.line = line;
            level = match.group("level");
        }

        public boolean problematic() {
            return problematic.test(level);
        }

        @Override
        public String toString() {
            return line;
        }
    }
}

For example, using it with Spring Boot's default log pattern one might write a factory helper:

public final class SpringDefaultNiceLoggingRule {
    private static final String logLevels = Stream.of(LogLevel.values()).
            filter(level -> OFF != level).
            map(Enum::name).
            collect(joining("|"));

    public static NiceLoggingRule springDefaultNiceLoggingRule() {
        return new NiceLoggingRule(
                "^(?<timestamp>\\d{4,4}-\\d{2,2}-\\d{2,2} \\d{2,2}:\\d{2,2}:\\d{2,2}\\.\\d{3,3}) +(?<level>"
                        + logLevels + ") +",
                SpringDefaultNiceLoggingRule::problematic);
    }

    private static boolean problematic(final String level) {
        return 0 > INFO.compareTo(LogLevel.valueOf(level));
    }
}

Then a simple Spring Boot unit test becomes:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MockServletContext.class)
public final class RootControllerTest {
    @Rule
    public final NiceLoggingRule niceLogging = springDefaultNiceLoggingRule();

    private MockMvc mvc;

    @Before
    public void setUp()
            throws Exception {
        mvc = standaloneSetup(new RootController()).build();
    }

    @Test
    public void shouldGetRoot()
            throws Exception {
        mvc.perform(get("/").
                accept(APPLICATION_JSON_UTF8)).
                andExpect(status().isOk()).
                andExpect(jsonPath("$.message", equalTo("Hello, world!")));
    }
}

Saturday, December 19, 2015

Spring REST showcase

I've noodled for some time now at mini-projects showcasing Spring REST with as many bells and whistles as I could pack in before it broke. I've never reached a satisfactory conclusion, which is more a testament to my mercurial temperament than to Spring. My ideal project would include:

  • No XML, if avoidable (Lombok, I'm looking at you)
  • No properties files (thank you, Spring YAML support)
  • Annotations and code generation (thank you, Spring Boot and Lombok)
  • Good documentation (Swagger and RAML, why do you need to be so tricky?)
  • Complete REST adherence (HATEOAS, you are still an ugly child, sorry to say that)
  • Modern Java
  • No external container (Spring Boot to the rescue!)
  • Many example integration points (and this is why I stay with you Spring)
  • Maven build (sorry Gradle, I gave up makefiles so I would never again debug my build)
  • Production support (Spring actuator: genius; see OSI)
  • Cloud support
  • Full CD pipeline (Boxfuse, you may save me yet; Github and Travis, you're still the best)

Essentially I want to implement a showcase REST microservice adhering to Larry Wall's three great virtues of a programmer: Laziness, Impatience and Hubris.

Well, there's always yet another Github repo.

Updates I'll keep updating this post as I find new things to desire in a showcase project.

Friday, November 06, 2015

Wrong, but technically right

tldr; — Immutable objects should have all-final fields.

I'm reading one of those "interview questions" posts and this jumped out at me:

Question 3: Does all property of Immutable Object needs to be final? (answer) Not necessary, as stated above you can achieve same functionality by making member as non-final but private and not modifying them except in constructor. Don't provide setter method for them and if it is a mutable object, then don't ever leak any reference for that member. Remember making a reference variable final, only ensures that it will not be reassigned a different value, but you can still change individual properties of object, pointed by that reference variable. This is one of the key point, Interviewer like to hear from candidates.

This is unfortunate. Although technically true, in my experience I've found the non-final case to come up <1% of the time. It's terribly misleading for less experienced developers to see an answer like this without having the context that goes with it.

To understand why I'm trepidatious, you can't go wrong with the C2 wiki on value objects. The right pattern for immutable objects in Java goes something like:

@EqualsAndHashCode
@RequiredArgsConstructor(staticName = "valueOf")
@ToString
public final class HiMomImImmutable {
    public final int i;
    public final String s;
}

Here I use Lombok annotations as shorthand for the equivalent Java code. If you're not familiar with Lombok, please become so—it's both a time-saver and a bug-killer in your code.

Lombok has a @Value annotation for these. However I disagree that with their choice that fields should be private and accessed with getters. To me this makes sense when consuming frameworks requiring bean-like getters, but not otherwise.

Back to the post, the author's answer is unclear: he mentions modifying final fields in the constructor. But of course, any field marked final may be assigned in the constructor—must be so assigned—if not initialized in declaration. Then if you have complex logic to initialize (itself a code smell), try this:

public SomeClass(/* args */) {
    this.someField = aStaticMethod(/* some other args */);
}

This encapsulates the initialization logic in a static method as the final field may be initialized only once, and not referred to before initialization.

Monday, October 26, 2015

Approximating tuples in Java

What is a tuple? It's an ordered collection of individually typed elements. Wikipedia has a complicated explanation that comes down to the same thing in the context of ordinary programming. The Python implementation of tuples is a good example.

There are many related concepts, such as:

Arrays and lists
Ordered but all elements are the same type
Ordered dictionaries (maps)
Ordered but all values are of the same type, and they are named
Aggregates (structs, unions)
Individually typed but named and unordered

The closest matches to tuples in current Java are "structs" (more below) and arrays or lists, each with drawbacks. For most use of tuples, arrays and lists are non-starters: elements are all of the same nominal type. There is a lot of thought around how to do this best in Java.

What do I mean by saying Java has "structs" ala "C"? The vast bulk of Java code hides fields away with private, but exposes them with getter methods (and setters when non-final). This is the "Java Bean" anti-pattern. An alternative is to simply expose fields directly:

public final class CartesianPoint {
    public final int x;
    public final int y;

    public CartesianPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

This is almost a tuple. However:

  • CartesianPoint extends java.lang.Object but should not be an object in the OOP sense
  • Elements are accessed by name, e.g., point.x, rather than position
  • Elements are unordered—you cannot write a general function to process the first and second elements of the tuple without knowing 1) the struct type and 2) the names of the fields

But for many use cases this can be close enough, for example as a return type to simulate multiple value return. Hopefully Java 10 brings value types which resolves the java.lang.Object issue. This may even bring true tuples!

This example can be improved with Lombok:

@EqualsAndHashCode
@RequiredArgsConstructor(staticName = "valueOf")
@ToString(includeFieldNames = false)
public final class CartesianPoint {
    public final int x;
    public final int y;
}

Calling code would look like:

public CartesianPoint locate() {
    int x = computeX();
    int y = computeY();

    return CartesianPoint.valueOf(x, y);
}

Notice the visual similarity of the local variables x and y to the corresponding fields in CartesianPoint. Users of CartesianPoint would see:

public static void main(final String... args) {
    Boat boat = Boat.rowBoat();
    CartesianPoint point = boat.locate();

    out.printf("%s -> x is %d, y is %d%n", point, point.x, point.y);
}

$ ./float-boat 1 2
CartesianPoint(1, 2) -> x is 1, y is 2

If you want to go hog wild, the ordered and unnamed qualities of tuples can be simulated though not without significant noise:

Function<CartesianPoint, Integer> first = p -> p.x;
Function<CartesianPoint, Integer> second = p -> p.y;

out.printf("first is %d, second is %d%n",
        first.apply(point),
        second.apply(point));

Update

Streaming functionally:

Function<CartesianPoint, Integer> first = p -> p.x;
Function<CartesianPoint, Integer> second = p -> p.y;
Stream.of(first, second).
    map(f -> f.apply(point)).
    forEach(out::println);