• Refining redirect semantics in the Servlet API

    This post is bike shedding, but as bike shedding go, it’s very important to write about it.

    In web applications, it’s necessary to prevent impatient users from POSTing the same data over and over again. For example, to avoid the pain of putting the same item into the basket multiple times because of a browser refresh.

    To implement that, there’s a good practice, called the POST/redirect/GET pattern:

    POST/redirect/GET pattern,

    This week, I read again the list of HTTP status codes. In particular, the following specific snippet drew my attention:

    302 Found

    This is an example of industry practice contradicting the standard. The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours. However, some Web applications and frameworks use the 302 status code as if it were the 303.

    303 See Other (since HTTP/1.1)

    The response to the request can be found under another URI using the GET method. When received in response to a POST (or PUT/DELETE), the client should presume that the server has received the data and should issue a new GET request to the given URI.

    Unfortunately, the HttpServletResponse.sendRedirect() method returns the status code 302 instead of 303. Hence, it shouldn’t be used when implementing the above pattern. But how to do it then?

    Simply, just go down one abstraction level and manage headers manually:

    @WebServlet("/foo")
    class FooServlet : HttpServlet() {
    
        override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
            // Do stuff here
            resp.addHeader("Location", "/bar")
            resp.sendError(303)
        }
    }

    This achieves the desired result.

    Location HTTP headers
    Categories: JavaEE Tags: redirectservlet
  • Unit tests vs integration tests, why the opposition?

    A woman punching a guy with boxing gloves

    Writing a blog post every week requires a good source of inspiration. Fortunately, Twitter is there.

    This time, it was the following tweet that sparked the flame.

    While I understand Twitter is not the place for subtle and complex thoughts, I believe such approach do more harm than good. Given that I have devoted a significant portion of my time thinking about, designing and writing tests of all kinds, I believe my perspective can bring something to the table.

    Shameless plug

    While you’re at it, have a look at my book Integration Testing from the Trenches, dedicated to, guess what, integration testing.

    By definition, a tweet is not meant to provide detailed arguments supporting one’s point of view. So, let’s check statements made in the original post.

    Definitions

    As in the post, I find the term "unit testing" ambiguous, because of the scope of the unit. Likewise, the term "integration testing" can refer to different things in the mind of different people.

    In the rest of this post, I’ll follow the terminology proposed in the article.

    Agreeing on a vocabulary is very important:

    • In the book "How Google tests software", the authors use the execution speed of a test to categorize it (small, medium and large).
    • In my book, I keep both terms as-is but define their meaning to be un-ambiguous.

    "A safety net for refactoring"

    Properly designed feature tests provide comprehensive code coverage and don’t need to be rewritten because they only use public APIs. Attempting to refactor a system that only has single-class tests is often painful, because developers usually have to completely refactor the test suite at the same time, invalidating the safety net. This incentivizes hacking, creating tech debt

    The first part about testing public APIs, I completely agree with.

    The second part is more nuanced: "Attempting to refactor a system that only has single-class tests is often painful."

    This makes perfect sense. If the only tests you have are single-class tests, refactoring is going to break those. And in that case, you’re left without any clue whether the refactoring introduces regressions or not.

    "Test end-to-end behavior"

    With only single-class tests, the test suite may pass but the feature may be broken, if a failure occurs in the interface between modules. feature tests will verify end-to-end feature behavior and catch these bugs.

    There’s an important condition there: "With only single-class tests".

    Yes, a testing harness consisting only of single-class tests cannot insure the whole system works as intended.

    When I make presentations about testing, I usually use the following comparison: Let’s consider the making of a car. Single-class testing is akin to testing each nut and bolt separately. Imagine testing of such components brought no issue to light. Still, it would be very risky to mass manufacture the car without having built a prototype and sent it to a test drive.

    "Write fewer tests"

    A feature test typically covers a larger volume of your system than a single class test

    Again, there’s nothing to disagree with.

    Still, I find the statement a bit strange, as it’s not a real advantage. While you write fewer feature tests to cover the same scope as single-class tests, they are made bigger.

    The size of a test is a problem in feature testing as it makes it harder to pinpoint the root cause in case of a test failure. The bigger the scope of a test, the harder the analysis, see the next section for more details.

    “My feature test broke, and it’s way harder to debug than single class tests.”

    Think about how much time you will spend if a customer reports a new bug. First, you spend time trying to reproduce the bug. Next, you have to debug and fix the problem. Finally, you have to write single class tests. In general, reproducing the bug alone will cost more time than you spent debugging a feature test. In fact, if you have trouble debugging a properly-designed feature test, it is actually the same as debugging your whole server and we assert you have bigger issues if you have trouble debugging your server.

    At this point, I start to disagree.

    First, I don’t think a production bug can be captured in a feature test. If that would have been the case, then why was the bug allowed in the production system and not fixed before deployment?

    Then, there’s one bold statement: "if you have trouble debugging a properly-designed feature test". This looks like a the No True Scotsman logical fallacy. Because if I have trouble debugging a feature test, then the author can always answer it was not properly designed. Yet, he offers no advice on how to design a feature test in a proper way.

    Conclusion

    I could continue, but I think I made my point. While at the beginning, the author pays attention not to oppose single-class testing and feature testing, it continues by trying to prove that the later is superior to the former. On the opposite, I do think they complement each other.

    Keeping the above analogy of the car, would anyone assemble the prototype car and send it to a test drive without having tested separately each nut and bolt? Probably not, because if the car crashes in the test drive:

    • It will take time and effort to understand the root cause
    • If the root cause if one faulty nut/bolt, it could have been caught much earlier with less time/effort

    And guess what, it directly translates into some of the disadvantages of feature tests:

    1. Hard to debug
    2. Slow

    Of course, feature tests have advantages over single-class tests. But so do single-class tests have over feature tests.

    I think people too easily discarded the Testing Pyramid.

    The famous testing pyramid

    If you want to know more about testing in general and integration testing specifically, don’t forget to check Integration Testing from the Trenches.

    Categories: Development Tags: testingunit testingintegration testing
  • Starting with Ethereum - Writing a contract

    Ethereum logo

    In the latest post, the required infrastructure to do something on Ethereum was set up. Now is the time to roll up our sleeves and start writing some code on it.

    In this post, I’ll show how to write a trivial contract.

    What’s a smart contract anyway?

    A smart contract is a computer protocol intended to facilitate, verify, or enforce the negotiation or performance of a contract.
    — Wikipedia
    https://en.wikipedia.org/wiki/Smart_contract

    That doesn’t tell much. My understanding is that on the blockchain in general, and on Ethereum in particular, smart contracts are just code. Which is a good thing, since we are developers, and writing code is our bread-and-butter (or at least it should be).

    As Ethereum has an Ethereum Virtual Machine, it can run contracts, code, in the form of dedicated bytecode. However, just like in Java, directly writing such bytecode is not really feasible for non-trivial software. Thus, a high-level language is required. There are several of those available, that compile to EVM bytecode:

    Solidity

    I chose Solidity for several reasons:

    • I’ve had not so great experiences with both Python and C
    • It seems to be the most used language
    • The documentation is solid (pun intended)

    Solidity is a contract-oriented, high-level language for implementing smart contracts. It was influenced by C++, Python and JavaScript and is designed to target the Ethereum Virtual Machine (EVM).

    Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.

    — Solidity documentation
    https://solidity.readthedocs.io/en/develop/

    There are a couple of options to compile Solidity code locally, including:

    • A Docker image
    • A Homebrew package
    • An IntelliJ plugin: To install the plugin, go to IntelliJ IDEA  Preferences  Plugins. Then click on the Browse Repositories…​ button, and search for Solidity. After restart, you can select File  New  Smart contract to create new Solidity .sol files.

    Last but not least, one can try the online editor, called Remix. Remix can also run the compiled code on a limited set of networks, and offers a debugger, which is a good option to start with.

    A trivial contract

    The documentation provided is of good quality. Please refer to it to write your own code.

    Let’s just write a contract that adds 2 unsigned integers. This is simple, but it allows us to go further easily.

    pragma solidity ^0.4.0; (1)
    contract Mathematic { (2)
    
        function add(uint a, uint b) public pure returns (uint sum) { (3)
            return a + b;
        }
    }
    1 A Solidity file starts with meta-data telling about its version.
    2 A Solidity file consists of a contract.
    3 Aside from the expected structure (public, returns), notice the pure keyword
    A word on contracts

    Contracts bear a striking similitude to the concept of classes in other languages (such as Java). They can have both state - attributes, and behavior - methods. They can also be abstract.

    In addition, they can have members specific to Solidity, Events, to interact with them.

    Pure functions

    A pure function is a concept inherited from Function Programming. In FP, its return value depends solely on its input parameter(s) and has no side-effects (such as logging, writing to a context, etc.).

    In Solidity, the definition is as follows:

    Functions can be declared pure in which case they promise not to read from or modify the state.
    — Solidity documentation
    https://solidity.readthedocs.io/en/develop/contracts.html#pure-functions

    Note that the state refers to the the state of the Blockchain. It means that the Blockchain is not only an execution environment for contracts, but can also be seen as a database of sort - though an expensive one (more later).

    Testing the contract

    The easiest way to test the contract is to use Remix (see above).

    1. Create a new .sol file and name it Mathematics- or reuse the default one. As opposed to Java, there’s no check that the contract’s name matches the file’s.
    2. Paste the above code.
    3. On the left side, notice the menu:Compiler tab. By default, the Auto compile checkbox is enabled.
    4. Go to the menu:Run tab.
    5. As the above code has no interaction with Ethereum, choose the "JavaScript" VM for Environment.
    6. Now, with the Mathematics value selected, click on the pink Create button. A new block should appear below: it’s our new "virtual" smart contract.
    7. Notice the add button, that’s the way to call the method. Just fill in 2 integers, separated by a comma and click it. The result should be displayed on the left side of the method block.
      Compiling and executing a smart contract in Remix
    Categories: Development Tags: blockchainethereumsmart contract
  • Starting with Ethereum - Setup

    Ethereum logo

    Many people know about Bitcoin, because of its recent rise (and soon crash?). However, Bitcoin is just a currency, albeit a crypto one. As such, it’s of very limited interest to me. But it’s based on the concept of blockchain and that seems to be much more interesting. While there are a lot of resources available on the Web regarding blockchain, they mainly focus on the concept of blockchain, or how it works internally, not so much on how you can as a developer use it.

    This is the first post in what I hope will be a serie which aims at correcting that. The blockchain implementation I’ll be using will be Ethereum because it’s an already established technology, with a mature ecosystem around it.

    This post will describe how to setup the whole tooling around Ethereum, and lay the foundations of the posts to come.

    The Wallet

    The wallet is the first step when you want to start working with Ethereum. It’s called a wallet because it does hold the Ethereum currency - called ether. It also holds other custom assets - called tokens.

    Ethereum provides such a wallet, just download it from the home page. This software also allows to deploy and run smart contracts.

    For Mac users, there’s also a Homebrew recipe. To install, type:

    brew cask install ethereum-wallet

    Once installed, launch the application. A network needs to be chosen: choose "Rinkeby" which is a test network. At this point, the blockchain is copied locally. Wait…​

    The Ethereum blockchain being copied

    Then, an account needs to be created. Choose a password.

    Wallet with an account configured

    Get funds

    Whatever your stance regarding it, money is at the foundation of the world. In Ethereum, this is no different. On the production network, you’d need to buy ethers from a broker. On "Rinkeby" which is a playground network, one can just ask for ethers.

    Go on https://faucet.rinkeby.io and follow instructions to receive ethers. You basically have to post your wallet public key on a social network - to prevent abuse. The rate by which one can ask for ethers is also limited, to prevent abuse.

    Requesting ethers for the Rinkeby network

    Funds should be available soon after the post has been published on the social network of your choice. Check your account, you should be richer.

    The rate limit is:

    • 3 ethers every 8 hour
    • 7.5 ethers per day
    • or 18.75 ethers every 3 days

    Astute readers might notice that it’s better to ask for less, but then more often (3 ether * 8 hours * 3 times * 3 days = 72 ethers).

    The balance can also be checked on etherscan.io. Just replace the last segment of the URL path with your account public key.

    Export/import accounts

    Chances are you will have multiple computers, or you will change computer, or even change software. As such, it’s very important to be able to export/import accounts.

    Exporting

    Within the Ethereum wallet, go to File  Backup  Accounts. On OSX, this translates to ~/Library/Ethereum/rinkeby/keystore. There should be one keystore file, starting with UTC, which name matches the public key (the one posted on social media previously). Its content is in JSON format.

    Importing

    Another available wallet for Ethereum is Metamask, available as a dedicated browser or a Chrome extension.

    1. Install the Chrome extension - it can be uninstalled just afterwards
    2. Locate the extension in the browser bar
    3. Locate the Account button - it’s the second rightmost one
    4. Choose Import Account
    5. In Select Type, choose JSON File
    6. Point to the above file
    7. Type your account password

    At this point, MetaMask should also display your account and its balance. Notice it’s the same account public key and the same balance.

    Account imported in MetaMask
    Categories: Development Tags: blockchainethereum
  • Managing randomness in Java

    Dice rolling on a checkboard

    If you already had to manage some degree of randomness on Java, chances are you got acquainted with the Math.random() methods. However, the previous method returns a double. Beyond very basic use-cases, another option has to be considered, in the form of the java.util.Random class.

    Random

    An instance of this class is used to generate a stream of pseudorandom numbers.
    — JavaDoc
    https://docs.oracle.com/javase/8/docs/api/java/util/Random.html

    This root class provides basic random numbers generation capabilities, nothing mind-blowing.

    • Generate a single random:
      • boolean
      • byte array
      • double
      • float, whether uniform or from a Gaussian distribution
      • long
      • or int (from 0 to 232 or a specific bound)
    • Generate a stream of random:
      • int
      • long
      • or double

    For more specialized needs, there are two children classes, ThreadLocalRandom and SecureRandom.

    Random class hierarchy

    ThreadLocalRandom

    One problem about the Random class is that it’s based on an AtomicLong for number generation. It’s thread-safe by definition, but it may cause performance issue if used by too many of threads at once.

    Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools.
    — JavaDoc
    https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadLocalRandom.html

    Usage is like:

    ThreadLocalRandom.current().nextX(...) // (where X is Int, Long, etc.)

    There are some interesting things about ThreadLocalRandom:

    • Compared to Random, it adds additional random-generating methods with bounds for types long and double
    • It doesn’t use the next(int bits) for the other random-generating methods, to avoid the AtomicLong contention

    SecureRandom

    The important bit about Random is that it doesn’t provide true randomness, but only pseudo-randomness. From the JavaDoc of the next(int bits)(upon which all other random generator methods depend):

    This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer and described by Donald E. Knuth in The Art of Computer Programming, Volume 3: Seminumerical Algorithms, section 3.2.1.
    — JavaDoc
    http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/Random.java#l188

    On the opposite, SecureRandom offers true randomness:

    This class provides a cryptographically strong random number generator (RNG).

    A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.

    — JavaDoc
    https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

    This class depends on a:

    Provider

    A Provider provides (sic) some or all parts of the Java Security API. It has a name e.g. SunRsaSign, and a version.

    Algorithm

    Pretty self-explanatory, e.g. NativePRNG

    Both provider and algorithm are platform-dependent. It means that randomness obtained by using SecureRandom is only as good as the provider and algorithm used.

    To obtain an instance of the class, one can call either:

    1. One of the available constructors
    2. One of the getInstance() static method
    3. The getInstanceStrong() static method

    I’d suggest using the last option, as it will throw an exception if no "strong" random algorithm is available.

    A "strong" algorithm is defined by the securerandom.strongAlgorithms security property. Running Security.getProperty("securerandom.strongAlgorithms") on my local dev environment yields NativePRNGBlocking:SUN. I’ll let everyone decide whether an algorithm prefixed with PNRG (Pseudo-Random Number Generator…​) is good enough.

    Remember to check $JAVA_HOME/lib/security/java.security to manage the security configuration of your JVM.
    Categories: Java Tags: Randomnesssecurity
  • Design gotchas in JDK's functional interfaces

    Diagram of the Doppler effect

    Because of a course I prepared, I recently had a closer look at the java.util.function package in JDK 8, and discovered a couple of interesting design choices.

    Callable is not a Supplier

    Their respective definitions are:

    @FunctionalInterface
    public interface Callable<V> {
        V call() throws Exception;
    }
    
    @FunctionalInterface
    public interface Supplier<T> {
        T get();
    }

    Thus, a Callable and a Supplier are defined in the same way:

    Callable<String> callable = () -> "Hello";
    Supplier<String> supplier = () -> "Hello";

    But they are not equivalent:

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(callable); (1)
    executorService.submit(() -> "Hello");(2)
    executorService.submit(supplier); (3)
    executorService.submit((Callable) supplier); (4)
    1 OK
    2 OK
    3 Doesn’t compile
    4 Throws at runtime

    Comparator is not a BiFunction

    Their respective definitions are:

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);
    }
    
    @FunctionalInterface
    public BiFunction<T, U, R> {
        R apply(T t, U u);
    }

    The same statements as above apply, but there’s one thing of note. No method throws a checked exception. Obviously, methods names are different, but Comparator could have been written in the following way:

    public interface Comparator<T> extends BiFunction<T, T, Integer> {
    
        int compare(T o1, T o2);
    
        default Integer apply(T o1, T o2) {
            return compare(o1, o2);
        }
    }

    Yet, Comparator is a legacy class, so better not touch it.

    Predicate is not a Function

    Definitions:

    @FunctionalInterface
    public Predicate<T> {
        boolean test(T t);
    }
    
    @FunctionalInterface
    public interface Function<T,R> {
        R apply(T t);
    }

    As above, this one could have been written as:

    public interface Predicate<T> extends Function<T, Boolean> {
    
        boolean test(T t);
    
        default Boolean apply(T t) {
            return test(t);
        }
    }

    Or even better, keeping just one single method:

    public interface Predicate<T> extends Function<T, Boolean> {
    }

    There might be two reasons for this lack of relationship:

    • The specialized method name (test instead of apply), but to be honest, that’s not a real issue since most Predicate instances will be written as lambdas anyway.
    • The boolean primitive return type - instead of Boolean, to prevent returning null. Guess what? Thanks to auto-boxing, it prevents nothing:
    Predicate<Object> predicate = o -> (Boolean) null;

    Conclusion

    Java is a language that values backward-compatibility (e.g. generics and type erasure) - a lot. That means that whatever design choices are made, they will stay forever, or at least long enough to have consequences.

    According to my understanding of Functional Programming, two functions are equivalent if, from the same input they return the same output. Naming is not relevant, and adds noise. While the 2 first lack of relationships described above can be justified by backward-compatibility, I find the last one contradicting that. Any thoughts?

    Categories: Java Tags: JDKfunctional interfacesdesign
  • Using Kotlin on the SAP Hybris platform

    SAP Hybris logo

    Since I discovered Kotlin, I use it in all my personal projects. I’ve become quite fond of the language, and with good reason. However, there’s yet no integration with the Hybris platform - though there’s with Groovy and Scala. This post aims at achieving just that, to be able to use Kotlin on Hybris projects.

    Generate a new extension

    The first step on the journey is to create a new extension:

    ant extgen
    1. Choose the yempty package
    2. Choose an adequate name, e.g. "kotlinfun"
    3. Choose a root package, e.g. ch.frankel.blog.kotlin
    Don’t forget to add this new extension to the localextensions.xml file.

    Add libraries

    Kotlin requires libraries, both to compile and to run. They include:

    • kotlin-ant.jar
    • kotlin-compiler.jar
    • kotlin-preloader.jar
    • kotlin-reflect.jar
    • kotlin-script-runtime.jar

    Though it would be nice to use external-dependencies.xml, some JAR are not available as Maven dependencies (e.g. kotlin-ant.jar). Thus, it’s required to manually get the relevant Kotlin compiler and unpack it.

    Create folders

    To help with the build, let’s create dedicated folders for sources and tests, respectively kotlinsrc and kotlintestsrc. Configure the module or the project accordingly - depending whether your IDE of choice is IntelliJ IDEA or Eclipse.

    On the Hybris platform, both sources and tests will compile in the same folder.

    Create simple Kotlin files in kotlinsrc and kotlintestsrc.

    Configure Kotlin in IDE

    While at it, configure Kotlin for the IDE. IntelliJ IDEA will pop-up an alert box to do so if a Kotlin file is created anyway. I have no clue about Eclipse…​

    The fun part

    Now that compiling works inside of the IDE, it should also be part of the standard command-line build. Fortunately, there are build hooks into the Hybris build pipeline. Those are configured inside the build_callbacks.xml file.

    A naive first draft would look like:

    <project name="kotlinfun_buildcallbacks">
    
        <property name="kotlin.lib.dir" location="${ext.kotlinfun.path}/lib"/>
    
        <taskdef resource="org/jetbrains/kotlin/ant/antlib.xml">
            <classpath>
                <pathelement location="${kotlin.lib.dir}/kotlin-ant.jar"/>
                <pathelement location="${kotlin.lib.dir}/kotlin-compiler.jar"/>
                <pathelement location="${kotlin.lib.dir}/kotlin-preloader.jar"/>
                <pathelement location="${kotlin.lib.dir}/kotlin-reflect.jar"/>
                <pathelement location="${kotlin.lib.dir}/kotlin-script-runtime.jar"/>
            </classpath>
        </taskdef>
    
        <macrodef name="kotlin_compile">
            <attribute name="srcdir"/>
            <attribute name="destdir"/>
            <attribute name="extname"/>
    
            <sequential>
                <echo message="compile kotlin sources for @{extname} using srcdir: @{srcdir}"/>
                <mkdir dir="@{destdir}"/>
                <kotlinc src="@{srcdir}" output="@{destdir}">
                    <classpath>
                        <pathelement location="${kotlin.lib.dir}/kotlin-stdlib.jar"/>
                        <fileset dir="${[email protected]{extname}.path}" erroronmissingdir="false">
                            <include name="${[email protected]{extname}.additional.src.dir}/**"/>
                            <include name="${[email protected]{extname}.additional.testsrc.dir}/**"/>
                        </fileset>
                        <pathelement path="${build.classpath}"/>
                        <pathelement path="${platformhome}/bootstrap/bin/models.jar" />
                        <fileset dir="${bundled.tomcat.home}">
                            <include name="lib/jsp-api.jar"/>
                            <include name="lib/servlet-api.jar"/>
                            <include name="lib/el-api.jar"/>
                            <include name="lib/wrapper*.jar"/>
                        </fileset>
                        <pathelement path="${[email protected]{extname}.classpath}" />
                    </classpath>
                </kotlinc>
            </sequential>
        </macrodef>
    
        <macrodef name="kotlinfun_compile_core">
            <attribute name="extname"/>
            <sequential>
                <if>
                    <isset property="[email protected]{extname}.coremodule.available"/>
                    <then>
                        <if>
                            <istrue value="${[email protected]{extname}.extension.coremodule.sourceavailable}"/>
                            <then>
                                <kotlin_compile srcdir="${[email protected]{extname}.path}/kotlinsrc"
                                               destdir="${[email protected]{extname}.path}/classes"
                                               extname="@{extname}"/>
                                <kotlin_compile srcdir="${[email protected]{extname}.path}/kotlintestsrc"
                                               destdir="${[email protected]{extname}.path}/classes"
                                               extname="@{extname}"/>
                            </then>
                        </if>
                    </then>
                </if>
            </sequential>
        </macrodef>
    
        <macrodef name="kotlinfun_after_compile_core">
            <sequential>
                <kotlinfun_compile_core extname="kotlinfun"/>
            </sequential>
        </macrodef>
    </project>

    The above is configured for a simple core module, not a web one. It can be added afterwards though.

    Unfortunately, this doesn’t work. Launching the build with ant build will produce the following output:

    /hybris/bin/platform/resources/ant/compiling.xml:530: java.lang.NoSuchMethodError:
     com.google.common.collect.Iterables.filter(Ljava/lang/Iterable;Lcom/google/common/base/Predicate;)Ljava/lang/Iterable;

    Looking more closely at the kotlin-compiler.jar, one must notice it embeds Guava, which also happens to be on the hybris classpath. Hence, there’s a version conflict. Fortunately, there’s a smarter version of the compiler - kotlin-compiler-embeddedable.jar available on repo1 that shades Guava i.e. embeds it using a different package name, thus resolving the conflict. Just update the callback file with the new JAR name, and be done.

    Now, the build produces a different output:

    /hybris/bin/custom/kotlinfun/buildcallbacks.xml:34: java.lang.IllegalStateException:
     File is not found in the directory of Kotlin Ant task: kotlin-compiler.jar

    For reasons unknown, the Ant task checks the existence of dependent libraries using their file names! Check the source code for proof. There’s an evil workaround: rename the JAR as it’s expected. And update the build file back to the initial version…​

    At this point, it’s possible to build the platform with Kotlin files compiled.

    Improvements

    Though it works, there are a couple of possible improvements:

    • Change the lib folder to a dedicated folder e.g. compile , so as not to ship it in the distributed archive
    • Add the configuration to also compile a web module
    • Refactor the macros into a common extension, so that different Kotlin extensions can use it.

    In the end, nothing prevents you from using Kotlin on SAP hybris right now!

    Categories: Development Tags: Kotlinhybris
  • Make your life easier with Kotlin stdlib

    A bunch of books on shelves

    IMHO, Kotlin is not about big killer features - although extension methods and properties could certainly be categorized as such, but about a bunch of small improvements that have deep impact. Most of them are not built-in into the language, but are functions offered as part of the Kotlin standard library. In this post, I’d like to go through a limited set of them, and describe how they can be used to improve the code.

    TODO()

    It’s quite common to have //TODO comments in a new codebase. For most of us developers, it might even be a reflex. When the flow comes in, don’t stop because of a lack of specification, but write down a reminder to get back to it later. Whatever later means. Even IDEs happily generate code with such comments.

    fun computeCustomerNumber(customer: Customer): String {
        // TODO Not specified as of November 27th
    }

    Yet, no problem occurs when the actual code is run. Nothing happens, nothing to really remind us that piece should be implemented. Of course, some code analysis tools might uncover it, but it might already be too late. And it requires the tool to actually be run.

    Kotlin provides the TODO() function, that actually throws an exception when it’s called. This way, even running a simple unit test will forcibly point you to the fact there’s something to be done there.

    fun computeCustomerNumber(customer: Customer): String {
        TODO("Not specified as of November 27th")
    }

    apply()

    Depending on an API specifics, constructing some objects might be rather tedious, and involve a lot of details. To hide those details, the current consensus is generally to create a method out of it. Here’s a snippet to create a combo-box component for the Vaadin web framework:

    fun createCountriesCombo(): ComboBox<String> {
        val countries = ComboBox<String>("Countries")
        countries.setItems("Switzerland", "France", "Germany", "Austria")
        countries.isEmptySelectionAllowed = false
        countries.placeholder = "Choose your country"
        countries.addValueChangeListener {
            val country = countries.value
            bus.post(CountryChangeEvent(country))
        }
        return countries
    }

    Even then, depending on the amount of properties to set, it’s easy to get lost in the details. apply() is a simple function, defined as:

    fun <T> T.apply(block: T.() -> Unit): T { block(); return this }

    It means this function can be called on any type T, and its only argument is a lambda receiver, that returns nothing. As for any lambda receiver, this inside the lambda refers to the object the function is called on. This let us refactor the above snippet into the following:

    fun createCountriesCombo(): ComboBox<String> {
    val countries = ComboBox<String>("Country").apply {
            setItems("Switzerland", "France", "Germany", "Austria")
            isEmptySelectionAllowed = false
            placeholder = "Choose your country"
            addValueChangeListener {
                bus.post(CountryChangeEvent(value))
            }
        }
    }

    Even better, the snippet can be now be easily refactored to take advantage of expression body:

    fun createCountriesCombo() = ComboBox<String>("Country").apply {
        setItems("Switzerland", "France", "Germany", "Austria")
        isEmptySelectionAllowed = false
        placeholder = "Choose your country"
        addValueChangeListener {
            bus.post(CountryChangeEvent(value))
        }
    }

    Icing on the cake, with any IDE worth its salt, folding may be used to display the overview, and unfolding to reveal the details.

    IDE-unfolded apply function
    IDE-folded apply function

    use()

    Before Java 7, the closing of a connection had to be explicitly done in a finally block:

    Connection conn = getConnection();
    try {
        // Do stuff with the connection
    } finally {
        if (conn != null) {
            conn.close();
        }
    }

    Java 7 added the try-with-resource syntax. For example, the previous snippet can refactored into this one:

    try (Connection conn = getConnection()) {
        // Do stuff with the connection
    }

    The try-with-resource syntax greatly simplifies the code. However, it’s part of the language syntax and thus carries a lot of implicitness:

    • The type in the resource statement must implement AutoCloseable.
    • There can be multiple resources opened in the same statement. In that case, they are closed in the reversed order they were opened.
    • If an exception is thrown in the try block and also during the closing of the resource(s), the latter is suppressed and set to the main exception.

    The Kotlin counterpart is handled through the use function, whose signature is:

    fun <T : Closeable, R> T.use(block: (T) -> R): R

    No black magic involved. It’s a simple function, and its source code is available online.

    Conclusion

    Those are only a sample of what is available. In general, the syntax of languages can be learned in 21 days (or probably even less). However, it takes a lot more time to know the API.

    Kotlin is less about the syntax and more about the API.

    Categories: Development Tags: Kotlinstdlib
  • Making the most out of conferences

    A conference room full of people

    This week was my last conference of 2017, Voxxed Day Thessaloniki organized by my good friend Patroklos. I started going to conferences some years ago.

    Going to a conference is an investment, whether in time or in money - or in both. You should me make sure to get the most out of that investment. In this post, I’d like to write down what I do to achieve that.

    Plan ahead

    The first thing to do is to get the list of available talks ahead. Some conferences require attendees to register to talks beforehand. That’s especially true for workshops, which have a limited number of seats. You’d be very sorry to miss a talk you wanted to attend only because you didn’t register.

    Also, some have talks in different buildings. Even at conferences, logistics do play a role.

    Even if that’s not the case, planning ahead will get you a clear picture, in case you’re interested in more than one talk at the same time.

    Workshops over talks

    Some conferences offer workshops in addition to talks. IMHO, such workshops have way more value than regular talks. While in a talk, your mind can wander away, workshops make you more implicated by essence, because you need to do something. In the end, you’ll be more focused and what you learned will be more persistent.

    Avoid long talks

    When I was a student, I listened to 2-hours lesson. Even then, it was hard to stay focused for such a long time. Some conferences propose 3-hours talk. I don’t think anyone can stay focused during the whole talk.

    While it might be possible to attend one such talk over the conference, more than one is not worth it.

    Take notes

    A good way to keep your focus is to take notes. An even better way is to share your notes, whatever the medium. It can be you personal blog, you company blog, a company meeting, anything. By setting an objective, you’ll pay more attention during the talk.

    Put your phone away

    Let me repeat it: put. your. phone. away. Or shut it off. Or leave it in your bag. It’s too easy to be distracted by notifications, especially if you have a smart watch on top of it. Hey, an email! Hey, a Twitter follower! Hey, a connection request on LinkedIn. I’m guilty of this myself.

    During talks, phone are only useful to:

    • take pictures of slides
    • tweet a quote from the speaker

      In the first case, speakers (or conferences) nearly always make their slides available afterwards. In the second, write the quote down and tweet later.

    Don’t be shy

    The talk is finished. It’s QA time. A lot of questions are in your head. But you dare not ask them, for whatever reason. Or you waved your hand, but was not chosen and the time is up. Or there was no QA.

    In all cases, ask your question. If time is up, go the speaker after the session. If he leaves the room, chase him. Most speakers will be very happy to engage in a discussion on the subject they talked about. And then, you’ll keep what you learned longer because of that personal engagement.

    Walk away

    Yes, people don’t want to talk about that, but sometimes, the talk is not great. Perhaps the content is not what you expected. Perhaps the speaker is not that great. Or whatever.

    In that case, you shouldn’t be afraid to just walk away, and use that time in a more productive way. Or just take a break - see below.

    Voting with your feet is important. But it’s even more important to give a detailed feedback. Conference organizers and speakers want to improve, so this information is core to them.

    Try something new

    After the first or second talk about <insert hype subject here> (e.g. Docker, microservices, React, etc.), what you learn is pretty marginal. If you’re an expert of <insert subject here>, why would you go for a talk about it? Granted, you could want to deepen your understanding, but in general, conference talks are not so deep dive because they need to attract many people.

    On the opposite, attending a talk on a subject which is completely foreign to you could open new options. For example, I’m a Vaadin fan and still went to an AngularJS talk some years ago. It was great, I never regretted it. Now, I have one more option in my solutions toolbelt when designing an architecture.

    Speaker over content

    Let’s face it. Some speakers are better than others. They can make a good and entertaining talk out of poor content. When the content is good, the talk is just awesome. You remember it. You want to tell your colleagues about it. You’re even likely to pester them until they watch the recording. It got you inspired!

    While you should give a chance to new talents, it’s sometimes a good idea not to think about too much about the content and just go for the show.

    Meet new people

    Yes, conferences are about improving skills, and discovering new things. But this is not by far the only possibilities.

    Networking is as important as technical content, if not more. In conferences, you could talk to someone who could offer you your dream job, or introduce you to a new idea. Or you could mingle with a group, and have a nice time debating over an idea - or simply chit-chat. Work is not all, relaxing is also required at some time. Network if possible.

    More importantly, if you already have a network, try to enlarge your horizon. Meet new people. Conferences are a fantastic opportunity to meet experts in a field completely unrelated to yours. Listen to them talk about it in a passionate way.

    Don’t overdo it

    With the first few conferences, I did want to squeeze every last piece of information out of conferences. I went to every talk I could Took notes, wrote blog post. And ended up quite tired.

    A conference is not like a sprint, but more like a marathon. Stuffing a lot of knowledge quickly into your head doesn’t help retain it.

    Pauses are important. Netwok (see above). Go to boothes, play games, sit and think about what you learned, rest and sleep if need, whatever works for you. That’s also useful time, albeit of a different kind.

    Categories: Miscellaneous Tags: Conference
  • On developer shortage

    A laptop on a table with nobody sitting in front

    Who is not aware that there’s a developer shortage? I mean, if you’re into the software industry, everybody is telling it every now and then - especially if you’re on the recruiting side. To handle that, companies come up with creative solutions - some are sponsoring education initiatives, or even creating their own. However, I think it’s not the right answer.

    Of course, there’s no doubt that there’s a shortage of good developers. Yet, that’s true for every industry: there’s a lack of good plumbers, of good carpenters, of good car mechanics, etc. So, why is there such a pathos around it in IT? I’ve come up with several reasons, that boil down to a single point. Let me develop.

    Unrelated technologies/skills

    Have you ever written a job description that looks like a Christmas wish list? I mean, a lot of technologies, mainly unrelated. Like front-end and back-end, or sysadmin skills with any kind of development skills.

    And since I’m there, I need to tell you there no such thing as a full-stack developer. At least, not in the sense you think. I have designed systems from front to back, and I’ve fixed bugs on the front-end, but I’m not on par with a regular experienced front-end developer.

    Yet, every day, I learn new things - that I try to share here. Do you believe I can learn them in my free time, but not as a new hire?

    Degrees

    Does your job description requires a university degree? A degree in computer science? A licence or a master?

    If that’s the case, it means you believe those university degrees somehow prepare people to do the job. Or worse, you don’t really believe it, but at least, it will protect you if the hire is not the right fit in the end.

    Do they teach you object-oriented programming in universities? Or mutation testing? Or testing at all? How people who are full-time teachers know about modern build pipelines? About Docker? They do know a lot about sorting algorithms though, which you probably don’t need to implement yourself in the industry.

    Certifications

    Do you require certifications for the job? Of course, it might make sense to require a Java certification for a Java job. But do you know how people are getting certified? Do you know what it really entails?

    Well, certifications are based on multiple-choice questions. Mostly based on knowing the API by heart. In real-life, I have an IDE and Google if I forget about them.

    Diversity

    In most developed countries, selection by age is not allowed. However, there are subtle ways to filter by age. Asking for a number of years of experience is a good way. Like 5 years of experience probably means ~28 years, counting a master’s degree.

    Thing is, I’ve worked in the same team as an Android developer, he had 5 years of experience. Only he was 21, as he had started developing in Android at age 16. Would you hire him, since he fulfills the requirements, or is he too young for your taste?

    Too young, too old, not the right gender, not the right ethnicity…​ There are a lot of bias that might sit between you and potential capable hires.

    Work onsite

    Do you require your developers to work onsite? 100% of the time? Why?

    I’ve worked with remote colleagues. I do work now with remote colleagues. Some companies are 100% remote. Are they making bad software? If you believe people need to meet each other once in a while, does that mean that people need to commute every day to work?

    For sure, there are differences between working while co-located and not. But there are a lot of tips and tricks available to make it work.

    Creating a team is about building trust. Trust doesn’t appear automatically by co-locating people.

    Dress code

    Is there a specific dress code in your company? I’m referring to a dress code that is not compatible with the average developer’s dress code e.g. costume, bow and tie.

    Do you think developers work better when they dress in a certain way? Or is your reason is that developers are part of the image of the company, and customers might see them (hint: they never do). Or do you think that in order to cooperate with business people, they need to dress the same way? Then, think about a car mechanic who would handle your car dressed in bow and tie?

    Hiring process itself

    What’s your hiring process? How many steps completely unrelated to the job do I need to pass in order to get to the real interviews? Do I need to answer questions such as "Where do you see yourself in 5 years?" or "What’s your 3 best qualities?".

    I’m not saying this is a rule, but I’ve never seen an HR team that knew about the specifics of the developer job. Having an hiring process that doesn’t take it into account is plain crazy, especially since HR is but the first step.

    HR should be a help, not an hindrance.

    Salary

    This one is pretty obvious, but do you pay developers at the market level? Do you include the salary range in your job description?

    When browsing job ads, it’s an extra effort to ask for the compensation. Most developers won’t take the time, and just discard your job description. And if they do, and the offer doesn’t match, it’s time lost for both parties.

    There are only 2 possible reason you don’t include compensation policy. Either you’re afraid of telling current employees, and that means something is already broken. Or you’re afraid of telling competitors, and let’s be blunt, they probably already know - because people talk about their compensation.

    Culture

    Last but not least, how do you consider developers inside your company? Are they a true part of the value chain? Are they only accountable or also decision makers? Do you threaten them to outsource their job in India every day to keep them "under pressure"?

    Developers are in touch. Because of the same university, same technology user group, whatever…​ They know about your company and its culture, about its pros and cons.

    Conclusion

    Does any of the above point ring a bell? There’s no developer shortage, there are only barriers you set yourself between your company and a potential workforce. Break the barriers.

    Categories: Miscellaneous Tags: hiring