Showing posts with label lambdas. Show all posts
Showing posts with label lambdas. Show all posts

Monday, 3 June 2024

Kotlin Scope Functions

Scope function examples below:

  • let
  • with
  • run
  • apply
  • also
  • takeIf and takeUnless
  • Using them all at the same time!!!

I really hope I'm not the only one that gets confused about the different Scope functions1 in Kotlin and what they mean and when to use what.

The reference in [1] is excellent, but if I have to look up documentation on what certain methods do, the methods are not very well named.

So, in short, here's some examples, actually gleaned from the documentation and given my own spin on it with things that actually make sense.

Let

    /**
     * Useful if you do not wish to assign the result to an intermediate variable.
     * Useful with ? in case the result is NULL.
     */
    fun getDescription(address: Address?): String? =
        address?.let { address.getDescription() }

With

    /**
     * "with this object, do the following."
     * We're not interested in the result.
     */
    @Test
    fun withTest() {
        with(addressInEngland) {
            assertThat(street).isEqualTo("Morsestreet")
            assertThat(city).isEqualTo("London")
        }
    }

    /**
     * "with a helper object, do the following."
     */
    @Test
    fun withHelperTest() {
        val description = with(addressHelper) {
            computeAddress(addressInEngland)
        }
        assertThat(description).isEqualTo("12 Morsestreet London")
    }

Run

    /**
     * "run the code block with the object and compute the result."
     * Nice if you need to use it in an expression.
     */
    @Test
    fun runAsExtentionFunctionTest() {
        val didItWork: Boolean = database.run {
            val address = retrieveAddressFromDatabase()
            addressInAmerica.pobox = "43000"
            updateInDatabase(addressInAmerica)
        }
    }

    /**
     * "run the code block and compute the result."
     * Does not have a "this" or "it". Nice if you need to use it in an expression.
     */
    @Test
    fun runAsNonExtentionFunctionTest() {
        val didItWork = run {
            val address = database.retrieveAddressFromDatabase()
            with(shippingService) {
                sendItemToAddress(address)
            }
            log("Item sent")
            success
        }
    }

Apply

    /**
     * "apply the following assignments to the object."
     * The most common use case is object configuration, as below.
     */
    @Test
    fun applyTest() {
        val sameObject = Address().apply {
            housenumber = 12L
            street = "Morsestreet"
            city = "London"
        }
    }

Also

/**
     * "and also do the following with the object."
     * A common use case is to also assign the object to a property/variable.
     */
    private fun createHomeAddress() =
        Address().apply {
            housenumber = 12L
            street = "Morsestreet"
            city = "London"
        }
            .also { homeAddress = it }

TakeIf and TakeUnless

    /**
     * "return/use the value if this condition is true"
     * The opposite is takeUnless.
     */
    @Test
    fun takeIfTest() {
        assertThat(addressInEngland.takeIf { it.state != null }).isNull()
        assertThat(addressInAmerica.takeIf { it.state != null }).isEqualTo(addressInAmerica)
    }

And now for the big one!!!

    /**
     * Let's try all of them at the same time!
     */
    @Test
    fun allScopesTest() {
        val mailingSentForNewAddress = Address()
            .apply {
                housenumber = 12L
                street = "N. High Street"
                city = "Columbus"
                state = "Ohio"
                country = "United States of America"
            }
            .also {
                homeAddress = it
                with(database) {
                    updateInDatabase(it)
                }
            }
            .takeUnless { mailingAlreadySent(it) }
            ?.run {
                sendMailing()
                log("Mailing sent to ${getDescription()}.")
                success
            } ?: false

        val mailingSentForAddress =
            with(addressInEngland) {
                takeUnless { mailingAlreadySent(this) }
                    ?.run {
                        sendMailing()
                        log("Mailing sent to ${getDescription()}.")
                        success
                    } ?: false
            }
    }

Here I have tried to make use of the Scope functions in such a way that the different operations make sense.

P.S. I take offence on using "it" as the automatic name for the argument of the lambda. It sounds too much like the old Java "int i" in for loops. In other words, "it" has no meaning and the meaning depends entirely on context.

There's too much "it" and too much "this" and the context switching when using several Scope functions makes my head hurt.

References

[1] Kotlinlang.org - Scope Functions
https://kotlinlang.org/docs/scope-functions.html#functions

Thursday, 30 November 2023

Refactoring

So, I saw some code that I didn't like, and I decided to refactor it.

The code was thusly.

public boolean onLeave() {
    boolean valid = super.onLeave();
    Account account = database.getAccount();
    ShoppingList shoppingList = database.getShoppinglist(account);
    if (valid) {
      valid = !shoppingList.isEmpty();
    }
    if (valid) {
      valid = !blockedAccounts.contains(account);
    }
    if (valid) {
      String country = account.getPerson().country();
      valid = webshop.alsoShipsTo(country);
    }
    if (valid) {
      valid = account.hasCreditcardAttached() ||
          account.hasPrepaidcardAttached() ||
          account.hasCash();
    }
    return valid;
  }

And I thought to myself, it's really just a list of expressions, where each one is evaluated until you find one that evaluates to false, and then you stop.

So, that's basically a Stream where you filter out all the "false" values, and get the first one.

So, I decided to refactor it just like that.

public boolean onLeave() {
    Account account = database.getAccount();
    ShoppingList shoppingList = database.getShoppinglist(account);

    List<Supplier<Boolean>> checks = new ArrayList<>();
    checks.add(super::onLeave);
    checks.add(() -> !shoppingList.isEmpty());
    checks.add(() -> !blockedAccounts.contains(account));
    checks.add(
        () -> {
          String country = account.getPerson().country();
          return webshop.alsoShipsTo(country);
        });
    checks.add(() -> account.hasCreditcardAttached() ||
        account.hasPrepaidcardAttached() ||
        account.hasCash());

    return checks.stream()
        .filter(t -> t.get().equals(Boolean.FALSE))
        .findFirst()
        .isEmpty();
  }

I proudly showed this to my colleagues, and they immediately shook their heads in disgust.

Apparently, in my eagerness to use Lambdas and Streams and all that cool stuff, what I really had done is recreated the short-circuit version of an If statement in Streams.

I find myself turning to Lambdas and Streams when in reality these are not needed, and my eventual solution works fine without them.

So, rewriting this as a short-circuited IF statement looks like this:

public boolean onLeave() {
    Account account = database.getAccount();
    ShoppingList shoppingList = database.getShoppinglist(account);

    return super.onLeave() &&
        !shoppingList.isEmpty() &&
        !blockedAccounts.contains(account) &&
        webshop.alsoShipsTo(account.getPerson().country()) &&
        (account.hasCreditcardAttached() ||
            account.hasPrepaidcardAttached() ||
            account.hasCash());
  }

Granted, a few more and my IntelliJ will start to complain about the number of expressions in the if statement, and it's possible to clean it up a little by creating separate methods for some of the expressions. But I feel it looks fine.

So, in conclusion, just because you know something cool and shiny, it's no reason to try and use it everywhere!

It is a corrolary that in order to properly use something, you must have some knowledge or experience of when and where it's best to be used.

Friday, 24 May 2019

Abuse of Lambdas

So, sometimes when you have an existing software structure, with lots of domain rules inside, it becomes difficult to change. Especially when there is a lot of cohesion between your classes.

This is the problem of tight coupling, as opposed to loose coupling1.

I recently encountered this in our software.

And of course, I needed to change something deep inside.

Now, I didn't need to change anything about the domain logic. It was very good and working as intended.

But I needed a change purely for technical reasons. In this case, the domain logic was used in a Batch Processing on Hibernate Entities, and the domain logic was (in this case, not normally) generating a lot of Entities, and they were all persisted in the Session Context, which naturally grew. And then the dirty check and the session closing takes a long time, etc, etc. See reference [2] on why this's bad.

So I was looking for a way to persist entities, without adding them to all the collections with the CascadeType without changing the domain logic too much, and also keep the default behaviour as standard.

I didn't want to use inheritance, as it was a persisted Hibernate Entity.

So, I came up with the following hack:

Quite simply, I can now add behaviour to an Entity when I need it.

For example:

As me and my colleague say "A seemingly innocent first step on a slippery slope to hell."

Of course, this kind of abuse has always been possible, but it is now easier to do than ever (without having to create an entire class for the priviledge).

References

[1] Wikipedia - Loose coupling
https://en.wikipedia.org/wiki/Loose_coupling
[2] Vlad Mihalcea - The best way to do batch processing with JPA and Hibernate
https://vladmihalcea.com/the-best-way-to-do-batch-processing-with-jpa-and-hibernate/

Friday, 16 February 2018

Turning a Stream into an Iterable

Recently I wanted to know how to change a stream into an Iterable. The method in the API that I need to call expects an Iterable.

I found the following solution in [1]:

public class RealEstateEvaluator
{
  public void evaluate(Session session, Iterable<House> iterable)
  {
    // do stuff
  }
}

public void realEstateEvaluation()
{
  Stream<House> housenumbersStream = 
    housenumbers.stream()
      .map(realEstateService::getHouse);   

  new RealEstateEvaluator().evaluate(getSession(), housenumbersStream::iterator);
}

However, [1] did mention that the result was unreadable. It is confusing that a method reference that provides an Iterator, perhaps accidentally, fulfills the contract for Iterable2.

That's right. Iterable is an interface3, which has three methods, two of which have default implementations. Which means it has one method (iterator()), which means it can be used as a Lambda expression.

I prefer:

public void evaluate()
{
  List<House> houses = 
    housenumbers.stream()
      .map(realEstateService::getHouse)
      .collect(Collectors.toList();   

  new RealEstateEvaluator().evaluate(getSession(), houses);
}

It is a lot more readable. And I am a big believer in the Principle of Least Surprise.

All Collections are Iterables, by the way.

Update 2018-02-23: after reading and evaluating the comment below, I still think using the method reference makes it harder to read, but is much safer to use. Perhaps getting used to using stream::iterator is just a question of time.

References

[1] LambdaFAQ - How do I turn a stream into an iterable
http://www.lambdafaq.org/how-do-i-turn-a-stream-into-an-iterable/
[2] StackOverflow - Why does stream not implement iterable
https://stackoverflow.com/questions/20129762/why-does-streamt-not-implement-iterablet
[3] Oracle JavaDoc - Iterable
https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html?is-external=true

Saturday, 29 October 2016

The Martingale using Lambdas

I created a small blog post some time ago regarding the Martingale System of Gambling.

In it, a programming example is available, which could be rewritten using the Lambda style in Java 8.

I am going to attempt doing just that and post my results below.

ForEach

When I was following the MOOC course of Oracle1, Simon Ritter quite emphatically mentioned trying not to use the foreach method when not required.

But let us try it now, as a seemingly perfectly reasonable first step on a slippery slope to hell.

What we need is a stream of random numbers, and then run the foreach on it.
So far, so good.

Still doesn't look very much better, and perhaps even a little bit worse.

Mapping

Let's try to make it better.

For this we are going to use an "Account" class. Like this:

This class will be used in the Lambda, like so:

Conclusion

Lambdas can make your code look a lot cleaner. However, they can never replace all the loops in your code, as witnessed in the example above.

I'd really like to use collect or reduce instead of the forEach in the example, but I don't think I can.

But if anyone has any suggestions on how to fix it, please tell me.

For the source code to the "Bet" class, check out https://gist.github.com/maartenl/a804f4ac435f491b57c7ae810d5fd577.

Peek and Debugging

Peek is very valuable if you wish to do some debugging of your new Lambdas.

Using the following:
new Random()
           .ints(0, 37)
           .peek(System.out::println)
           .mapToObj(x -> Bet.getBet(x))
           .peek(System.out::println)
           .forEach(x
                   ->
                   {
                     if (x == Bet.RED)
                     {
                       account.add();
                     } else
                     {
                       account.subtract();
                     }
           });

You get some nice output to see what's happening:
10
BLACK
29
BLACK
11
BLACK
19
RED
26
BLACK
34
RED
34
RED

References

[1] Oracle - Announcing: JDK 8 MOOC: Lambdas and Streams!
https://blogs.oracle.com/javatraining/entry/announcing_jdk_8_mooc_lambdas
[2] The Java™ Tutorials > Collections > Aggregate Operations - Reduction
https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
Wikipedia - Roulette
https://en.wikipedia.org/wiki/Roulette

Sunday, 9 November 2014

J-Fall 2014

Well, I have once again been privileged enough to attend the J-Fall 2014 on Wednesday, the 5th of November, in Nijkerk, the Netherlands.

I'll provide a short summary of the Breakout Sessions I followed, and the parts that really struck me as interesting. There's more information on the sessions available at [1].

My chosen schedule:

Keynotes

Bert Ertman, after 10 years at the NLJUG, has decided to step back and become a regular attendee of J-Fall. He is the most visible of the people behind J-Fall, as he has opened J-Fall, to the best of my knowledge, every year. Let us hope we shall see more of him and not less.

The Keynotes were not actually that interesting. The Keynote of Oracle was more related to awards for proven Java-ness, than what Oracle has planned for the future. The keynote of Oracle was provided by James Weaver, who was also giving a Session last year regarding JavaFX and guitar playing.

The Keynote of ING was surprisingly similar to last year, regarding the banks new way of working with software releases (Agile, Scrum, three releases every week, automated testing, DevOps, etc.)

The Keynote of Salves was interesting, in that it had a high geek-techy-factor, with drones flying, and brainwaves to control them, with pattern recognition in cameras. But the complexity of the setup, and the conference location and The Dreaded Demo Effect got to 'em, which is a shame.

I found the best Keynote to be the one provided by Quintor, a consultancy business started in 2005, regarding a simulated Cluster with Hadoop they set up during one of their "Summer Camps" to brute-force a Shortest Path Algorithm. They needed some penguins to find an igloo between ice blocks and rocks. They created "Willem", a server that was running 20 or so virtual environments, chained in a Hadoop cluster with Apache HBase as work memory and Akka Reactive Streams.

The Sessions

Event-sourced architectures with Akka

A great number of projects are always based around the idea of Shared Mutable State. This shared mutable state makes things very hard to scale, so it has traditionally been pushed to the database as far as possible. Stateless code always scales better, because it can be easily run parallel.

It seems to me that event-sourcing is basically based on the database transactionlog that has been in Databases for the past hundreds of years.

The idea is that we store the events that happened, instead of storing only the changes of data. In the latter case we lose a lot of history. In order to keep the side effects out of the way when replaying the event log, these are not re-done.

A simple example is, instead of storing Price and Orders, we store events like PriceChanged or OrderCancelled.

Of course, this presents problems as you have to rerun the event log in order to find out the current situation of the system. This is solved by creating snapshots.

Another problem is the fact that Searching for stuff becomes harder. So it makes sense to have basically two different modules, one module is responsible for changes (and stores events and the likes) and one module is responsible for querying and searching (and searches, for example, over Snapshots).

The abbreviation concerning this is called CQRS, Command Query Responsibility Segregation2. Here the command model is the eventstore (the "journal") and the query model can have several data stores, each containing for example snapshots.

It is possible to have the module that stores events present hooks to the searchmodule to keep the segregated models synchronised.

Some software that is used for the event model and storage of events are:
  • Cassandra
  • Kafka
  • DynamoDB
  • MongoDB
  • HBase
  • HBase
  • MapDB
  • JDBC
We can use Java Serialization, the default, or specific implementations of Java Serialization for example Protobuf, Kryo, Avro.

Akka can be used for all this, it provides a new experimental persistence module called appropriately Akka Persistence, that uses event sourcing.

Code can be found on github at https://github.com/sandermak/akka-eventsourcing. The url provided by Sander was http://bit.ly/akka-es, convenient for if the source moves.

One of the advantages, are that events show the business processes a lot better than normal persisted objects do. With events it is much more clear what is happening.

Conclusion is that event sourcing is very applicable to Domain Driven Design.

A word on versioning, a change in event-structure is going to cause a problem for the history (which uses the old event-structure). There are several solutions for this:
  • don't change your event structure (which, likely isn't possible)
  • use both old and new event-structure at the same time (which, introduces legacy code that needs to be maintained)
  • change ALL your events, also the historical ones (which, from a purity standpoint is debatable)
  • create a snapshot of the historical (old) events, and continue using new events henceforth (losing a bit of history)

I rated this as the best Session of the day!

Reactive programming with Java 8 and Java EE 7

Most of our programming is run sequentially, which, with the current advent of multiple cores, becomes inefficient (they say).

In Java 7 "Futures" were introduced to take care of doing things in parallel using ThreadPools.

A Future is a placeholder for a value that hasn't been set yet, but will (hopefully) be set in the future.

The Java API for Futures is very extensive with a lot of different classes containing a lot of different methods. In the future (my, was that a pun?) there might well come to the front a framework that abstracts away a lot of the nitty-gritty of this highly detailed API. Where the other sessions were light on the amount of code, this one more than made up for them.

Some codepoints:
  • ForkJoinPool.commonPool() => suited to the number of cores the JVM is running on.
  • Callable -> interface, provides a task to perform.
  • ManagedExecutorService -> for externally configurated threadpools for example in an application server like Glassfish. It is a part of JEE 7.
  • CompletableFuture -> takes care of Promise Pipelining. These may trigger actions.
The example provided was regarding Customer data, Contract data of that customer, and Communication data of that customer.

Modelling the flow (probably in a flow model) helps a lot, as you lose a lot of visibility on what the code is actually doing.

You tend to define/plan everything up front, with Futures, and then you start the ball rolling, so to speak, with the last call in the chain.

JAXRS 2.0 has the possibility to perform REST services Asynchronously. This can be done, using:
public void retrieve(@Suspended AsyncResponse response, ...
{
    response.resume...
}

HTTP connections are released during requests, this will lead to much better scalability. (HTTP threads can be re-pooled)

His source is on github at martijnblankestijn/reactive-rest-demo.
One diagram that basically says it all, where green is retrieval of customer information, and red and purple are contract data and communication data respectively of said customer:

Modularity and Domain Driven Design : a killer combination?

The idea of this session was to be serious about the standard software design pattern Separation of Concerns, where you have Loose Coupling and High Cohesion.

The reason why, is that the Cost of A Change should be predictable, and should not result in slowly escalating costs, regarding lost/unattainable deadlines or high maintenance.

The way to do this is with Functional Modularisation, because a functional change should only impact that functional module.

There should be few hard connections between domains, for example no Foreign Keys or the like.
There should be no query between modules, which is a problem when you wish to do some serious Search Queries. A query between modules and across several modules, causes these modules to be tightly coupled.

So, in other words, cross module searches should be postponed as long as possible.

When this isn't possible, you could use CQRS, Command Query Responsibility Segregation.

Elasticsearch can be used to do the searching.

All the modules can be queried individually by the SearchModule, and the SearchModule uses elasticsearch.

Hand-on-Labs: Hands-on with Java 8

This was fairly interesting. They decided on providing a lab on several features in Java 8: the Lambdas (of course), and the new DateTime API.

I've managed to nick their Lab and plan on practicing more of the assignments at home (there wasn't enough time for me at the conference, there were quite many of them).

Microservices: the how and why?

Unfortunately, this was a bit of a miss. I am stuck with no clear idea of what Microservices are exactly, but it seems to follow quite closely in the footsteps of the Session on Modularity.

Here are some book titles mentioned:
  • Domain Driven Design4 - Erik Evens
  • Release It!5 - Michael T. Nygard
  • Antifragile6 - Nassim Nicholas Taleb

Characteristics of Micro services:
  • small (1000 lines of code)
  • do one thing, and do it well (Unix philosophy)
  • independent
  • language agnostic communication
  • highly decoupled

Conway's Law3: organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations.

Basically what this means is that, for example, if you have three teams, one for the UI, one for the Middleware, and one for the database, you end up with a software product that uses a UI, a Middleware and a Database. If the entire team works on ONE microservice, you get the absolute best product. It also means you cannot have a standard team. It is SOA (Service Oriented Architecture) done right.

Missed Sessions

I was planning on visiting Hot migration of JSF to cool SPA with smart hacks, but somehow that fell through.

Unfortunately, at the end of all that it was 17:00 hours, and I was Conference-tired, so I decided to skip Using Docker to Develop, Test and Run Maven projects.

Conclusion

J-Fall always provides an excellent glimpse in what the Software Community (at that current time) feels is most important in sharing with their colleagues.

The main conclusion that I can take away from this J-Fall is that somehow a number of the Sessions was regarding a Separation of Concerns in one way or another (either by an event log, or modules, or micro services, or you-name-it). I heard the term CQRS more than once. Perhaps its importance is felt more and more now that the entire world is getting wired and complexity and unlikely combinations of projects is growing at a rapid rate. (Internet-of-Things anyone?)

References

[1] NLJUG - J-Fall 2014
http://www.nljug.org/jfall/2014/
[2] Martin Fowler - CQRS
http://martinfowler.com/bliki/CQRS.html
[3] Wikipedia - Conway's Law
http://en.wikipedia.org/wiki/Conway%27s_law
[4] Domain Driven Design
Erik Evens
[5] Release It!
Michael T. Nygard
[6] Antifragile
Nassim Nicholas Taleb
ElasticSearch
http://www.elasticsearch.org/

Saturday, 9 November 2013

JFall 2013

I went to JFall 2013, the annual Dutch Java Conference, organised by the NLJUG on Wednesday, the 6th of November 2013 in Nijkerk, the Netherlands.

I found the Keynotes to be singularly exciting, a lot better compared to last year.

Main change was the main sponsor, ING, who have some interesting requirements for their software and who have undergone a change
from the traditional way of developing software to the DevOps way.

My chosen schedule:
  • Shootout! Template engines on the JVM (Jeroen Reijn)
  • Retro Gaming with Lambdas (Stephen Chin)
  • Code-driven introduction to the Java EE 7 Platform (Arun Gupta)
  • Hands-On Labs: Gradle (Mr. Haki)
  • Scratching the Surface with JavaFX (James Weaver)
  • ING Beleggen: how top quality software and state-of-the-art technology leads to continuous delivery (Jos Klompe)

I managed, according to my colleague, to miss out on the talk by Allard Buijze called 'Reactive applications: ready for the future'. But, if all is well, I should be able to view it at Parleys.com.

I hear the talk 'On the integrity of data in Java Applications' (Lucas Jellema) was also really good, that I didn't visit. There's only 24 hours in a day.

Shootout! Template engines on the JVM


The presentation was provided by Jeroen Reijn of Hippo (the Java CMS). He mentioned a few old Template engines, JSP, Freemarker and Velocity. Hippo seems to make use of Freemarker, at least at the moment.

Then he went into some (relatively) new Template engines with included benchmarks:
  • Thymeleaf (web+spring mvc+large memory footprint, a little slow)

    Has Natural Templating, which means that additional namespaces in the XHTML will cause the xhtml pages to render on a normal browser. (It just ignores the additional namespaces).

    Benchmark: 25,000 requests took 30 sec.
    For whom: html designers
  • Mustache (not just web+spring mvc addon)

    Logic-less, so they claim, has no control statements (if, for, while, else, etc). Called Mustache because Expressions are written between double curly brackets ({{), and those look like a mustache.

    Good IDE support.

    Benchmark: 25,000 requests took 12/13 sec.
    For whom: html designers
  • Jade (web)

    A Node.js based template engine. Indentation is part of the syntax, which means there's no need for closing tags. It's minimal, easy to read and small.

    Good IDE support.

    Benchmark: 25,000 requests took 20 sec.
    For whom: java developers
  • Scalate (Scala Template Engine, very slow due to the layout mechanism)

    Scala based, integrates well into Spring, Play, Lift, etc. Supports multiple template languages. The one language Jeroen went into deeper detail about is called SCAML.

    Benchmark: 25,000 requests took 100 sec.
    For whom: Scala enthousiasts

For the java developers that feel the need, the need for speed, stick to JSP and Freemarker.

Retro Gaming with Lambdas


Stephen Chen provided both an overview of lambdas in Java 8 and a practical example in the form of a JavaFX game called 'MaryHadALittleLambda'.

The latter part of which is available on github at https://github.com/steveonjava/MaryHadALittleLambda.

He talked about
  • lambdas
  • extension methods
  • the hamburger operator
  • method references
  • @FunctionalInterface

Code-driven introduction to the Java EE 7 Platform


It was given by the Arun Gupta. I was quite surprised to learn that he's been an employee of JBoss for the past three weeks.

I'm also still not used to the fact that their JBoss Application Server is now called ... Wildfly.

He did a quick code-driven introduction in the following topics:
  • WebSocket (URLs start with 'ws://')
  • JAX-RS (JS339)
  • JSON Client Api
  • Batch
  • JMS

JEE 7 samples are available at his github account at https://github.com/arun-gupta/javaee7-samples.

Hands-On Labs: Gradle


Gradle is sort of like Maven only with a Groovy DSL instead of XML and is more flexible than Maven. Where Maven required selfmade Plugins to get it to do the things you want, Gradle can just be adapted.

From what I hear it is quite easy, even automatic, to convert Maven build scripts into Gradle build scripts.

It seems that NetBeans has builtin support for Gradle, no plugins required. I gotta check that out!

Gradle helps in building a Project. The project consists of tasks. A task consists of actions.

The Lab was one of the easiest and simplest to do. I could have just as easily done that at home.

Scratching the Surface with JavaFX


I enjoyed the presentation of Jim (James) Weaver immensely. It started off with a Dutch Music Guessing Game to break the ice, presumably. After that he showed us the touch events interface in JavaFX. Then proceeded to dazzle us with simple 3D in JavaFX3D.

We should check out iotcommunity.net, and I should mention in JIRA that I want to have shadows from lightnodes.

JavaFX Ensemble application is very nice, as a starting point on what JavaFX makes possible.

Currently, there is some 'unofficial' versions of JavaFX that run on Android and IOS. Expect more news on this.

JavaFX can be lay outed by means of CSS. CSS is a good way to make it more 'finger friendly'. We're talking about touch screens after all.

The 3d parts showed things like shapes (ball, cube, triangle mesh, textures, bump maps), lights (ambient and directional), cameras.

One of the more awesome parts of the presentation was the fact that he wanted to play the guitar, when he was away from home, but without dragging his guitar along. So he programmed touch sensitive guitar strings in 3d on his Microsoft Touchpad. He could play quite well and it was very impressive to see a really good demo of all the touch events he had been talking about.

ING Beleggen: how top quality software and state-of-the-art technology leads to continuous delivery


Jos Klompe and his colleague provided a riveting and energizing talk about what they do for ING, to be specific the portal that customers and employees use to trade stocks and other, more complex, financial instruments.

The most interesting in the story is the complete turnaround from a Bank with a traditional waterfall model over to a dynamic Bank using Agile and Scrum and DevOps teams that is putting IT at the core of its business.