Git: Create a new, empty and unrelated branch

I wanted to start publishing to GitHub Pages from my learning and experimenting project simple-meetup. One of the learning scopes of the above project is “code as documentation” and the question to which extend such a project can be used to write articles and generate documentation. In this project I’m using Asciidoctor and the Gradle Plugin as suggested by my friends Ralf and Gernot in their column Hitchhiker’s Guide to Docs as Code and corresponding repo.

GitHub Pages can be setup separately for every repository and you can choose to select a branch for your HTML-files. As I didn’t plan this upfront, I obviously didn’t have an empty branch for that and I didn’t want to create one and have all the other commits in it. Enter --orphan for the checkout-command:

--orphan
Create a new orphan branch, named , started from and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits.

The index and the working tree are adjusted as if you had previously run “git checkout “. This allows you to start a new history that records a set of paths similar to by easily running “git commit -a” to make the root commit.

See checkout --orphan.

Run git checkout --orphan gh-pages and you’ll end up with a new branch called gh-pages with all the files you have staged, but they can be safely removed with git rm -rf . and then the branch can be committed and pushed.

If you’re wondering what I am doing with that branch: Part of the build are ideas from the docToolchain. I am generating articles with this stance in Gradle:

tasks.withType(AsciidoctorTask) { docTask ->
    dependsOn check
 
    attributes \
          'sourceDir': "$projectDir/src/"
 
    sourceDir = new File("src/articles")
    outputDir = new File(project.buildDir, "articles")
    resources {
        from(sourceDir) {
            include '*.png'
        }
    }
}
 
task generateHTML (
        type: AsciidoctorTask,
        description: 'use html5 as asciidoc backend'
) {
    backends = ['html5']
}
 
defaultTasks "clean", "build", "generateHTML", "generatePDF"

This generation is an essential part of the build and it runs by default. In my Travis CI script I have the following after_success hook:

after_success:
- cd build/articles/html5
- git init
- git config user.name "${GH_USER_NAME}"
- git config user.email "{GH_USER_EMAIL}"
- git add . ; git commit -m "Deploy to GitHub Pages"
- git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:gh-pages

It changes to the output directory, reinitializes the repository there and force pushes the new master to the remote gh-pages branch. The variables are my GitHub username and a token I created for the purpose of having Travis to be able to push.

| Comments (0) »

09-Dec-17


November recap and Java quickies

November has been a crazy month. Even though I joined Ralf in his Movember team and grew a mustache, I visited the JUG Münster at LVM Münster and gave my talk about SQL once again in a slightly updated version:

It felt very good being part of innoQ on this occasion.

Also very nice was the mentioning of my latest short tutorial in this week in spring.

Communications

What didn’t feel too good was the passing of my dear god father and especially his sad funeral. It really brought me down. As a result, I was in a bad mood for the last week and somewhat impatient and angry. Further down the road, communication got hard.

I already have been thinking a lot lately about communication problems and why they are so hard to solve in our business. As soon as things stress up (in a bad way), communication goes haywire. Often people build walls around themselves, myself included, and suddenly a bunch of good people who could form a good team, don’t. My friend and colleague Alex has written a great article (in German) on micro services, but honestly, it’s way more about various forms of communication as well. Check it out here.

While I tend to say I wanna do something with programming but without humans, the opposite is true. I love to listen, a good discussion, exchanging thoughts. Looking back at the past day, I spent several hours discussing options with the technical lead of our customer to evolve a platform and to onboard a new colleague into the project and the hours were well spent.

Spring Boot Buch

As hoped in last months recap, I got the preface from Jürgen himself and the book is somewhat jürgenized now.

The book itself is 95% done. It’s copy edited, spellchecked and ready to be set, but we are awaiting at least one release candidate of Spring Boot 2, which will see the light this month (December). I already did some changes on the Actuator parts and will do some big changes due to Spring Security 5. I have all the examples at GitHub. If you find something that doesn’t work, please let me know.

Java quickies and new, small projects

2 weeks ago I got nerd-sniped by Lukas, after complaining on twitter that I don’t have the amazing Spring Boot configuration mechanism for a task at hand. He proposed to just build it myself with plain JDK. I didn’t succeed fully, but did some nice, low-level stuff to map properties to classes. While working on that, I wrote this and some more in the pipeline. As I am a bit astonished how “new” Java 8 concepts still are for some, I will publish them the next months.

I have some new smaller projects:

The last project, AssertJ demos, come from experiments with AssertJ, both in the simple-meetup project as well as at the customers.

AssertJ got me while solving the following problem. Imagine this weird service, written in Java 9 but what was the other drinking while designing this return types?

public class WeirdService {
    public Object getSomething() {
        throw new UnsupportedOperationException("This is unsupported");
    }
 
    public Object getAString() {
        return "Hello";
    }
 
    public Object getTheRightThing() {
        return List.of(
            Map.of("firstName", "Michael", "lastName", "Simons"),
            Map.of("firstName", "Christina", "lastName", "Simons"),
            Map.of("firstName", "Anton", "lastName", "Simons"),
            Map.of("firstName", "Oskar", "lastName", "Simons")
        );
    }
}

AssertJ solves testing this freakish thing in every aspect:

class WeirdServiceTest {
 
    final WeirdService weirdService = new WeirdService();
 
    @Test
    @DisplayName("What to do? JUnit 5 or AssertJ?")
    public void demonstrateExceptionHandling() {
        // JUnit 5
        UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class, () -> weirdService.getSomething());
        assertEquals("This is unsupported", e.getMessage());
 
        // AssertJ
        assertThatThrownBy(() -> weirdService.getSomething())
            .isInstanceOf(UnsupportedOperationException.class)
            .withFailMessage("This is unsupported");
    }
 
    @Test
    @DisplayName("Sometimes you have service that is just… weird… 🤡 Here it returns objects")
    public void niceTypeChecks() {
        assertThat(weirdService.getAString())
            .isInstanceOf(String.class)
            .asString()
            .isEqualTo("Hello");
 
        assertThat(weirdService.getTheRightThing())
            .isInstanceOf(List.class)
            .asList()
            .extracting("firstName")
            .containsExactly("Michael", "Christina", "Anton", "Oskar");
    }
}

First, look at the beautiful exception testing. I even find it nicer than the JUnit 5 way of doing stuff. And then, checking the returned type of the service, which comes with an elegant casting and then: extracting stuff from results is smart: It either works on properties or in this case, on map keys.

I collapsed several multi-page tests with that stuff into small chains of method calls. If you’re into testing, go have a look at AssertJ. Together with JUnit 5s possibilities to write the tests itself, its a great way to gain trust into your code.

| Comments (0) »

01-Dec-17


Wildly unused helper: EnumSet

Available since Java 1.5 is the nice helper class EnumSet and I still find code like this way to often:

public class Foo {
   enum Thing {
      A, B, C
   }
 
   public static final Set<Thing> THINGS = new HashSet<>();
   static {
      THINGS.add(Thing.A);
      THINGS.add(Thing.B);
      THINGS.add(Thing.C);
   }
}

With Java 9 you could write Set.of(Thing.A, Thing.B, Thing.C) but then you’d miss the optimizations done for enums:

Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based “bit flags.” Even bulk operations (such as containsAll and retainAll) should run very quickly if their argument is also an enum set.

As my friend Mark pointed out, it runs in O(1) for small to medium sets:

So, replace the above with

public class Foo {
   enum Thing {
      A, B, C
   }
 
   public static final Set<Thing> THINGS = EnumSet.allOf(Thing.class);
}

Or, if you need immutability, throw in Collections.unmodifiableSet(EnumSet.allOf(Thing.class));. Read operations are passed through anyway.

| Comments (0) »

22-Nov-17


Integration testing with Docker-Compose, Gradle and Spring Boot

This post has been featured on This Week in Spring – November 28th, 2017.

Lately I have been preparing a small project called simple-meetup that I plan to use for different purposes. You’ll find the repository at GitHub: github.com/michael-simons/simple-meetup. It’s the first project where I used Gradle very intensive and I like my build file a lot.

The first intention of this repository is being an example for an article for OBJEKTSpektrum on testing. The project used JUnit 5 at the beginning, but I switched back to 4 for various reasons, which I explain in a follow up. Thanks upfront to Christian Stein, JUnit 5 committer and contributor, for your interest and feedback on this!

I already wrote about integration testing with Docker and Maven. In that post I used the docker-maven-plugin to fire up supporting services for my tests.

While researching similar options to use with Gradle, I stumbled upon this post by Thomas Kieffer from Codecentric. He describes the docker-compose-role in detail. This rule is a JUnit 4 rule designed to start containers defined in a docker-compose.yml before tests and tearing them down afterwards and also waiting for services to become available before running tests.

This is quite nice, as it doesn’t make your tests dependend on the build tool itself. There is activity to make this available as JUnit 5 extension as well, see #138.

While Thomas demonstrated a generic approach, I’d like to show you how to use this with Spring Boot and replace Spring Boot properties at the right point before the Spring context gets refreshed.

For my meetup project, I need a database and I want to run integration tests against the “real deal”. Here’s my Docker-Compose file:

And this is what the integration tests looks like:

@RunWith(SpringRunner.class)
@ActiveProfiles("it")
@DataJpaTest
@ContextConfiguration(initializers = PortMappingInitializer.class)
public class EventRepositoryIT {
 
    private static DockerComposeRule docker = DockerComposeRule.builder()
        .file("src/integrationTest/resources/docker-compose.yml")
        .waitingForService("it-database", HealthChecks.toHaveAllPortsOpen())
        .waitingForService("it-database", PostgresHealthChecks::canConnectTo)
        .build();
 
    @ClassRule
    public static TestRule exposePortMappings = RuleChain.outerRule(docker)
        .around(new PropagateDockerRule(docker));
 
    // Actual tests omitted
}

Two things to notice: First I didn’t use the DockerComposeRule as a class rule. Instead, I used a chain of JUnit rules. A rule chain works from outer to inner rules. The declaration public static TestRule exposePortMappings = RuleChain.outerRule(docker).around(new PropagateDockerRule(docker)) says: Apply the docker-compose-rule first and then an instance of PropagateDockerRule. Second: I apply ContextConfiguration with an instance of Springs ApplicationContextInitializer, dubbed PortMappingInitializer.

The initializers are called just before the Spring Boot context gets refreshed and autoconfiguration kicks in. What my initializer does is getting the instance of the docker compose rule out of a thread local and reads the name of all services and the mapped ports from it:

The important part is the usage of `TestPropertySourceUtils`. I use it to add inline properties to the environment. Those test properties have higher priority than any other properties except the devtools properties.

The purpose of the PropagateDockerRule is then plain and simple: It stuffs the current instance of the docker compose rule into the thread local:

That way, I can use inlined properties like this: spring.datasource.url = jdbc:postgresql://localhost:${it-database.port}/postgres. Spring Boot and it’s starters use it to point my database agains the instance I just started. The project repo includes additional health checks, but that’s all there is. The test database would also be subject to initialization, wether one uses Flyway, Liquibase or a simple schema or data script.

What’s nice about the setup is that I can fire up the test from my IDE, regardless of the build-tool. While one can usually run single Unit tests from the IDEs out there, its more complicated to run a single failsafe-based integration test with Maven.

| Comments (4) »

20-Nov-17


Past summer: October wrap-up

This year, time flies. Writing this post at about 7pm, it’s already dark. October had some brilliant moments regarding weather and I enjoyed the golden autumn very much. As announced last month, I send the “final” manuscript of Spring Boot Buch to dpunkt.verlag in the last week of September. 2 weeks later, I received three packets full of paper. 500 pages, with a lot of red corrections and annotations. I worked together with my fantastic wife Christina through the paper and fixed the LaTeX sources of the book. We still had to update some examples. There’s still so much change going on in Spring land. Whereas last month I had to update huge amounts of the Actuator chapter, it’s Spring Security this time. See the announcement of 5.0.0.M5. I just had it fixed and added a new starter (spring-boot-starter-security-reactive) and about 2 weeks later, it disappeared. So right now, I just didn’t bother fixing it again, because the finished correction (spelling and grammar that is) of the book was send to my publisher. The agreement we have is that the layout will be done now and the chapters marked as “will probably change” are done last. In the end, you can preorder the book right now: Preorder Spring Boot 2: Moderne Softwareentwicklung mit Spring 5, it will be published in time in January 2018.

My book will include a preface by Jürgen Höller himself. Jürgen and I met at Topconf last week, where he held a closing keynote and spoke about (literally) a life in Open Source. I like the non technical keynote and the inside a lot. Jürgen recently was awarded with the JAX Special Jury Award at JAX London for his work for Spring and I am more than happy to have him in my book:



I was in Darmstadt this month and spoke about Spring Boot myself:

Jörn Hameister wrote an excellent post about my content, thanks a lot! For that talk I prepared a new starter, that might come in handy for some with the release of Spring Boot 2.

The JUG Darmstadt meeting was great, meeting my friends Gerd, Ralf und Niko. Nikos Serverlessbuch is already finished and I’m currently reading the one he gave me as a gift. I’m really happy to be in his preface 🙂

The slides above are my first slides bearing innoQ logos and colors. I was so nervous (actually, I was a wrack) by the end of September. Departing the old company took his toll and being afraid if innoQ and consultancy would work for me and in what setting. I had a hard time thinking straight. Right now I’m with a customer in Aachen and actually not doing Spring. Despite that, I’m learning a lot thanks to a great internal slack and from my innoQ colleague Jerry. Wether it’s technology, domain, you name it. There seems to be an expert for everything. I’m really happy about the development. And what is also great is the fact that discussions, with colleagues and also customer, are really high level with mutual respect. At the moment, I’m happy and I feel finally good again. Looking forward to the coming weeks.

| Comments (1) »

28-Oct-17