The Holy Java

Building the right thing, building it right, fast

Archive for the ‘Languages’ Category

Topics related to a programming language and to these languages in general

Java: Simulating various connection problems with Toxiproxy

Posted by Jakub Holý on November 26, 2018

Advertisements

Posted in Languages | Tagged: | Leave a Comment »

Clojure – comparison of gnuplot, Incanter, oz/vega-lite for plotting usage data

Posted by Jakub Holý on November 4, 2018

What is the best way to plot memory and CPU usage data (mainly) in Clojure? I will compare gnuplot, Incanter with JFreeChart, and vega-lite (via Oz). (Spoiler: I like Oz/vega-lite most but still use Incanter to prepare the data.)

The data looks like this:

;; sec.ns | memory | CPU %
1541052937.882172509 59m 0.0
1541052981.122419892 78m 58.0
1541052981.625876498 199m 85.9
1541053011.489811184 1.2g 101.8

The data has been produced by monitor-usage.sh.

The tools

Gnuplot 5

Gnuplot is the simplest, with a lot available out of the box. But it is also somewhat archaic and little flexible.

Read the rest of this entry »

Posted in Languages, [Dev]Ops | Tagged: , , | Comments Off on Clojure – comparison of gnuplot, Incanter, oz/vega-lite for plotting usage data

Beware the performance cost of async_hooks (Node 8)

Posted by Jakub Holý on November 1, 2018

I was excited about async_hooks having finally landed in Node.js 8, as it would enable me to share important troubleshooting information with all code involved in handling a particular request. However it turned out to have terrible impact of our CPU usage (YMMV):

This was quite extreme and is likely related to the way how our application works and uses Promises. Do your own testing to measure the actual impact in your app.

However I am not the only one who has seen some performance hit from async_hooks – see https://github.com/bmeurer/async-hooks-performance-impact, in particular:

Here the results of running the Promise micro benchmarks with and without async_hooks enabled:

Benchmark Node 8.9.4 Node 9.4.0
Bluebird-doxbee (regular) 226 ms 189 ms
Bluebird-doxbee (init hook) 383 ms 341 ms
Bluebird-doxbee (all hooks) 440 ms 411 ms
Bluebird-parallel (regular) 924 ms 696 ms
Bluebird-parallel (init hook) 1380 ms 1050 ms
Bluebird-parallel (all hooks) 1488 ms 1220 ms
Wikipedia (regular) 993 ms 804 ms
Wikipedia (init hook) 2025 ms 1893 ms
Wikipedia (all hooks) 2109 ms 2124 ms

To confirm the impact of async_hook on our app, I have performed 3 performance tests:

CPU usage without async_hooks (Node 8)

It is difficult to see but the mean CPU usage is perhaps around 60% here.

CPU usage with “no-op” async_hooks (Node 8)

Here the CPU jumped to 100%.

CPU usage with “no-op” async_hooks (Node 11)

The same as above, but using Node 11 for comparison. I recorded it for just a few minutes but the CPU usage is still around 100%:

The code

This is the relevant code:

Posted in Languages | Tagged: , | Comments Off on Beware the performance cost of async_hooks (Node 8)

Troubleshooting javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Posted by Jakub Holý on October 5, 2018

Re-published from the Telia Tech Blog.

The infamous Java exception javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure is hardly understandable to a mere mortal. What it wants to say is, most likely, something like this:

Sorry, none of the cryptographic protocols/versions and cipher suites is accepted both by the JVM and the server.

For instance the server requires a higher version of TLS than the (old) JVM supports or it requires stronger cipher suites than the JVM knows. You will now learn how to find out what is the case.

We will first find out what both the server and the JVM support and compare it to see where they disagree. Feel free to just skim through the outputs and return to them later after they were explained.

What does the server support?

We will use nmap for that (brew install nmap on OSX):

map --script ssl-enum-ciphers -p 443 my-server.example.com
Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-05 00:54 CEST
Nmap scan report for my-server.example.com (127.0.0.1)
Host is up (0.031s latency).

PORT STATE SERVICE
443/tcp open https
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| compressors:
| NULL
| cipher preference: server
|_ least strength: A

Here we see that the server only supports TLS version 1.2 (ssl-enum-ciphers: TLSv1.2:) and the listed ciphers, such as TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA.

What does the JVM have on offer?

Now we will find out what the JVM supports (I did that through Clojure but you could have just as well used Java directly; notice the javax.net.debug property):

sh $ env -i java -Djavax.net.debug=ssl:handshake:verbose java -jar clojure-1.8.0.jar
Clojure 1.8.0
user=> (.connect (.openConnection (java.net.URL. "https://my-server.example.com/ping")))
;; ...
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1521850374 bytes = { 121, 217, 101, 186, 111, 183, 47, 46, 159, 230, 139, 103, 7, 181, 250, 172, 113, 121, 4, 55, 122, 148, 111, 82, 87, 170, 70, 10 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: my-server.example.com]
***
main, WRITE: TLSv1 Handshake, length = 175
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
SSLHandshakeException Received fatal alert: handshake_failure sun.security.ssl.Alerts.getSSLException (Alerts.java:192)

Here we see that the JVM uses TLS version 1 (see *** ClientHello, TLSv1) and supports the listed Cipher Suites, including TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA.

What’s wrong?

Here we see that the server and JVM share exactly one cipher suite, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA. But they fail to agree on the TLS version, since the server requires v1.2 while the JVM only offers v1.

The solution

You can either configure the server to support a cipher suite and protocol version that the JVM has or teach JVM to use what the server wants. In my cases that was resolved by running java with -Dhttps.protocols=TLSv1.2 (alternatively, you could add all of SSLv3,TLSv1,TLSv1.1,TLSv1.2) as recommended by π at StackOverflow.

Sources

The troubleshooting technique comes from the article “SSLHandshakeException: Received fatal alert: handshake_failure due to no overlap in cipher suite
” by Atlassian. The observation that the server and JVM disagreed on the TLS version comes from my good colleague Neil.

Posted in General, Languages | Tagged: , , | Comments Off on Troubleshooting javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Experience: Awesome productivity with ClojureScript’s REPL

Posted by Jakub Holý on December 21, 2017

Re-posted from Telia’s tech blog.

What’s the deal with ClojureScript? How can you justify picking such a “niche” language? I have recently experienced a “wow” session, demonstrating the productivity gains of ClojureScript and the interactive development it enables thanks to its REPL. I would like to share the experience with you. (If you have never heard about it before – it is a modern, very well designed Lisp that compiles to JavaScript for frontend and backend development. It comes with a REPL that makes it possible to reload code changes and run code in the context of your live application, developing it while it is running.)

Read the rest of this entry »

Posted in Languages | Tagged: , , | Comments Off on Experience: Awesome productivity with ClojureScript’s REPL

Storytelling as a Vehicle of Change: Introducing ClojureScript for the Heart and Mind

Posted by Jakub Holý on October 7, 2015

People don’t really like changes yet change we must in this fast-developing world. How to introduce a change, or rather how to inspire people to embrace a change? That is one of the main questions of my professional life.

I have recently talked about Functional programming (FP) in JavaScript and compared it to ClojureScript, which was designed for FP. To my surprise the team proposed to give ClojureScript a try and we agreed to have a live coding session, implementing a new functionality in our internal part of our webshop using ClojureScript. But how to kindle this little flame of motivation to keep it going, despite hurdles that will certainly come? And here I got a few interesting ideas.

  1. An experienced speaker once recommended sharing personal experiences (even – or especially – if they make me vulnerable) as it is much easier for people to relate to them than to general statements.
  2. A Cognicast eposide mentioned storytelling as a great tool for introductory guides. We humans are natural storytellers, we think in stories and relate to them much more easily – so a story should be great also to communicate the value of a change.
  3. My ex-colleague Therese Ingebrigtsen gave an inspiring talk presenting some points from The Switch – mainly that we need to address the recipient’s minds with rational arguments, but also their hearts to involve their emotion (e.g. by drawing a picture of the new bright future), and that it is important to show a clear path forward.

Read the rest of this entry »

Posted in General, Languages | Tagged: , , | Comments Off on Storytelling as a Vehicle of Change: Introducing ClojureScript for the Heart and Mind

An answer to CircleCI’s “Why we’re no longer using Core.typed”

Posted by Jakub Holý on October 6, 2015

CircleCI has recently published a very useful post “Why we’re no longer using Core.typed” that raises some important concerns w.r.t. Typed Clojure that in their particular case led to the cost overweighting the benefits. CircleCI has a long and positive relation to Ambrose Bonnaire-Sergeant, the main author of core.typed, that has addressed their concerns in his recent Strange Loop talk “Typed Clojure: From Optional to Gradual Typing” (gradual typing is also explained in his 6/2015 blog post “Gradual typing for Clojure“). For the sake of searchability and those of us who prefer text to video, I would like to summarise the main points from the response (spiced with some thoughts of my own).

Read the rest of this entry »

Posted in Languages | Tagged: , | Comments Off on An answer to CircleCI’s “Why we’re no longer using Core.typed”

Refactoring & Type Errors in Clojure: Experience and Prevention

Posted by Jakub Holý on October 6, 2015

While refactoring a relatively simple Clojure code to use a map instead of a vector, I have wasted perhaps a few hours due to essentially type errors. I want to share the experience and my thoughts about possible solutions since I encounter this problem quite often. I should mention that it is quite likely that it is more a problem (an opportunity? :-)) with me rather than the language, namely with the way I write and (not) test it.

The core of the problem is that I write chains of transformations based on my sometimes flawed idea of what data I have at each stage. The challenge is that I cannot see what the data is and have to maintain a mental model while writing the code, and I suck at it. Evaluating the code in the REPL as I develop it helps somewhat but only when writing it – not when I decide to refactor it.

Read the rest of this entry »

Posted in Languages | Tagged: , , | Comments Off on Refactoring & Type Errors in Clojure: Experience and Prevention

Example: Functional Reactive Programming decisively beats Imperative on simplicity, length

Posted by Jakub Holý on June 17, 2015

@theburningmonk Yan Cui has a nice example demonstrating how Functional Reactive Programming [slides 185 – 206] (with Elm’s Signals) yields a much shorter and easier to understand (one you know FRP) code than an imperative code with mutations spread all over the code base.

The game

Use the Up and Down keys to move the platforms and thus bounce the ball from left to right and back:

screenshot-game

The imperative solution

Read the rest of this entry »

Posted in Languages | Tagged: , | Comments Off on Example: Functional Reactive Programming decisively beats Imperative on simplicity, length

A Usable Node.js REPL for Emacs

Posted by Jakub Holý on March 11, 2015

Being used to the excellent REPL in Clojure(Script), I was surprised to find out that Node.js REPL is somewhat weak and that its support in Emacs is not actively maintained. I anyway managed to get a usable REPL with these three components:

  1. The Emacs nodejs-repl package (nearly 2 years old)
  2. J. David Smith’s nodejs-repl-eval.el to be able to send code to the REPL (binding nodejs-repl-eval-dwim to C-x C-e so that I can execute the current sexp/region)
  3. My own extension of nodejs-repl-eval.el that takes care of escaping JS constructs that the REPL interprets in a special way

Regarding #3: The problem with the Node.js REPL is that valid JS code does not always behave correctly in the REPL. This is because: 1) _ is a special variable (the last result) while in code it is often used for the underscore/lodash library; 2) The REPL also interprets lines somewhat separately and tries to execute <dot><name> as a REPL command, breaking chained calls that start on a new line. My solution uses some RegExp magic to turn

var _ = require("lodash"); // #1a conflicting use of _
_.chain([1,2])             // #1b conflicting use of _
   .first()                // #2 interpreted as non-existing REPL command '.first'
   .value();

into

var __ = require("lodash");  // #1a Notice the doubled _
__.chain([1,2]).             // #1b Notice the doubled _
   first().                  // #2 Notice the dot has moved to the previous line
   value();

when the code is being sent to the REPL

Posted in Languages, Tools | Tagged: , , | Comments Off on A Usable Node.js REPL for Emacs