Solving “Received fatal alert: handshake_failure” error when performing HTTPS connections on a custom made JRE with jlink

TL; Tell me already what to do:
Add the jdk.crypto.cryptoki module to the list of --add-modules parameter to your jlink command invocation


If you’re reading this you’re one of the few developers out there that wanted to distribute a java 9+ app (using either jdk 9, jdk 10, jdk 11 or jdk 12, as of this writing) with a smaller version of the jdk, to build your custom jre, you used the jlink tool.

When you run your app using the full JRE that comes with the OpenJDK, your app is working fine when it comes to making https requests, but when you run your app using your custom jre you get the following error when opening https connections

Received fatal alert: handshake_failure

This issue occurs because your JRE is missing lots of Cipher Suites that come with the full JDK.

With your JDK, you can try to check the list of supported ciphers with this one liner using the jrunscript tool:

jrunscript -e "print(java.util.Arrays.toString(javax.net.ssl.SSLServerSocketFactory.getDefault().getSupportedCipherSuites()))"

however that might not work for your custom JRE if you haven’t included the scripting module, so here’s a Java program I made that prints all the available Ciphers of your JRE

public class PrintCiphers {
    public static void main(String[] args) {
	var sslSocketFactory = javax.net.ssl.SSLServerSocketFactory.getDefault();
	System.out.println("SSLServerSocketFactory -> " + sslSocketFactory.getClass().getName());
	try {
  	    var getSupportedCipherSuitesMethod = sslSocketFactory.getClass().getMethod("getSupportedCipherSuites");
	    String[] ciphers = (String[]) getSupportedCipherSuitesMethod.invoke(sslSocketFactory);
	    int i=1;
            for (String c : ciphers) {
		System.out.println(i++ + " " + c);
	    }
	} catch(Throwable t) {
	    t.printStackTrace();
	}
    }
}

If you run PrintCiphers on your OpenJDK’s full JRE, you will see almost 50 Cipher Suites available:

$ java PrintCiphers;
1 TLS_AES_128_GCM_SHA256
2 TLS_AES_256_GCM_SHA384
3 TLS_CHACHA20_POLY1305_SHA256
4 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
5 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
6 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
7 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
8 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
9 TLS_RSA_WITH_AES_256_GCM_SHA384
10 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
11 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
12 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
13 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
14 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
15 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
16 TLS_RSA_WITH_AES_128_GCM_SHA256
17 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
18 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
19 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
20 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
21 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
22 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
23 TLS_RSA_WITH_AES_256_CBC_SHA256
24 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
25 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
26 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
27 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
28 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
29 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
30 TLS_RSA_WITH_AES_256_CBC_SHA
31 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
32 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
33 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
34 TLS_DHE_DSS_WITH_AES_256_CBC_SHA
35 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
36 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
37 TLS_RSA_WITH_AES_128_CBC_SHA256
38 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
39 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
40 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
41 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
42 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
43 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
44 TLS_RSA_WITH_AES_128_CBC_SHA
45 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
46 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
47 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
48 TLS_DHE_DSS_WITH_AES_128_CBC_SHA
49 TLS_EMPTY_RENEGOTIATION_INFO_SCSV

but if you use your custom JRE to run PrintCiphers you will see only 23 Cipher Suites available:

$ jre/bin/java PrintCiphers
1 TLS_AES_128_GCM_SHA256
2 TLS_AES_256_GCM_SHA384
3 TLS_CHACHA20_POLY1305_SHA256
4 TLS_RSA_WITH_AES_256_GCM_SHA384
5 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
6 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
7 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
8 TLS_RSA_WITH_AES_128_GCM_SHA256
9 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
10 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
11 TLS_RSA_WITH_AES_256_CBC_SHA256
12 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
13 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
14 TLS_RSA_WITH_AES_256_CBC_SHA
15 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
16 TLS_DHE_DSS_WITH_AES_256_CBC_SHA
17 TLS_RSA_WITH_AES_128_CBC_SHA256
18 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
19 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
20 TLS_RSA_WITH_AES_128_CBC_SHA
21 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
22 TLS_DHE_DSS_WITH_AES_128_CBC_SHA
23 TLS_EMPTY_RENEGOTIATION_INFO_SCSV

To solve the problem you must add the jdk.crypto.cryptoki module to the list of --add-modules parameter to your jlink command invocation, next time your run PrintCiphers you should see the full list of Cipher Suites and your SSL handshake issues should be gone.

How to run your Kotlin gradle built app from the command line

So you build your Kotlin app, you went through the trouble of creating a build.gradle script that you build with

gradle assemble

this outputs a a “build/libs/kotlin.jar” .jar file, but you have no clue how to run your Kotlin code from the command line.

Doing it by hand with “java -cp ” is too much work, and there is a way to do

gradle run

or even

gradle -b /home/myuser/mykotlinapp/build.gradle run

in case you need to run your Kotlin script from a cronjob.

Make sure you have the following inside your build.gradle script in order to make the “run” task available


apply plugin: 'application'

// DO notice the "Kt" suffix on the class name below, if you don't use the Kt generated class you will get errors
mainClassName = 'com.myapp.MyKotlinAppKt'

// optional: add one string per argument you want as the default JVM args
applicationDefaultJvmArgs = ["-Xms512m", "-Xmx1g"]

What if I don’t want to use gradle, and just java

ok… ok…
java -cp $KOTLIN_LIB/kotlin-runtime.jar:build/libs/kotlin.jar: com.myapp.MyKotlinAppKt

[CODE/JAVA] Scanner – read a full line

I was solving problems at HackerRank to teach a friend how to code in Java and to process the input data it’s convenient to use Java’s built in Scanner class.

However, in one of the problems we wanted to read a whole line at once and we noticed that the Scanner’s API is geared towards reading the next token, and it doesn’t have a method that reads the entire line. It has one method that skips a line and reads from the last point which is very weird to use, so we created a static method to just read the next entire line, keeping it simple.

public static String readLine(Scanner scanner) {
            Pattern oldDelimiter = scanner.delimiter();
            scanner.useDelimiter("\\r\\n|[\\n\\x0B\\x0C\\r\\u0085\\u2028\\u2029]");
            String r = scanner.next();
            scanner.useDelimiter(oldDelimiter);
            return r;
    }

The Scanner uses as its default token delimiter a whitespace pattern, so what we do in this method is to temporarily replace the token delimiter for a newline delimiter. Once set to newline all we need to do is to read the next token, which will be the entirety of the line, and then we put the previous delimiter set back in place.

In Java 8 there’s a new Linebreak matcher expression \R, however, if we want our method to be backwards compatible (as we don’t know on which JRE it could be running) we set the equivalent delimiter manually in our function

\R  Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

If you don’t like the static function approach you can always repurpose this code and extend Scanner into a custom MyScanner class , and add a method nextLine that does the same thing

[CODE/JAVA] ARGB_8888 Pixel Abstraction

This is one of the ways you can decode Pixel colors out of the integers you get from Android Pixels.

ARGB_8888, stands for Alpha, Reg, Green, Blue. The 8’s stand for the number of bits per channel.

In Android, signed int‘s are used to represent pixel’s alpha/color information.
Since Android’s language of choice is java, these ints are 32-bit integers, each int takes 4 bytes.

4 bytes = 32 bits = 8bits + 8bits + 8bits + 8bits.

If you had an int like 0xFFAABBCC, each pair of letters on that hexadecimal would mean the following from left to right

{alpha=0xFF}{red=0xAA){green=0xBB}{blue=0xCC}

If you’ve done web programming and played with rgb colors and you didn’t know about this, now it all should click on how your web browser represents colors, except in HTML you don’t deal with the alpha value in the front. On Android’s XML you do.

In bits (binary), the 0xFFAABBCC value would look like this:

alpha red green blue
0xFF 0xAA 0xBB 0xCC
255 170 187 204
{0b11111111}{0b10101010}{0b10111011}{0b11001100}

If you wanted to look at the entire number in binary/bits, it’d be something like this (leaving spaces for visual help):

0b11111111 10101010 10111011 11001100 == 0xFFAABBCC == 4289379276

So if you wanted to get the red channel (0xAA = 170 = 0b10101010) , you’d have to move the whole thing towards the right 16 places, and then compare it with only the rightmost 8 bits.

So, we shift 16 places to the right, we’d get rid of the 2 bytes on the right side and end up only with the left half

0b11111111 10101010

Since we only care about those 8 bits on the right, we do an “&” (bitwise “and”) against 0xFF=255=0b111111111 (all 8 rightmost bits set to 1)

0b11111111 10101010 &
0b00000000 11111111
====================
0b00000000 10101010

So with simple right bit shifting and “& 0xff” of the shifted value we can extract the values per channel.

This class also features a “multiplyByFloat()” function, which I was using to multiply to each channel as I was operating with convolution kernels while playing with image filters.

/** ARGB_8888 Pixel abstraction */
public static class PixelARGB_8888 {
 public final byte a;
 public final byte r;
 public final byte g;
 public final byte b;
 public final int intVal;

 public PixelARGB_8888(final int argb32bitInt) {
  a = (byte)((argb32bitInt >> 24) & 0xff);
  r = (byte)((argb32bitInt >> 16) & 0xff);
  g = (byte)((argb32bitInt >> 8) & 0xff);
  b = (byte)(argb32bitInt & 0xff);
  intVal = argb32bitInt;
 }

 public PixelARGB_8888(byte a, byte r, byte g, byte b) {
  this.a = a;
  this.r = r;
  this.g = g;
  this.b = b;
  intVal = (a << 24) + (r << 16) + (g << 8) + b;
 }

 public static int multiplyByFloat(float factor, int arg32bitInt) {
  return multiplyByFloat(factor, arg32bitInt, false);
 }

 public static int multiplyByFloat(float factor, int argb32bitInt, boolean multiplyAlphaChannel) {
  PixelARGB_8888 original = new PixelARGB_8888(argb32bitInt);
  byte alpha = original.a;
  if (multiplyAlphaChannel) {
   alpha = (byte)(original.a * factor);
  }
  PixelARGB_8888 multiplied = new PixelARGB_8888(alpha, (byte)(factor * original.r), (byte)(factor * original.g), (byte)(factor * original.b));
  return multiplied.intVal;
 }
}

IntelliJ / Adroid Studio / CLion / GoLand / PyCharm / PHPStorm keymap shortcuts I can’t live without

Download settings.jar (Import with `File -> Import Settings`)

I got to IntelliJ after years of using Emacs and Eclipse. Here’s how my keymap looks now that I work with Jetbrains tools, these are the keyboard shortcuts I can’t live without as a programmer.

 

Legend (Mac keyboard)
⌘ Command
⇧ Shift

⌘1 Show Intent Actions (Things like assign to local variable)
⌘- Decrease font size
⌘= Increase font size
⌘0 Reset font size
⌘↓ Scroll to botom
⌘↑ Scroll to top
⌘f Find in text
⌘. Find next highlighted error
^⇧F Find in path (searches in all files, like a grep)
⌘⇧G Find Usages (Find all Occurrences of selected symbol [variable, method, class, identifier])
⌘I Show current function/method parameter info
F3 Jump to source (go inside function’s code)
⌘E Show list of recent files
⌘B Build
⌘L Jump to line number
⌘[ Back
⌘] Forward
⌘T Show implementations of an interface.
⌘⇧F Format (selected) code
⌘⇧O Organize/Optimize imports
⌘⌥R Rename current symbol
^K Kill line
⌘D Duplicate line
Ctrl+G on selected token – repeats selection and enables multiple cursors
Alt+Up | Alt+Down – Move the current line up or down

Debugger shortcuts
F5 Step Into
F6 Step Over
F7 Step Out
F9 Resume Program

^K Cut up to Line End. (Deletes everything to the right of where the text cursor or caret is)

2 Java debugging tricks

1. Embed state in your thread names.

Some times when you see a crash log with a thread dump, you see the stack of all the threads at the moment of the snapshot, but there’s no way to see what the state of the variables and objects at play in the thread were like.

You can use Thread.currentThread.setName(...) and embed variable states on the thread name for a more useful thread dump output.

2. Set a Default uncaught exception handler and log the error to the thread.

 

GRADLE: How to specify resources from different folders on your sourceSet

Sometimes you need to have resources in your sourceset and these may come from different locations on disk, the official documentation is lacking in real world examples, or at least I just didn’t understand it very well, but from reading forums I finally got it to work.

In the example I specify what files to include/exclude from two different folders.
When the final .jar is created, they’ll keep the package path structure that lives inside the given srcDir folders.

If you just want to add these files (for some reason to the root of your resulting jar, you should make srcDir the full path to where the files live)

sourceSets {
main {
java {
//your java source paths and exclusions go here…
}

resources {
srcDir ‘components/resources/src/main/resources’
include ‘**/*.properties’
include ‘**/*.png’
include ‘**/*.gif’
include ‘**/*.jpg’
include ‘**/*.html’
include ‘**/*.js’
include ‘**/*.sh’
include ‘**/*.dat’
include ‘**/*.icc’
exclude ‘**/*.DS_Store’

srcDir ‘common/vuze/azureus2/src’
include ‘**/Messages*.properties’
exclude ‘**/*.class’
exclude ‘**/*.java’
}
}
}

GRADLE: How to copy files from another .jar into your resulting output .jar

In our project we like to deliver a single jar as the final product, if you need to copy files that live on an existing jar into the Gradle’s output jar, this example shows you how to do that (and more)

jar {
//this is how you change the name of the output jar
archiveName=’frostwire.jar’

//some exclusion rules to keep your .jar clean
exclude(‘META-INF/*.SF’, ‘META-INF/*.DSA’, ‘META-INF/*.RSA’, ‘META-INF/*.MF’)

//here we grab all the .class files inside messages.jar and we put them in our resulting jar
from (zipTree(‘lib/jars/messages.jar’)) {
include ‘**/*.class’
}

//how to manipulate the jar’s manifest
manifest {
attributes ‘Main-Class’: ‘com.limegroup.gnutella.gui.Main’
}
}

GRADLE: How to add a list of local .jar files to the build classpath

Sometimes you don’t want/cant use maven repos, all you have is a bunch of local jars on disk that you want to use as part of your compilation classpath, and the freaking gradle documentation is too vague.

Here is an example:

dependencies {
compile files(‘lib/jars/gettext-commons.jar’,
‘lib/jars/lucene-3.5.0.jar’,
‘lib/jaudiotagger.jar’,
‘lib/jars/h2-1.3.164.jar’,
‘lib/jars/messages.jar’,
‘lib/jars/slf4j-api-1.7.5.jar’,
‘lib/jars/jaudiotagger.jar’,
‘lib/jars/metadata-extractor-2.6.2.jar’
)
}

[SOLVED] Gradle: How to increase the Java Compiler’s available Heap Memory

The documentation is not very clear on what all the available options are…
after much Googling and many different attempts finally figured out how to raise the maximum heap of the compiler from within the gradle.build script.

apply plugin: ‘java’

compileJava {
//raise heap
options.fork = ‘true’
options.forkOptions.with {
memoryMaximumSize = “2048m”
}
}

Update:
So I’ve noticed this works great on MacOSX, but it doesn’t work at all on Windows 8.

The solution to increasing the JVM’s Heap has been to remove those options from gradle.build script and add a new file on the same folder as where your gradle.build file lives called ‘gradle.properties’

These are the contents that made it work for both Mac and Windows (I’ve still not tested this on my linux box)

org.gradle.jvmargs=-Xms256m -Xmx1024m