New Blog: Curious (Clojure) Programmer

I decided to move on and create a new blog dedicated to learning Clojure/ClojureScript and related technologies: Curious (Clojure) Programmer.

OutOfSingularity won’t be maintained anymore. For all new stuff, please, visit http://curiousprogrammer.net/.

Advertisements
Posted in Uncategorized | Leave a comment

Clojure, lein run, and obscure error messages

Today,

I was playing with examples from wonderful Living Clojure book, chapter 5.

This is mainly stuff that I have already know, but I still did want to write down all code and try it by myself. There was no surprise until I got to the very end of chapter when there’s an example demonstrating usage of “:main” in project.clj.

Pretty trivial, huh?!

I did the appropriate changes to my project.clj:

(defproject wonderland "0.1.0-SNAPSHOT"
~ :description "Examples from the book Living Clojure by Carin Meier"
~ :url "https://github.com/jumarko/living-clojure"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
~ :dependencies [[org.clojure/clojure "1.8.0"]
~ [camel-snake-kebab "0.3.2"]]
~ :main wonderland.core)

and tried to execute lein run:

lein run
Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :alter-name of protocol: #'camel-snake-kebab.internals.alter-name/AlterName found for class: nil, compiling:(/private/var/folders/hn/tgwyrdmj1tb5pmmbdkd1g_qc0000gn/T/form-init2789214926070543937.clj:1:125)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: No implementation of method: :alter-name of protocol: #'camel-snake-kebab.internals.alter-name/AlterName found for class: nil
at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:568)
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:560)
at camel_snake_kebab.internals.alter_name$eval3006$fn__3007$G__2997__3014.invoke(alter_name.clj:4)
at camel_snake_kebab.core$__GT_snake_case.invokeStatic(core.clj:20)
at camel_snake_kebab.core$__GT_snake_case.doInvoke(core.clj:20)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at wonderland.core$serpent_talk.invokeStatic(core.clj:5)
at wonderland.core$serpent_talk.invoke(core.clj:4)
at wonderland.core$_main.invokeStatic(core.clj:9)
at wonderland.core$_main.doInvoke(core.clj:7)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:375)
at user$eval2877.invokeStatic(form-init2789214926070543937.clj:1)
at user$eval2877.invoke(form-init2789214926070543937.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 14 more

 

Holly shit! The example uses the camel-snake-kebab library, but what does this mean?!

Caused by: java.lang.IllegalArgumentException: No implementation of method: :alter-name of protocol: #'camel-snake-kebab.internals.alter-name/AlterName

Since I was not able to decrypt this message, I started to look for the solution on the internet. I found two stackoverflow questions:

I found that I misspeled the name of main function – instead of (defn -main...) I had (defn- main). I fixed the signature of main method, but problem persisted.

I triple-checked that I had spelled the name of my namespace in the project.clj correctly. I also tried to play with project.clj adding various stuff like ^:skip-aot, etc. Obviously, this didnt’ help.

More than half hour later, it suddenly came: I forgot to pass the argument on command line!

This is my namespace with main method:

(ns wonderland.talk
  (:require [camel-snake-kebab.core :as csk]))

(defn serpent-talk [input]
  (str "Serpent! You said: " ( csk/->snake_case input)))

(defn -main [& args]
  (println (serpent-talk (first args))))

serpernt-talk function that is called within -main method expects one argument. It didn’t get any and failed with mysterious error message.

Once I supplied proper argument, everything was OK:

lein run "Hello"
Serpent! You said: hello

That is! Sometimes, the Clojure error messages are really cryptic – at least for me.

 

Posted in Clojure, Uncategorized | Tagged , | Leave a comment

Jmxterm, JDK7, Mac OS X and “JDK instead of JRE” error

In last few days I have implemented some types of smoke tests which are executed via JMX. For manual testing I have used jmxterm on amazon linux instance and it worked seamlessly.

However, when I run jmxterm on my Mac OS X Lion with JDK 7 and tried to invoke the very basic “jvms” command I got following error
UnsupportedOperationException: Operation requires JDK instead of JRE

Since I have not found any known solution for this problem I come up with my own fix. Right now, it is only pull request and it might be (or not) merged in the future. Feel free to use this patch anywhere:

Pull request
Commit diff

Posted in Uncategorized | Tagged | Leave a comment

BDD myths

Acceptance Test Driven Development (ATDD) and Behavior Driven Development (BDD) is getting a lot of attention in last years. And lot of misunderstanding too.

Recently, I’ve watched a great presentation Busting BDD Mythsfrom Gojko Adzic. So, if you have enough time you can completely skip following lines and watch it (I strongly recommned it and also two other great presentations such as
Sleeping with enemy and Visualising quality) NOW.
For the others here is a summary.

Two things

There is a nice saying that you should be able to describe the core of your job (interest, hobby, etc) in only two words, or two different sentences, e.g.

Web programming

  • Ctrl + C
  • Ctrl + V

Automation (Bill Gates)

  • Automation applied to an efficient operation will magnify the efficiency
  • Automation applied to an inefficient operation will magnify the inefficiency

What this means is described by first of BDD Myths “Instoolation”.

BDD Myths

  1. Instoolation – belief that process problems can be solved by installing a tool.

    The sad fact is that tool really does not help. If you have a process problems you must resolve them before. Otherwise the tool only make the all whole situation worse.

  2. Businessting – belief that business users should write acceptance tests.

    Gojko introduced many real-world examples of companies that struggled with ATDD and BDD. They made a complaints such a following:
    Customers didn’t want to speak with use. So we’ve installed Fitnessee but customers still don’t want to speak with us!
    You should not try to force your customers to write acceptance tests on their own. Neither testers, nor the programmers. Otherwise you’ll lost the biggest value of BDD – continuous feedback and communication. And this would be similar to situation when customer provide us with crappy requirements written in Word or whatever other tool.
    The most important think is a collaboration of whole team from to beginning to the end.

  3. Acceptagration – belief that tests are either unit or acceptance-integration.

    Acceptance tests should not be that “big kraken” that requires whole database
    and other external services. We should carefully identify the parts in the system that are risky and test those parts. We don’t always need to test whole system with all the dependencies – actually, we should strive for the opposite.
    So:

    • if risk is in collaboration of 7 web services then test it all
    • if risk is in single class then test single class

    Another good advice (originated from Domain Driven Design) is you should try to model your system in a clean way separated from infrastructure. There is a famous Sturgeon’s Law which says:
    Ninety percent of everything is crap.
    So isolate your model from that ninety percent and test it in a clean way.

  4. Rolation – belief that [some_role] should do BDD in isolation (eg. testers do everything).

    There’s nothing worse than adopt BDD by giving a task “write acceptance tests” to external tester. BDD is about solving communication problems and no tool can solve this without people collaboration. As Gojko said:
    If there is a team of one person and there are communication problems there is no tool in the world that solves those problems
    BDD cannot be performed in isolation. If people work together they can discover misunderstood requirements at the very beginning of process and resolve them. Furthermore, there are no more levels of “DONEs” (implementation is DONE, tests are done, accapetance tests are done, …) anymore. There is only one definition of DONE. I really like this concept, because I’ve found the very similar issue in our company.

  5. Longression – belief that the long term value of BDD is in regression testing.

    At this place Gojko mentioned book Economics of software quality. Author Capers Jones investigated thousands of software projects and realized that the regression tests are able to discover only 23% of bugs.
    In fact, there are companies (such as uswitch.com in the UK) which are using acceptance tests only once. Once they passed they will disable them. They found out that a better way how to detect bugs is by setting sensitive KPIs (by business users) and they are monitoring them constantly. Interesting point here is that they haven’t had no serious problem at the production for at least 6 months.

    So what are the acceptance tests good for if not for regression testing ?
    To answer this Gojko provided his own version of

    Two things about BDD

    • Explore examples through collaboration
    • Create living documentation (don’t focus too much on tests automation)

For those who have gotten till here – really watch the Gojko’s presentation. It is far more usefull and enjoying than this boring post!

Posted in Agile, Programming, Project Management, TDD | Tagged | Leave a comment

Unit testing that sucks less – various points

While moving around the various sources about unit testing and OO software construction in past two days I’ve come across few interesting articles and presentations. Among other I’ve rediscovered  presentation from Neil Ford: Unit Testing That Sucks Less Here, I want to summarize some more interesting points:

  • Hamcrest
  • Infinitest.
    Runs tests constantly in background. Every time the class is changed (recompiled), its unit tests are run. There are plugins for Eclipse and Intellij IDEA. Eclipse has a “Compile on Save” feature, in IDEA it is a good approach to map shortcut ‘Ctrl + s’ to “Compile (file)” action.
  • Jester.
    Jester finds code that is not covered by your tests by making some changes to source code of original classes. This principle is called mutation testing. Jester is not under active development.Fortunately, there is a better up-to-date and more capable alternative called PIT. It seamlessly integrates with maven, ant and gradle and there is even the PIT Sonar Plugin. Be aware that mutation testing can take a lot of time therefore it can be useful to run these types of tests against only some portion of your codebase.

  • Spock, JBehave, Cucumber – acceptance testing. Acceptance tests are driven by customer requirements.
    Very interesting subject -> Will be discussed in some future post.
  • Groovy.
    Groovy is a dynamic language and is especially useful for writing tests. Here are some tips and links for writing unit tests in Groovy. Even if you have your main source code in java you can easily write unit tests in Groovy.

  • JTestR – Enables us to write unit tests for java code in ruby. This does not seem attractive for me – I’ll use Groovy instead.
Posted in Uncategorized | Tagged | Leave a comment

Base64 encoding using apache commons codec and problematic CR LF

While trying to use Base64 Encoder from apache commons codec I have encountered a following problem: trailing CR LF characters cause encoding string to be refused by validation.

The root cause of this problem is a fact that original Base 64 standard use CR LF for separation of encoded lines. However, in my case (encoding crypthographic signature) this was not a desired behavior. Instead of simple usage:

Base64.encodeBase64String(stringToBeEncoded)

I had to use following form

 StringUtils.newStringUtf8(Base64.encodeBase64(stringToBeEncoded, false));

“false” means that in this case the encoded value won’t bu chunked and therefore no CR LF trailing characters!

Posted in Uncategorized | Tagged | Leave a comment

Spring Data MongoDB struggling

We are starting to use mongo document oriented database for storing data about schedules and executions for our new scheduler.
Since we want to use Spring Data support for mongo I examined its possibilities.

Let’s have following objects:

public class Schedule {
    String name;
    Map parameters;
    DateTime nextExecutionTime;
    Execution lastExecution;
}
public class Execution {
    DateTime startTime;
    DateTime endTime;
    String status;
}

Schedules are stored in mongo DB database, in collection named “schedules”.
Now, imagine that we want to get all schedules ready for processing. Those are the schedules that met following criteria:

1) (Schedule#lastExecution is not defined (null))
OR
2)(Schedule#lastExecution.status is “OK” or “ERROR
AND
Schedule#nextExecutionTime <= current time)

Have not been working with spring data and mongo db ever before, I realized to get results quite difficult.
I constructed two queries one for each condition ( 1) and 2) ).

    Query noLastExecutionQuery = Query.query(
            Criteria.where("lastExecution").exists(false);
    Query okOrErrorLastExecution = Query.query(
            Criteria.where("lastExecution.status").in("OK", "ERROR")
                   .and("nextExecutionTime").lte(currentTimeInMillis);

Now, I try to use OrQuery (descendant of Query):

    new OrQuery(noLastExecutionQuery, okOrErrorLastExecution);

This approach simply does not work because OrQuery combines criteria from both queries incorrectly.
This issue with OrQuery criteria building makes me looking for alternative approach:

        final Criteria schedulesCriteria = new Criteria()
                .orOperator(
                        // either schedules without lastExecution
                        where("lastExecution").exists(false),
                        // OR status in (OK, ERROR) AND nextExecutionTime <= current time
                        where("lastExecution.status")).in("OK", "ERROR")
                                .and("nextExecutionTime).lte(new Date().getTime()));
        Query schedulesQuery = new Query(schedulesCriteria);

schedulesQuery can now be used e.g. as a parameter into MongoTemplate#find method to find all schedules critera.

PS: When searching for root cause of issue, I have found a mongosniff to be a very useful tool for showing real queries being executed against Mongo DB.

Posted in Programming, Spring | Tagged | 1 Comment