<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matthew Gilliard</title>
    <description>The latest articles on DEV Community by Matthew Gilliard (@mjg123).</description>
    <link>https://dev.to/mjg123</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F173566%2Fdc5e7851-4a8e-4b82-8632-81183bf9b8d9.jpeg</url>
      <title>DEV Community: Matthew Gilliard</title>
      <link>https://dev.to/mjg123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mjg123"/>
    <language>en</language>
    <item>
      <title>How to build a CLI app in Java using jbang and picocli</title>
      <dc:creator>Matthew Gilliard</dc:creator>
      <pubDate>Mon, 17 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/mjg123/how-to-build-a-cli-app-in-java-using-jbang-and-picocli-262n</link>
      <guid>https://dev.to/mjg123/how-to-build-a-cli-app-in-java-using-jbang-and-picocli-262n</guid>
      <description>&lt;p&gt;Traditionally Java applications have been used for long-running processes - web application servers can run for days or weeks at a time. The JVM handles this well: &lt;a href="https://www.baeldung.com/jvm-garbage-collectors"&gt;Garbage Collection&lt;/a&gt; is efficient over huge amounts of memory, and &lt;a href="https://en.wikipedia.org/wiki/Profile-guided_optimization"&gt;Profile-Guided Optimization&lt;/a&gt; can make your code faster the longer it runs.&lt;/p&gt;

&lt;p&gt;However, it’s perfectly possible to write short-lived apps too, and in this post I’ll show how to build a CLI app whose total runtime is just a couple of seconds. You can build sophisticated CLI tools in Java for data processing, connection to databases, &lt;a href="https://dev.to/twilio/5-ways-to-make-http-requests-in-java-2p3"&gt;fetching data from the web&lt;/a&gt;, or taking advantage of any of the Java libraries that you're used to.&lt;/p&gt;

&lt;p&gt;I’ll use &lt;a href="https://jbang.dev"&gt;jbang&lt;/a&gt; for packaging and running the app, and &lt;a href="https://picocli.info/"&gt;picocli&lt;/a&gt; to handle argument parsing and output.  The app will send an SMS using &lt;a href="https://www.twilio.com/docs/sms/api"&gt;Twilio’s Messaging API&lt;/a&gt;, in a single Java source file less than 100 lines long.&lt;/p&gt;

&lt;p&gt;To follow along you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sdkman.io/"&gt;SDKMAN!&lt;/a&gt; - I wrote about &lt;a href="https://dev.to/twilio/using-sdkman-to-work-with-multiple-versions-of-java-54km"&gt;why I love SDKMAN!&lt;/a&gt; Before.&lt;/li&gt;
&lt;li&gt;a Twilio account. If you don’t have one already, get one for free at &lt;a href="https://twilio.com/try-twilio"&gt;https://twilio.com/try-twilio&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;your Twilio account credentials set as &lt;a href="https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html"&gt;environment variables&lt;/a&gt;: &lt;code&gt;TWILIO_ACCOUNT_SID&lt;/code&gt; and &lt;code&gt;TWILIO_AUTH_TOKEN&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ❗ Jbang
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jbang.dev/"&gt;Jbang&lt;/a&gt; is a one-stop shop for making Java applications that can be run as scripts. It can download the required version of Java, add dependencies and create self-executing source files. It can also run Java code directly from the web, from github repos or even from Twitter (if you can fit your code into &lt;a href="https://twitter.com/maxandersen/status/1266329490927616001"&gt;280 characters&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Using SDKMAN! install jbang with: &lt;code&gt;sdk install jbang&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For the impatient: Once you have jbang installed you can skip the rest of this post and run the code directly from GitHub with &lt;code&gt;jbang https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java&lt;/code&gt; - the first time you run it, you will be reminded that running code from URLs is inherently unsafe - you can trust me here though&lt;/em&gt; 😉&lt;/p&gt;

&lt;p&gt;To create a new script for a CLI app, in an empty directory run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jbang init --template=cli SendSms.java
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This creates a single file, &lt;code&gt;SendSms.java&lt;/code&gt; which you can run directly with &lt;code&gt;./SendSms.java&lt;/code&gt;. This file is valid both as Java source and as a shell script, thanks to the first line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//usr/bin/env jbang "$0" "$@" ; exit $?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a neat trick that works as Java since it’s a comment. As a shell script it runs &lt;code&gt;jbang&lt;/code&gt;, passing the name of the source file and any arguments.&lt;/p&gt;

&lt;p&gt;The second line shows how to add dependencies to a jbang script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//DEPS info.picocli:picocli:4.2.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the standard &lt;code&gt;GROUP_ID:ARTIFACT_ID:VERSION&lt;/code&gt; format for dependencies, used by gradle and other build tools.&lt;/p&gt;

&lt;p&gt;The rest of the file is normal Java code which is the “Hello World” for picocli, a library for creating CLI apps in Java.&lt;/p&gt;

&lt;p&gt;The last thing to do with jbang is to create a project which works in an IDE. You can’t just open the &lt;code&gt;SendSms.java&lt;/code&gt; file because jbang needs to download dependencies and add them to the classpath.&lt;/p&gt;

&lt;p&gt;Find out how to launch your IDE from the command line. For me on Linux it’s &lt;a href="https://intellij-support.jetbrains.com/hc/en-us/articles/360011901879-How-to-start-IDE-from-the-command-line"&gt;&lt;code&gt;idea.sh&lt;/code&gt;&lt;/a&gt; - for you it might be &lt;code&gt;idea&lt;/code&gt; or &lt;code&gt;eclipse&lt;/code&gt; or &lt;code&gt;code&lt;/code&gt; or something else, depending on which IDE you like and how you installed it. The following command will create a project that your IDE can understand, open the IDE and then monitor the project for changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jbang edit --live=&amp;lt;YOUR IDE COMMAND&amp;gt; SendSms.java
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command will wait indefinitely, watching for changes to the project. For testing the app as you are working, I find it easiest to have another open terminal in the same directory. Make sure to open this &lt;em&gt;after&lt;/em&gt; installing jbang to make sure that it is on your &lt;code&gt;$PATH&lt;/code&gt;. Now let's get into the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⌨️ Picocli
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://picocli.info/"&gt;Picocli&lt;/a&gt; is a library for creating CLI apps in Java. The goal for today is to modify the existing &lt;code&gt;SendSms.java&lt;/code&gt; so that it actually sends SMS. The arguments to the script will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;to&lt;/code&gt; phone number (probably your cell number)&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;from&lt;/code&gt; number (your Twilio number)&lt;/li&gt;
&lt;li&gt;the message body can be specified at the end of the command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The phone numbers should always be in &lt;a href="https://www.twilio.com/docs/glossary/what-e164"&gt;E.164 format&lt;/a&gt;. Running the script would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./SendSms.java \
    --to +4477xxxxxx46 \
    --from +1528xxxxx734 \
    Ahoy there 👋
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If the message isn't at the end of the command, it will be read from standard in, which means you can use the script in a &lt;a href="https://en.wikipedia.org/wiki/Pipeline_(Unix)"&gt;pipeline&lt;/a&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fortune | ./SendSms.java --to +4477xxxxxx46 --from +1528xxxxx734 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(&lt;a href="https://en.wikipedia.org/wiki/Fortune_(Unix)"&gt;fortune&lt;/a&gt; is a UNIX command that prints "funny" quotes)&lt;/p&gt;

&lt;h3&gt;
  
  
  ⁉️ Command line Options and Parameters
&lt;/h3&gt;

&lt;p&gt;Picocli distinguishes between &lt;strong&gt;options&lt;/strong&gt;  and &lt;strong&gt;parameters&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Options have names, specified by flags, and can appear in any order: &lt;code&gt;--to&lt;/code&gt; and &lt;code&gt;--from&lt;/code&gt; are options.&lt;/li&gt;
&lt;li&gt;Parameters are positional, the words of the message will be parameters if they're given at the end of the command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Delete the &lt;code&gt;private String greeting&lt;/code&gt; and its annotation, and add parameters and options for &lt;code&gt;--to&lt;/code&gt; &lt;code&gt;--from&lt;/code&gt; and the message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@CommandLine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"-t"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"--to"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The number you're sending the message @|bold to|@"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@CommandLine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"-f"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"--from"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The number you're sending the message @|bold from|@"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fromPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Parameters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The message to send"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;arity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0..\*"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java#L20-L37"&gt;this code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;The first two highlighted lines include text surrounded by &lt;code&gt;@|bold … |@&lt;/code&gt; which tells picocli to &lt;a href="https://picocli.info/#_ansi_colors_and_styles"&gt;format&lt;/a&gt; the words &lt;code&gt;to&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;message&lt;/code&gt; we specify the arity as &lt;code&gt;0..*&lt;/code&gt; which means "zero or more parameters", which will be gathered into an array of Strings. Note that if there are zero then &lt;code&gt;message&lt;/code&gt; will be &lt;code&gt;null&lt;/code&gt; rather than an empty array.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚪 About exit codes
&lt;/h3&gt;

&lt;p&gt;Skip over the &lt;code&gt;main&lt;/code&gt; method - the action happens in the &lt;code&gt;call&lt;/code&gt; method, which returns an &lt;code&gt;Integer&lt;/code&gt; used as the script's &lt;a href="https://www.shellscript.sh/exitcodes.html"&gt;exit code&lt;/a&gt;. An exit code of &lt;code&gt;0&lt;/code&gt; means "success" and any other number means "failure". This script will exit with &lt;code&gt;1&lt;/code&gt; for any kind of error. There are a few &lt;a href="https://tldp.org/LDP/abs/html/exitcodes.html"&gt;exit codes with special meanings&lt;/a&gt;, but none of those will apply to this script.&lt;/p&gt;

&lt;h3&gt;
  
  
  📩 Building the message text
&lt;/h3&gt;

&lt;p&gt;If the message is given at the end of the command then it will be in the &lt;code&gt;String[] message&lt;/code&gt;. If not, the array will be &lt;code&gt;null&lt;/code&gt; and we need to read from &lt;a href="https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)"&gt;Standard Input&lt;/a&gt; (stdin). Picocli doesn't have anything for reading from stdin but you can do it using a &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Scanner.html"&gt;&lt;code&gt;Scanner&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Remove the code from the &lt;code&gt;call()&lt;/code&gt; method and replace it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;wholeMessage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;wholeMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scanner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;useDelimiter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;wholeMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNext&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;wholeMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wholeMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;()){&lt;/span&gt;
  &lt;span class="n"&gt;printlnAnsi&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@|red You need to provide a message somehow|@"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java#L51-L67"&gt;this code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;If the message is non-null, join the parts together with spaces, otherwise use a &lt;code&gt;Scanner&lt;/code&gt; to read from stdin. Using a delimiter of &lt;code&gt;\\A&lt;/code&gt; with a &lt;code&gt;Scanner&lt;/code&gt; will read the whole input as a single token - known as the &lt;a href="https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks"&gt;Stupid Scanner Trick&lt;/a&gt; since at least 2004.&lt;/p&gt;

&lt;p&gt;Finally, if there isn't a message from either source, print an error and exit with a &lt;code&gt;1&lt;/code&gt;.  I added a &lt;code&gt;printlnAnsi&lt;/code&gt; method above &lt;code&gt;call()&lt;/code&gt; for including formatted output - it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printlnAnsi&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CommandLine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Help&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Ansi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AUTO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;string&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java#L44-L46"&gt;this code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;h3&gt;
  
  
  📲 Sending the SMS
&lt;/h3&gt;

&lt;p&gt;Below the &lt;code&gt;call()&lt;/code&gt; method, add this &lt;code&gt;sendSMS&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendSMS&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;wholeMessage&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nc"&gt;Twilio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_ACCOUNT_SID"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO\_AUTH\_TOKEN"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

  &lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;creator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;wholeMessage&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java#L82-L92"&gt;this code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;This is all that's needed to send an SMS with Twilio. For it to work we need to add a dependency on the Twilio Java Helper Library, so add this line to the top of the file, underneath the picocli dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;//DEPS com.twilio.sdk:twilio:7.54.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  🛠️ Joining it up
&lt;/h3&gt;

&lt;p&gt;The last thing to do is call &lt;code&gt;sendSMS&lt;/code&gt; from &lt;code&gt;call&lt;/code&gt;. Adding this code a the end of the &lt;code&gt;call&lt;/code&gt; method will do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending to ..."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;toPhoneNumber&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;": "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;sendSMS&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fromPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wholeMessage&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printlnAnsi&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@|green OK|@"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;printlnAnsi&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@|red FAILED|@"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printlnAnsi&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@|red "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"|@"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java#L68-L79"&gt;this code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;All being well, this will send the SMS. Any exception, such as bad credentials or using a non-existent phone number will put us in the &lt;code&gt;catch&lt;/code&gt; block where we print the error in red and exit with a &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's it! You can run &lt;a href="https://github.com/mjg123/SendSmsJbang/blob/master/SendSms.java"&gt;the final script&lt;/a&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./SendSms.java --to &amp;lt;YOUR CELL NUMBER&amp;gt; --from &amp;lt;YOUR TWILIO NUMBER&amp;gt; AHOY-HOY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;...and the message will arrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎁 Wrapping up
&lt;/h2&gt;

&lt;p&gt;We've seen that Java isn't just useful for big web applications - it works just fine for short-running CLI applications too, made easier with jbang and picocli.  This was just an example though - Twilio already has a very useful &lt;a href="https://www.twilio.com/docs/twilio-cli/quickstart"&gt;CLI&lt;/a&gt; already which can send SMS and do a lot more besides.&lt;/p&gt;

&lt;p&gt;Just for fun I did also create &lt;a href="https://twitter.com/MaximumGilliard/status/1287845230197211137"&gt;a version of the code that would fit in a tweet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'd love to hear about the fun (or serious) CLI tools you're building with Java, don't worry if they're more than 280 characters. Find me on Twitter or by email:&lt;/p&gt;

&lt;p&gt;🐦 &lt;a href="https://twitter.com/maximumgilliard?lang=el"&gt;@MaximumGilliard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📧 &lt;a href="//mailto:mgilliard@twilio.com"&gt;mgilliard@twilio.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can't wait to see what you build!&lt;/p&gt;

</description>
      <category>java</category>
      <category>cli</category>
    </item>
    <item>
      <title>5 ways to make HTTP requests in Java</title>
      <dc:creator>Matthew Gilliard</dc:creator>
      <pubDate>Thu, 23 Jul 2020 11:28:15 +0000</pubDate>
      <link>https://dev.to/twilio/5-ways-to-make-http-requests-in-java-2p3</link>
      <guid>https://dev.to/twilio/5-ways-to-make-http-requests-in-java-2p3</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftwilio-cms-prod.s3.amazonaws.com%2Fimages%2FRHWxEL1tiiEhgx6eT6X77zu1RolnTTDqv6IkMScTs35YZC.width-808.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftwilio-cms-prod.s3.amazonaws.com%2Fimages%2FRHWxEL1tiiEhgx6eT6X77zu1RolnTTDqv6IkMScTs35YZC.width-808.png" alt="5 ways to make HTTP requests in Java"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;[header image credit: Iron in the Butterfly Nebula, &lt;a href="https://apod.nasa.gov/apod/ap200721.html" rel="noopener noreferrer"&gt;NASA Astronomy Picture of the Day July 21 2020&lt;/a&gt; (modified)]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Making HTTP requests is a core feature of modern programming, and is often one of the first things you want to do when learning a new programming language. For Java programmers there are many ways to do it - core libraries in the JDK and third-party libraries. This post will introduce you to the Java HTTP clients that I reach for. If you use other ones, that’s great! Let me know about it. In this post I’ll cover:&lt;/p&gt;
&lt;h5&gt;
  
  
  Core Java:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;HttpURLConnection&lt;/li&gt;
&lt;li&gt;HttpClient&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Popular Libraries:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;ApacheHttpClient&lt;/li&gt;
&lt;li&gt;OkHttp&lt;/li&gt;
&lt;li&gt;Retrofit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll use the &lt;a href="https://apod.nasa.gov/apod/astropix.html" rel="noopener noreferrer"&gt;Astronomy Picture of the Day&lt;/a&gt; API from the &lt;a href="https://api.nasa.gov/" rel="noopener noreferrer"&gt;NASA APIs&lt;/a&gt; for the code samples, and the code is all &lt;a href="https://github.com/mjg123/java-http-clients" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt; in a project based on Java 11.&lt;/p&gt;
&lt;h2&gt;
  
  
  Core Java APIs for making Java http requests
&lt;/h2&gt;

&lt;p&gt;Since Java 1.1 there has been an HTTP client in the core libraries provided with the JDK. With Java 11 a new client was added. One of these might be a good choice if you are sensitive about adding extra dependencies to your project.&lt;/p&gt;
&lt;h3&gt;
  
  
  Java 1.1 HttpURLConnection
&lt;/h3&gt;

&lt;p&gt;First of all, do we capitalize acronyms in class names or not? Make your mind up. Anyway, close your eyes and center yourself in 1997. Titanic was rocking the box office and inspiring a thousand memes, Spice Girls had a best-selling album, but the biggest news of the year was surely &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpURLConnection.html" rel="noopener noreferrer"&gt;HttpURLConnection&lt;/a&gt; being added to Java 1.1.  Here’s how you would use it to make a &lt;code&gt;GET&lt;/code&gt; request to get the APOD data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a neat value object to hold the URL&lt;/span&gt;
&lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Open a connection(?) on the URL(??) and cast the response(???)&lt;/span&gt;
&lt;span class="nc"&gt;HttpURLConnection&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpURLConnection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Now it's "open", we can set the request method, headers etc.&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRequestProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accept"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This line makes the request&lt;/span&gt;
&lt;span class="nc"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Manually converting the response body InputStream to APOD using Jackson&lt;/span&gt;
&lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="no"&gt;APOD&lt;/span&gt; &lt;span class="n"&gt;apod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseStream&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Finally we have the response&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/JavaHttpURLConnectionDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;This seems quite verbose, and I find the order that we have to do things is confusing (why do we set headers &lt;em&gt;after&lt;/em&gt; opening the URL?). If you need to make more complex requests with &lt;code&gt;POST&lt;/code&gt; bodies, or custom timeouts etc then it’s all possible but I never found this API intuitive at all.&lt;/p&gt;

&lt;p&gt;When would you use &lt;code&gt;HTTPUrlConnection&lt;/code&gt;, then? If you are supporting clients who are using older versions of Java, &lt;strong&gt;and&lt;/strong&gt;  you can’t add a dependency then this might be for you. I suspect that’s only a small minority of developers, but you might see it in older codebases - for more modern approaches, read on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java 11 HttpClient
&lt;/h3&gt;

&lt;p&gt;More than twenty years after &lt;code&gt;HttpURLConnection&lt;/code&gt; we had Black Panther in the cinemas and a new HTTP client added to Java 11: &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html" rel="noopener noreferrer"&gt;&lt;code&gt;java.net.http.HttpClient&lt;/code&gt;&lt;/a&gt;. This has a much more logical API and can handle HTTP/2, and Websockets. It also has the option to make requests synchronously or asynchronously by using the &lt;code&gt;CompletableFuture&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;99 times out of 100 when I make an HTTP request I want to read the response body into my code. Libraries that make this difficult will not spark joy in me. HttpClient accepts a &lt;code&gt;BodyHandler&lt;/code&gt; which can convert an HTTP response into a class of your choosing. There are some built-in handlers: &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;byte[]&lt;/code&gt; for binary data, &lt;code&gt;Stream&amp;lt;String&amp;gt;&lt;/code&gt; which splits by lines, and a few others. You can also define your own, which might be helpful as there isn’t a built-in &lt;code&gt;BodyHandler&lt;/code&gt; for parsing JSON. I’ve written one (&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/JsonBodyHandler.java" rel="noopener noreferrer"&gt;here&lt;/a&gt;) based on &lt;a href="https://www.twilio.com/blog/java-json-with-jackson" rel="noopener noreferrer"&gt;Jackson&lt;/a&gt; following &lt;a href="https://docs.oracle.com/en/java/javase/13/docs/api/java.net.http/java/net/http/HttpResponse.BodySubscribers.html#mapping(java.net.http.HttpResponse.BodySubscriber,java.util.function.Function)" rel="noopener noreferrer"&gt;an example from Java Docs&lt;/a&gt;. It returns a &lt;code&gt;Supplier&lt;/code&gt; for &lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/APOD.java" rel="noopener noreferrer"&gt;the APOD class&lt;/a&gt;, so we call &lt;code&gt;.get()&lt;/code&gt; when we need the result.&lt;/p&gt;

&lt;p&gt;This is a synchronous request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// create a client&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newHttpClient&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// create a request&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpRequest&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accept"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// use the client to send the request&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonBodyHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// the response:&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an asynchronous request the &lt;code&gt;client&lt;/code&gt; and &lt;code&gt;request&lt;/code&gt; are made in the same way, then call &lt;code&gt;.sendAsync&lt;/code&gt; instead of &lt;code&gt;.send&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// use the client to send the request&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonBodyHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// We can do other things here while the request is in-flight&lt;/span&gt;

&lt;span class="c1"&gt;// This blocks until the request is complete&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;responseFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// the response:&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/JavaHttpClientDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;
  
  
  Third-party Java HTTP client libraries
&lt;/h2&gt;

&lt;p&gt;If the built-in clients don’t work for you, don’t worry! There are plenty of libraries you can bring into your project which will do the job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache HttpClient
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.apache.org/" rel="noopener noreferrer"&gt;Apache Software Foundation’s&lt;/a&gt; &lt;a href="https://hc.apache.org/httpcomponents-client-ga/" rel="noopener noreferrer"&gt;HTTP clients&lt;/a&gt; have been around for a long time. They’re widely-used and are the foundation for a lot of higher-level libraries. The history is a little confusing. The old &lt;a href="https://hc.apache.org/httpclient-3.x/" rel="noopener noreferrer"&gt;Commons HttpClient&lt;/a&gt; is no longer being developed, and the new version (&lt;em&gt;also&lt;/em&gt; called HttpClient), is under the &lt;a href="https://hc.apache.org/httpcomponents-client-5.0.x/index.html" rel="noopener noreferrer"&gt;HttpComponents&lt;/a&gt; project. Version 5.0 was released in early 2020, adding HTTP/2 support. The library also supports synchronous and asynchronous requests.&lt;/p&gt;

&lt;p&gt;Overall the API is rather low-level - you are left to implement a lot for yourself. The following code calls the NASA API. It doesn’t look too hard to use but I have skipped a lot of the error handling which you would want in production code and again I had to add &lt;a href="https://www.twilio.com/blog/java-json-with-jackson" rel="noopener noreferrer"&gt;Jackson&lt;/a&gt; code to parse the JSON response. You might also want to configure a logging framework to avoid warnings on stdout (no big deal, but it does irk me a bit). Anyway here’s the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CloseableHttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createDefault&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;HttpGet&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="no"&gt;APOD&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;httpResponse&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntity&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getContent&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/ApacheHttpClientDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Apache provides several more examples for &lt;a href="https://hc.apache.org/httpcomponents-client-5.0.x/examples.html" rel="noopener noreferrer"&gt;sync&lt;/a&gt; and &lt;a href="https://hc.apache.org/httpcomponents-client-5.0.x/examples-async.html" rel="noopener noreferrer"&gt;async&lt;/a&gt; requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  OkHttp
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://square.github.io/okhttp/" rel="noopener noreferrer"&gt;OkHttp&lt;/a&gt; is an HTTP client from &lt;a href="https://squareup.com/gb/en" rel="noopener noreferrer"&gt;Square&lt;/a&gt; with a lot of helpful built-in features, like automatic handling of GZIP, response caching and retries or fallback to other hosts in case of network errors as well as HTTP/2 and WebSocket support. The API is clean although there is no built-in parsing of JSON responses so again I added code to parse the JSON with Jackson:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;OkHttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OkHttpClient&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// defaults to GET&lt;/span&gt;

&lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newCall&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="no"&gt;APOD&lt;/span&gt; &lt;span class="n"&gt;apod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;byteStream&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/OkHttpDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;This is fine, but the real power of OkHttp is clear when you add Retrofit over the top.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrofit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://square.github.io/retrofit/" rel="noopener noreferrer"&gt;Retrofit&lt;/a&gt; is another library from Square, built on top of OkHttp. Along with all the low-level features of OkHttp it adds a way to build Java classes which abstract the HTTP details and present a nice Java-friendly API.&lt;/p&gt;

&lt;p&gt;First, we need to create an interface which declares the methods we want to call against the APOD API, with annotations defining how those correspond to HTTP requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;APODClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GET&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/planetary/apod"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Headers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accept: application/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getApod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api_key"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The return type of &lt;code&gt;CompletableFuture&amp;lt;APOD&amp;gt;&lt;/code&gt; makes this an asynchronous client. Square provide &lt;a href="https://github.com/square/retrofit/tree/master/retrofit-adapters" rel="noopener noreferrer"&gt;other adapters&lt;/a&gt; or you could write your own. Having an interface like this helps with mocking the client for tests, which I appreciate.&lt;/p&gt;

&lt;p&gt;After declaring the interface we ask Retrofit to create an implementation which we can use to make requests against a given base URL. It’s also helpful for integration testing to be able to switch the base URL. To generate the client, the code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Retrofit&lt;/span&gt; &lt;span class="n"&gt;retrofit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Retrofit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nasa.gov"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addConverterFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JacksonConverterFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;APODClient&lt;/span&gt; &lt;span class="n"&gt;apodClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retrofit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APODClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;APOD&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apodClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getApod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEMO_KEY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// do other stuff here while the request is in-flight&lt;/span&gt;

&lt;span class="no"&gt;APOD&lt;/span&gt; &lt;span class="n"&gt;apod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/RetrofitDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;h4&gt;
  
  
  API Authentication
&lt;/h4&gt;

&lt;p&gt;If there are multiple methods in our interface which all need an API key it is possible to configure that by adding an &lt;code&gt;HttpInterceptor&lt;/code&gt; to the base &lt;code&gt;OkHttpClient&lt;/code&gt;. The custom client can be added to the &lt;code&gt;Retrofit.Builder&lt;/code&gt;.  The code needed to create the custom client is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OkHttpClient&lt;/span&gt; &lt;span class="nf"&gt;clientWithApiKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OkHttpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addInterceptor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;originalRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="nc"&gt;HttpUrl&lt;/span&gt; &lt;span class="n"&gt;newUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;originalRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addQueryParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api_key"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;originalRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newUrl&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a href="https://github.com/mjg123/java-http-clients/blob/master/src/main/java/com/twilio/RetrofitCustomClientDemo.java" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;I like this kind of Java API for all but the simplest cases. Building classes to represent remote APIs is a nice abstraction that plays well with dependency injection, and having Retrofit create them for you based on a customizable OkHttp client is great.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other HTTP clients for Java
&lt;/h2&gt;

&lt;p&gt;Since posting this article &lt;a href="https://twitter.com/MaximumGilliard/status/1285933743518212096" rel="noopener noreferrer"&gt;on Twitter&lt;/a&gt; I have been delighted to see people discussing which HTTP clients they use. If none of the above is quite what you want, have a look at these suggestions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://rest-assured.io/" rel="noopener noreferrer"&gt;REST Assured&lt;/a&gt; - an HTTP client designed for testing your REST services. Offers a fluent interface for making requests and helpful methods for making assertions about responses.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://corese4rch.github.io/cvurl/" rel="noopener noreferrer"&gt;cvurl&lt;/a&gt; - a wrapper for the Java 11 HttpClient which rounds off some of the sharp edges you might encounter making complex requests.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/OpenFeign/feign" rel="noopener noreferrer"&gt;Feign&lt;/a&gt; - Similar to Retrofit, Feign can build classes from annotated interfaces. Feign is highly flexible with multiple options for making and reading requests, metrics, retries and more.&lt;/li&gt;
&lt;li&gt;Spring &lt;a href="https://spring.io/guides/gs/consuming-rest/" rel="noopener noreferrer"&gt;RestTemplate&lt;/a&gt; (synchronous) and &lt;a href="https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/html/boot-features-webclient.html" rel="noopener noreferrer"&gt;WebClient&lt;/a&gt; (asynchronous) clients - if you’ve used Spring for everything else in your project it could be a good idea to stick with that ecosystem. Baeldung has &lt;a href="https://www.baeldung.com/spring-webclient-resttemplate" rel="noopener noreferrer"&gt;an article comparing them&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;There are a lot of choices for HTTP clients in Java - for simple cases I would recommend the built-in &lt;code&gt;java.net.http.HttpClient&lt;/code&gt;. For more complex use-cases or if you want to have your HTTP APIs abstracted as Java classes as part of a larger application look at Retrofit or Feign.  Happy hacking, I can’t wait to see what you build!&lt;/p&gt;

&lt;p&gt;📧 &lt;a href="//mailto:mgilliard@twilio.com"&gt;mgilliard@twilio.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🐦 &lt;a href="https://twitter.com/maximumgilliard?lang=en" rel="noopener noreferrer"&gt;@MaximumGilliard&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>web</category>
      <category>http</category>
    </item>
    <item>
      <title>Using SDKMAN! to work with multiple versions of Java</title>
      <dc:creator>Matthew Gilliard</dc:creator>
      <pubDate>Fri, 06 Mar 2020 11:32:00 +0000</pubDate>
      <link>https://dev.to/twilio/using-sdkman-to-work-with-multiple-versions-of-java-54km</link>
      <guid>https://dev.to/twilio/using-sdkman-to-work-with-multiple-versions-of-java-54km</guid>
      <description>&lt;p&gt;If you code in Java, you might be coding against Java 11, or 8, or maybe an even older version. You may also be prototyping code against newer versions of Java, the current version is 13. Java 14 will be released this month, and 15 later this year. At the same time, you might be investigating different builds of OpenJDK - there are several free alternatives. I use &lt;a href="https://adoptopenjdk.net/"&gt;AdoptOpenJDK’s builds of OpenJDK&lt;/a&gt; which is an increasingly popular choice according to the &lt;a href="https://snyk.io/blog/36-of-developers-switched-from-oracle-jdk-to-an-alternate-openjdk-distribution-over-the-last-year/"&gt;JVM Ecosystem Report 2020&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You could also be trying out different build tools like &lt;a href="https://maven.apache.org/"&gt;Maven&lt;/a&gt; and &lt;a href="https://gradle.org/"&gt;Gradle&lt;/a&gt;. I use both, depending on the project.&lt;/p&gt;

&lt;p&gt;Put bluntly, managing all this can be difficult. It’s not impossible to manage by hand, but it’s fiddly and if you get it wrong the error messages can be hard to understand.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://sdkman.io/"&gt;SDKMAN!&lt;/a&gt; It’s a tool for managing the installation and selection of Software Development Kits - not just &lt;a href="https://sdkman.io/jdks"&gt;different versions and builds of Java&lt;/a&gt; itself, but tools for &lt;a href="https://sdkman.io/sdks"&gt;building, debugging, monitoring, documenting and deploying&lt;/a&gt; too. It is available for Windows, Linux and MacOS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IB0lBxNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/Selection_191.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IB0lBxNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/Selection_191.width-500.png" alt="SDKMAN! logo" width="448" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing SDKMAN!
&lt;/h2&gt;

&lt;p&gt;Follow the &lt;a href="https://sdkman.io/install"&gt;installation instructions&lt;/a&gt; for your platform. If you use the terminal a lot, I highly recommend checking out &lt;a href="https://ohmyz.sh/"&gt;Oh My Zsh&lt;/a&gt; which can add a ton of useful information and behaviour. There is an SDKMAN! plugin for Oh My Zsh which adds tab completion to the &lt;code&gt;sdk&lt;/code&gt; command which is really helpful. Enable this by finding the &lt;code&gt;plugins=&lt;/code&gt; line in the &lt;code&gt;.zshrc&lt;/code&gt; file in your home directory and adding &lt;code&gt;sdk&lt;/code&gt;. Mine reads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins=(git sdk)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do edit that file you’ll need to reload the Zsh config with &lt;code&gt;source ~/.zshrc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing a specific version of Java
&lt;/h2&gt;

&lt;p&gt;Let’s say we want to install the latest build of Java 11 from AdoptOpenJDK. First of all let's check that it’s available, using &lt;code&gt;sdk list java&lt;/code&gt;. If you’ve set up Oh My Zsh this is tab-completable:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bc9wZKjc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/original_images/1GDYeEXxYhWuPkNIFdTI7rw8AiSBCJwGFYuHN-3ghbGglpYiEROI0yqHlIIxx90QmMX-GMVf1w4R_h2OzfAy" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bc9wZKjc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/original_images/1GDYeEXxYhWuPkNIFdTI7rw8AiSBCJwGFYuHN-3ghbGglpYiEROI0yqHlIIxx90QmMX-GMVf1w4R_h2OzfAy" alt='Aminated gif showing a shell session where I run "sdk list java" and show that 11.0.6.hs-adpt is in the output, along with about 50 other possible choices.' width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the latest Java 11 OpenJDK build from AdoptOpenJDK has the identifier &lt;code&gt;11.0.6.hs-adpt&lt;/code&gt;. Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk install java 11.0.6.hs-adpt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SDKMAN! will download that version of Java, and unzip it into a directory on your computer. You don’t need to worry about exactly where, because SDKMAN! will also update environment variables so that you can use &lt;code&gt;java&lt;/code&gt; in the terminal immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.6+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.6+10, mixed mode)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Switching between Java versions
&lt;/h2&gt;

&lt;p&gt;I’ve also installed the latest early-access version of Java 14 (due to be released March 17th 2020) so that I can try out some of the new features. I did that with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk install java 14.ea.36-open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I said “no” when it asked if I wanted to use that as the default version. Later on, switch between them using &lt;code&gt;sdk use java &amp;lt;version&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bzw06y1Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/original_images/gvym4s1R1Xeh_HMuXB66ORa8ymgoPdFj-7I4QOVWaNxOigsmqMrOMBH78L3d3zLraYk80zptdqV3_Wkq3ccs" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bzw06y1Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/original_images/gvym4s1R1Xeh_HMuXB66ORa8ymgoPdFj-7I4QOVWaNxOigsmqMrOMBH78L3d3zLraYk80zptdqV3_Wkq3ccs" alt='Animated gif of a terminal session where I run "java -version" and it shows 11.0.6, then "sdk use java 14.ea.36-open" and "java -version" again. The version is now reported as "14"' width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think you would agree that this is a lot easier than managing downloads, installations and environment variables by hand.&lt;/p&gt;

&lt;p&gt;You can see what version you are using right now with &lt;code&gt;sdk current&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ sdk current Using:java: 14.ea.36-open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing other tools
&lt;/h2&gt;

&lt;p&gt;For different projects I use either &lt;a href="https://maven.apache.org/"&gt;Maven&lt;/a&gt; or &lt;a href="https://gradle.org/"&gt;Gradle&lt;/a&gt; as my build tool, and for debugging and profiling I sometimes use &lt;a href="https://visualvm.github.io/"&gt;VisualVM&lt;/a&gt;. Install the latest versions of these with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk install maven 3.6.3
sdk install gradle 6.2.2
sdk install visualvm 2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And they’re instantly available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using SDKMAN! with an IDE
&lt;/h2&gt;

&lt;p&gt;To select a particular version of Java for a project in IntelliJ IDEA or Eclipse, you will need to know exactly where SDKMAN! has unpacked your Java installations. This is &lt;code&gt;$HOME/.sdkman/candidates/java&lt;/code&gt;, with subdirectories named after the versions. The currently selected version of Java will also be available as &lt;code&gt;current&lt;/code&gt; in that directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ ls -l ~/.sdkman/candidates/java
total 8
drwxr-xr-x 10 mjg mjg 4096 Jan 15 12:14 11.0.6.hs-adpt
drwxrwxr-x 8 sdk mjg 4096 Mar 4 12:43 14.ea.36-open
lrwxrwxrwx 1 mjg mjg 52 Mar 4 12:35 current -&amp;gt; /home/mjg/.sdkman/candidates/java/14.ea.36-open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend keeping things clearer by configuring projects in your IDE to use a specific installation, rather than “current”.&lt;/p&gt;

&lt;p&gt;For IntelliJ IDEA this can be done from the “Project Structure” dialog. Either choose an existing version from the drop-down, or add a new Java version by selecting “New…” from the “Project SDK” section:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eHvSkjya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/G__Cbbdtuvl2ffqe_v08XegrD_w8vU-mi6MUT3qEvhzCbs.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eHvSkjya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/G__Cbbdtuvl2ffqe_v08XegrD_w8vU-mi6MUT3qEvhzCbs.width-500.png" alt='Screenshot of IntelliJ IDEA Project Structure dialog, highlighting the "New..." button for adding a new installation of Java for this project.' width="500" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Eclipse, this is done by heading to “Project Properties”, then “Java Build Path”, “Libraries” and selecting “Modulepath”:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yzxVQH7e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/pVRhbITDt9oomMb8ajqNo9CQeIYmPPCoqdd6YWa5Kcf-ff.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yzxVQH7e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/pVRhbITDt9oomMb8ajqNo9CQeIYmPPCoqdd6YWa5Kcf-ff.width-500.png" alt="Screenshot of an Eclipse Project configuration, highlighting the sections described in the text: Java Build Path, Libraries, and ModulePath" width="500" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should select the version that’s there already (11.0.6.hs-adpt in this example) and remove it, then select “Modulepath” again, “Add Library” and select “JRE System Library” from the dialog:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X8a09_Re--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/L1b2WCQdrOomPFfGzDzBfdPRqWoFy_Hr8EJzL8CRBstDsm.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X8a09_Re--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/L1b2WCQdrOomPFfGzDzBfdPRqWoFy_Hr8EJzL8CRBstDsm.width-500.png" alt='Another screenshot of Eclipse, this time the "Add Library" dialog, highlighting "JRE System Library"' width="500" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the “Add Library” dialog, select “Alternate JRE” and click “Installed JREs” to open another dialog which lets you choose an existing version, or add a new Java installation by browsing to where it is installed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2Y55gm__--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/ag2OSKIuKEqUP9SZIujceVClBPDxJ32AKpQJW00dkRg3PS.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2Y55gm__--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://twilio-cms-prod.s3.amazonaws.com/images/ag2OSKIuKEqUP9SZIujceVClBPDxJ32AKpQJW00dkRg3PS.width-500.png" alt='Another screenshot of Eclipse. This time it&amp;amp;#39;s the "Add Library" dialog with "Alternate JRE" and "Installed JREs" buttons highlighted.' width="500" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Happy Hacking!
&lt;/h2&gt;

&lt;p&gt;Using SDKMAN! can save you a lot of time and trouble if you work with multiple versions of Java and related tools. Maybe use that time to check out how to &lt;a href="https://www.twilio.com/blog/tag/java"&gt;build cool things with Java and Twilio&lt;/a&gt; like a &lt;a href="https://dev.to/twilio/using-whatsapp-twilio-and-azure-to-generate-photo-alt-text-in-java-1m97-temp-slug-4791396"&gt;WhatsApp bot which does image recognition&lt;/a&gt; or &lt;a href="https://dev.to/mjg123/wake-up-to-useful-daily-messages-with-java-and-azure-functions-4d0k-temp-slug-9592645"&gt;sending daily SMS reminders&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;I’d love to hear what you’re building, tell me about it on Twitter &lt;a href="https://twitter.com/MaximumGilliard"&gt;@MaximumGilliard&lt;/a&gt; or by email on &lt;a href="//mailto:mgilliard@twilio.com"&gt;mgilliard@twilio.com&lt;/a&gt;, or post it on Reddit to &lt;a href="https://reddit.com/r/twilio"&gt;/r/twilio&lt;/a&gt; for the whole world to see.&lt;/p&gt;

</description>
      <category>java</category>
      <category>installation</category>
      <category>tools</category>
    </item>
    <item>
      <title>Getting Started with the Java Streams API</title>
      <dc:creator>Matthew Gilliard</dc:creator>
      <pubDate>Tue, 02 Jul 2019 12:10:09 +0000</pubDate>
      <link>https://dev.to/twilio/getting-started-with-the-java-streams-api-k4n</link>
      <guid>https://dev.to/twilio/getting-started-with-the-java-streams-api-k4n</guid>
      <description>&lt;p&gt;The &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/stream/package-summary.html" rel="noopener noreferrer"&gt;Streams API&lt;/a&gt; was added in 2014 with the release of Java 8 so you’ve almost certainly got it available today. It is used to pass a series of objects through a chain of operations, so we can program in a more functional style than plain iteration allows. Still, when working with collections many developers still reach for the classic &lt;code&gt;for&lt;/code&gt; loop.&lt;/p&gt;

&lt;p&gt;In this post, I’ll introduce the terms used when talking about Streams, show some examples of each term and how they can be used together to create compact and descriptive code. Then I’ll show a real-world example of Streams code I wrote recently to pick winners in a raffle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a Stream?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Stream&lt;/strong&gt;  is a (possibly never-ending) series of Objects. A Stream starts from a &lt;strong&gt;Source&lt;/strong&gt;. The objects in a Stream flow through &lt;strong&gt;Intermediate Operations&lt;/strong&gt; , each of which results in another stream, and are gathered up at the end in a &lt;strong&gt;Terminal Operation&lt;/strong&gt;.  Streams are &lt;em&gt;lazy&lt;/em&gt;, which means the source and intermediate operations do nothing until objects are needed by the terminal operation.&lt;/p&gt;

&lt;p&gt;If we were making a fruit salad using the Streams API it might look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2Fk1NXVLA2JsVUdulilMQfMFpc_R2UanKDNYb7NpjR4vx3lS.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2Fk1NXVLA2JsVUdulilMQfMFpc_R2UanKDNYb7NpjR4vx3lS.width-500.png" alt="A Collection&amp;lt;Fruit&amp;gt; is streamed through Wash, Peel and Chop. Then the terminal operation "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Streams vs Collections
&lt;/h3&gt;

&lt;p&gt;At first look, Streams may appear similar to Collections - here's a few differences:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streams&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;may be infinite&lt;/li&gt;
&lt;li&gt;do not allow you to directly access individual items&lt;/li&gt;
&lt;li&gt;may include a way to create more elements on demand&lt;/li&gt;
&lt;li&gt;can only be read once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Collections&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;designed for holding a finite number of existing objects&lt;/li&gt;
&lt;li&gt;provide efficient ways to access individual items&lt;/li&gt;
&lt;li&gt;may be accessed as many times as you need to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ways of using Streams and Collections are quite different. As you will see below, it’s straightforward to create a Stream from a Collection and vice-versa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream Sources
&lt;/h2&gt;

&lt;p&gt;A Stream &lt;strong&gt;Source&lt;/strong&gt;  is something which creates a Stream, so what kinds of sources are there?&lt;/p&gt;

&lt;h3&gt;
  
  
  Collections
&lt;/h3&gt;

&lt;p&gt;A common source for a Stream is a &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html#stream()" rel="noopener noreferrer"&gt;Collection&lt;/a&gt;, like a &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html" rel="noopener noreferrer"&gt;List&lt;/a&gt; or a &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html" rel="noopener noreferrer"&gt;Set&lt;/a&gt; (you cannot stream a &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html" rel="noopener noreferrer"&gt;Map&lt;/a&gt; directly, but you can stream its &lt;code&gt;entrySet&lt;/code&gt;). Here’s a Stream from a List:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typesOfFruit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"clementine"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dragonfruit"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  I/O
&lt;/h3&gt;

&lt;p&gt;I/O (or Input/Output) concerns moving data in or out of your application, for example reading data over a network, or reading a file from disk. A Stream of lines can be made from a File like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lines&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-fruit-list.txt"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generators
&lt;/h3&gt;

&lt;p&gt;A Stream can be generated from scratch by providing the contents up-front using &lt;code&gt;Stream.of(...)&lt;/code&gt;, or providing a function which returns each object for the Stream with &lt;code&gt;generate&lt;/code&gt; or &lt;code&gt;iterate&lt;/code&gt;, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Random&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;randomNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;generate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;random:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Stream&lt;/code&gt; class also has &lt;code&gt;concat&lt;/code&gt; for combining multiple Streams into one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intermediate Stream Operations
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;Intermediate Operation&lt;/strong&gt;  is something which takes a Stream and transforms it into another Stream, possibly containing a different type of Object. Each element in the original Stream will be passed one at a time to the operation, and depending on how the operation works the resulting Stream may be the same length as the original, but could also be shorter or longer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Same length: returns a Stream of "APPLE", "BANANA", "CLEMENTINE", "DRAGONFRUIT"&lt;/span&gt;
&lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Shorter: this returns a Stream of "clementine", "dragonfruit"&lt;/span&gt;
&lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Longer: returns a Stream of "a", "p", "p", "l", "e", "b", "a" ...&lt;/span&gt;
&lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the way that &lt;code&gt;.flatMap(...)&lt;/code&gt; works is interesting. The lambda returns a &lt;code&gt;Stream&amp;lt;String&amp;gt;&lt;/code&gt;, so if this were a regular &lt;code&gt;.map(...)&lt;/code&gt; we would have a &lt;code&gt;Stream&amp;lt;Stream&amp;lt;String&amp;gt;&amp;gt;&lt;/code&gt;. What &lt;code&gt;flatMap&lt;/code&gt; does is join the inner Streams together to make a &lt;code&gt;Stream&amp;lt;String&amp;gt;&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;Remember that you can only traverse a Stream once, so you won’t be able to do all three of those operations on the same &lt;code&gt;typesOfFruit&lt;/code&gt; Stream. If you try it you will see &lt;code&gt;java.lang.IllegalStateException: stream has already been operated upon or closed&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaining Intermediate Operations
&lt;/h3&gt;

&lt;p&gt;The superpower of the Streams API, is that &lt;strong&gt;Intermediate Operations work on a Stream&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;return another Stream, so they can be chained together&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These operations return a Stream of all the letters in the fruit names which &lt;/span&gt;
&lt;span class="c1"&gt;// are after "G" in the alphabet, uppercased: "P", "P", "L", "N" ...&lt;/span&gt;
&lt;span class="n"&gt;typesOfFruit&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"G"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you try writing that without using Streams it will take far more code. You’ll have to create a lot of variables to hold intermediate values and the result will be far less compact and easy to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terminal Stream Operations
&lt;/h2&gt;

&lt;p&gt;Remember that Streams are &lt;strong&gt;lazy&lt;/strong&gt; , which means that Sources and Intermediate Operations don’t do any work until they need to. It’s the &lt;strong&gt;Terminal Operations&lt;/strong&gt;  that create that need.&lt;/p&gt;

&lt;p&gt;Another way to say that is that Terminal Operations turn a Stream back into &lt;em&gt;something else&lt;/em&gt;. Until you need that &lt;em&gt;something else&lt;/em&gt; the Stream just sits there, chilling.&lt;/p&gt;

&lt;p&gt;There are lots of possible Terminal Operations including &lt;code&gt;Collectors&lt;/code&gt; for gathering the Stream back into a Collection like a List or a Map, &lt;code&gt;.foreach(...)&lt;/code&gt; to run some operation on each item and methods like &lt;code&gt;.count()&lt;/code&gt; and &lt;code&gt;.reduce(...)&lt;/code&gt; to compute some value from the Stream. Here’s a few examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Collecting the Stream elements into a List&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fruitCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Doing something with each element of the Stream&lt;/span&gt;
&lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// How many elements are in the Stream?&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;fruitCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;typesOfFruit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Real-World Example of Streams
&lt;/h2&gt;

&lt;p&gt;By now you’ve probably thought of lots of ways you could use Streams in your own code, but I’d like to end with an example where I used Streams to pick winners for a raffle we decided to run on the Twilio booth at &lt;a href="https://www.jbcnconf.com/2019/" rel="noopener noreferrer"&gt;JBcnConf&lt;/a&gt;. Folks could enter by sending an SMS to &lt;a href="https://www.twilio.com/phone-numbers" rel="noopener noreferrer"&gt;a phone number I manage with Twilio&lt;/a&gt; and we needed to pick three people to win space-themed Lego. The Streams API made this code pretty nice to write.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2FsbSgAq_CfGE-4Nv5frdUJqAYxm55py1zHLYSQRp0mN50hd.width-500.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2FsbSgAq_CfGE-4Nv5frdUJqAYxm55py1zHLYSQRp0mN50hd.width-500.jpg" alt="Three Space Legos as prizes for a raffle, which could be entered by SMS."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch all the messages we received, using the &lt;a href="https://www.twilio.com/docs/libraries/java" rel="noopener noreferrer"&gt;Twilio Java helper library&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Remove entries which arrived too early or too late&lt;/li&gt;
&lt;li&gt;Grab the number each message was sent from&lt;/li&gt;
&lt;li&gt;Remove duplicates so that each person has an equal chance of winning&lt;/li&gt;
&lt;li&gt;Randomly shuffle the numbers&lt;/li&gt;
&lt;li&gt;Take only as many numbers as we had prizes to give&lt;/li&gt;
&lt;li&gt;Send an SMS to each winner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This looks like a case for the Streams API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2FF2MVg-vmuTOldxMip8xQ2yfIJXAI45AMkoQMygLULd1WaG.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fcom.twilio.prod.twilio-docs%2Fimages%2FF2MVg-vmuTOldxMip8xQ2yfIJXAI45AMkoQMygLULd1WaG.width-500.png" alt="Flowchart: A ResourceSet&amp;lt;Message&amp;gt; is streamed through operations which result in 3 winners being sent an SMS."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the code (it’s also &lt;a href="https://gist.github.com/mjg123/438436cea8f9f05678b93550c06fbf2e" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;First, fetch all the SMSs sent to the &lt;code&gt;CONTEST NUMBER&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Twilio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ACCOUNT_SID"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AUTH_TOKEN"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;ResourceSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;CONTEST_NUMBER&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ResourceSet&lt;/code&gt; is an &lt;code&gt;Iterable&lt;/code&gt; so we can use it as a &lt;strong&gt;Source&lt;/strong&gt; via the &lt;code&gt;StreamSupport&lt;/code&gt; class in &lt;code&gt;java.util.stream&lt;/code&gt;. I thought &lt;code&gt;Iterable&lt;/code&gt; might have its own &lt;code&gt;.stream()&lt;/code&gt; method but &lt;a href="https://stackoverflow.com/questions/23114015/why-does-iterablet-not-provide-stream-and-parallelstream-methods" rel="noopener noreferrer"&gt;it doesn’t&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;StreamSupport&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spliterator&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for the &lt;strong&gt;Intermediate Operations&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDateSent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isAfter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DRAW_START&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDateSent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isBefore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DRAW_END&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Message:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getFrom&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns a PhoneNumber&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;distinct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collectingAndThen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;();}))&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NUMBER_OF_WINNERS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trickiest operation is the shuffle (lines 5-7). Although Streams have &lt;code&gt;.sorted()&lt;/code&gt;, they don’t have a &lt;code&gt;.shuffled()&lt;/code&gt; so I used a &lt;code&gt;.collect(...)&lt;/code&gt; as an Intermediate Operation by collecting into a List, shuffling it and returning a Stream of that List.&lt;/p&gt;

&lt;p&gt;At this point we have a &lt;code&gt;Stream&amp;lt;PhoneNumber&amp;gt;&lt;/code&gt; with the right number of items in it. Finally, the &lt;strong&gt;Terminal Operation&lt;/strong&gt;  takes each phone number and &lt;a href="https://www.twilio.com/docs/sms/quickstart/java" rel="noopener noreferrer"&gt;uses the Twilio API&lt;/a&gt; to send a message someone will be happy to receive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;creator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CONTEST_NUMBER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CONGRATULATIONS_YOU_WON_MESSAGE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
           &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is &lt;a href="https://gist.github.com/mjg123/438436cea8f9f05678b93550c06fbf2e" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt; including the Maven config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The Streams API can help you write shorter and more direct code for dealing with bulk operations on Collections and more. In this post I’ve shown some of the basics - there’s more to Streams, such as &lt;a href="https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#executing_streams_in_parallel" rel="noopener noreferrer"&gt;Parallel Streams&lt;/a&gt;, &lt;a href="https://www.baeldung.com/java-8-primitive-streams" rel="noopener noreferrer"&gt;Primitive Streams&lt;/a&gt; (Streams of &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt; or &lt;code&gt;long&lt;/code&gt;) which can help with performance.&lt;/p&gt;

&lt;p&gt;If you find some code which could be improved with Streams your IDE &lt;a href="https://blog.jetbrains.com/idea/2016/12/intellij-idea-inspection-settings-for-refactoring-to-java-8/" rel="noopener noreferrer"&gt;might even suggest refactorings&lt;/a&gt; for you, and I’d love to hear how you get on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/maximumgilliard?lang=en" rel="noopener noreferrer"&gt;@MaximumGilliard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:mgilliard@twilio.com"&gt;mgilliard@twilio.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>streams</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to read and understand a Java Stacktrace</title>
      <dc:creator>Matthew Gilliard</dc:creator>
      <pubDate>Mon, 03 Jun 2019 12:42:46 +0000</pubDate>
      <link>https://dev.to/twilio/how-to-read-and-understand-a-java-stacktrace-3796</link>
      <guid>https://dev.to/twilio/how-to-read-and-understand-a-java-stacktrace-3796</guid>
      <description>&lt;p&gt;When things go wrong in a running Java application, often the first sign you will have is lines printed to the screen that look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
  at com.myproject.module.MyProject.badMethod(MyProject.java:22)
  at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
  at com.myproject.module.MyProject.someMethod(MyProject.java:10)
  at com.myproject.module.MyProject.main(MyProject.java:6)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;Stacktrace&lt;/strong&gt; , and in this post I'll explain what they are, how they are made and how to read and understand them. If that looks painful to you then read on...&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of a Stacktrace
&lt;/h2&gt;

&lt;p&gt;Usually a Stacktrace is shown when an &lt;a href="https://www.baeldung.com/java-exceptions" rel="noopener noreferrer"&gt;Exception&lt;/a&gt; is not handled correctly in code. This may be one of the &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Exception.html" rel="noopener noreferrer"&gt;built-in Exception types&lt;/a&gt;, or a &lt;a href="https://www.baeldung.com/java-new-custom-exception" rel="noopener noreferrer"&gt;custom Exception&lt;/a&gt; created by a program or a library.&lt;/p&gt;

&lt;p&gt;The Stacktrace contains the  &lt;strong&gt;Exception’s type&lt;/strong&gt;  and a &lt;strong&gt;message&lt;/strong&gt; , and a list of &lt;strong&gt;all the method calls&lt;/strong&gt;  which were in progress when it was thrown.&lt;/p&gt;

&lt;p&gt;Let’s dissect that Stacktrace. The first line tells us the details of the Exception:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1c4xu5lz6ta81w6sark4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1c4xu5lz6ta81w6sark4.png" width="500" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a good start. Line 2 shows what code was running when that happened:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lmnwjwgdxywofd3ntah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lmnwjwgdxywofd3ntah.png" width="500" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That helps us narrow down the problem, but what part of the code called &lt;code&gt;badMethod&lt;/code&gt;? The answer is on the next line down, which can be read in the exact same way. And how did we get there? Look on the next line. And so on, until you get to the last line, which is the &lt;code&gt;main&lt;/code&gt; method of the application.  Reading the Stacktrace from bottom to top you can trace the exact path from the beginning of your code, right to the Exception.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went wrong?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mqxvkf01xxvh2adf51k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mqxvkf01xxvh2adf51k.jpg" width="500" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing that causes an Exception is usually an explicit &lt;code&gt;throw&lt;/code&gt; statement. Using the file name and line number you can check exactly what code threw the Exception. It will probably look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  throw new RuntimeException("Something has gone wrong, aborting!");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a great place to start looking for the underlying problem: are there any if statements around that? What does that code do? Where does the data used in that method come from?&lt;/p&gt;

&lt;p&gt;It is also possible for code to throw an Exception without an explicit &lt;code&gt;throw&lt;/code&gt; statement, for example you can get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NullPointerException if &lt;code&gt;obj&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; in code which calls &lt;code&gt;obj.someMethod()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ArithmeticException if a division by zero happens in integer arithmetic, ie &lt;code&gt;1/0&lt;/code&gt;  - curiously there is no Exception if this is a floating-point calculation though, &lt;code&gt;1.0/0.0&lt;/code&gt; returns &lt;code&gt;infinity&lt;/code&gt; &lt;em&gt;just fine!&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;NullPointerException if a &lt;code&gt;null&lt;/code&gt; Integer is unboxed to an &lt;code&gt;int&lt;/code&gt; in code like this: &lt;code&gt;Integer a=null; a++;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;There are some other examples in the &lt;a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.6" rel="noopener noreferrer"&gt;Java Language Specification&lt;/a&gt;, so it’s important to be aware that Exceptions &lt;em&gt;can&lt;/em&gt; arise without being explicitly thrown.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dealing with Exceptions Thrown by Libraries
&lt;/h2&gt;

&lt;p&gt;One of the great strengths of Java is the huge number of libraries available. Any popular library will be well tested so generally when faced with an Exception from a library, it’s best to check first whether the error is caused by how our code uses it.&lt;/p&gt;

&lt;p&gt;For example, if we're using the &lt;a href="https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/math/Fraction.html" rel="noopener noreferrer"&gt;Fraction&lt;/a&gt; class from &lt;a href="https://commons.apache.org/proper/commons-lang/" rel="noopener noreferrer"&gt;Apache Commons Lang&lt;/a&gt; and pass it some input like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Fraction.getFraction(numberOfFoos, numberOfBars);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;numberOfBars&lt;/code&gt; is zero, then the Stacktrace will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.lang.ArithmeticException: The denominator must not be zero
  at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)   
  at com.project.module.MyProject.anotherMethod(MyProject.java:17)
  at com.project.module.MyProject.someMethod(MyProject.java:13)
  at com.project.module.MyProject.main(MyProject.java:9)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many good libraries provide &lt;a href="https://en.wikipedia.org/wiki/Javadoc#Structure_of_a_Javadoc_comment" rel="noopener noreferrer"&gt;Javadoc&lt;/a&gt; which includes information about what kinds of Exceptions may be thrown and why. In this case &lt;code&gt;Fraction.getFraction&lt;/code&gt; has documented &lt;a href="https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/math/Fraction.html#getFraction(int,%20int)" rel="noopener noreferrer"&gt;will throw an ArithmeticException if a Fraction has a zero denominator&lt;/a&gt;. Here it's also clear from the message, but in more complicated or ambiguous situations the docs can be a great help.&lt;/p&gt;

&lt;p&gt;To read this Stacktrace, start at the top with the Exception's type - &lt;code&gt;ArithmeticException&lt;/code&gt; and message &lt;code&gt;The denominator must not be zero&lt;/code&gt;. This gives an idea of what went wrong, but to discover what code caused the Exception, skip down the Stacktrace looking for something in the package &lt;code&gt;com.myproject&lt;/code&gt; (it’s on the 3rd line here), then scan to the end of the line to see where the code is (&lt;code&gt;MyProject.java:17&lt;/code&gt;). That line will contain some code that calls &lt;code&gt;Fraction.getFraction&lt;/code&gt;. This is the starting point for investigation: What is passed to &lt;code&gt;getFraction&lt;/code&gt;? Where did it come from?&lt;/p&gt;

&lt;p&gt;In big projects with many libraries, Stacktraces can be hundreds of lines long so if you see a big Stacktrace, practise scanning the list of &lt;code&gt;at ... at ... at ...&lt;/code&gt; looking for your own code - it’s a useful skill to develop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practice: Catching and Rethrowing Exceptions
&lt;/h2&gt;

&lt;p&gt;Let's say we are working on a big project that deals with fictional &lt;code&gt;FooBars&lt;/code&gt;, and our code is going to be used by others. We might decide to catch the ArithmeticException from &lt;code&gt;Fraction&lt;/code&gt; and re-throw it as something project-specific, which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  try {
    ....
    Fraction.getFraction(x,y);
    ....
  } catch ( ArithmeticException e ){ 
    throw new MyProjectFooBarException("The number of FooBars cannot be zero", e);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Catching the &lt;code&gt;ArithmeticException&lt;/code&gt; and rethrowing it has a few benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our users are shielded from having to care about the &lt;code&gt;ArithmeticException&lt;/code&gt; - giving us flexibility to change how commons-lang is used.&lt;/li&gt;
&lt;li&gt;More context can be added, eg stating that it’s &lt;em&gt;the number of FooBars&lt;/em&gt; that is causing the problem.&lt;/li&gt;
&lt;li&gt;It can make Stacktraces easier to read, too, as we’ll see below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It isn't necessary to catch-and-rethrow on &lt;em&gt;every&lt;/em&gt; Exception, but where there seems to be a jump in the layers of your code, like calling into a library, it often makes sense.&lt;/p&gt;

&lt;p&gt;Notice that the constructor for &lt;code&gt;MyProjectFooBarException&lt;/code&gt; takes 2 arguments: a message and the Exception which caused it. Every Exception in Java has a &lt;code&gt;cause&lt;/code&gt; field, and when doing a &lt;em&gt;catch-and-rethrow&lt;/em&gt; like this then you should &lt;em&gt;always&lt;/em&gt; set that to help people debug errors. A Stacktrace might now look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" com.myproject.module.MyProjectFooBarException: The number of FooBars cannot be zero
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:19)
  at com.myproject.module.MyProject.someMethod(MyProject.java:12)
  at com.myproject.module.MyProject.main(MyProject.java:8)
Caused by: java.lang.ArithmeticException: The denominator must not be zero
  at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:17)
  ... 2 more
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most recently thrown Exception is on the first line, and the location where it was thrown is still on line 2. However, this type of Stacktrace can cause confusion because the &lt;em&gt;catch-and-rethrow&lt;/em&gt; has changed the order of method calls compared to the Stacktraces we saw before. The main method is no longer at the bottom, and the code which &lt;em&gt;first&lt;/em&gt; threw an Exception is no longer at the top. When you have multiple stages of catch-and-rethrow then it gets bigger but the pattern is the same:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Check the sections from first to last looking for your code, then read relevant sections from bottom to top.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries vs Frameworks
&lt;/h2&gt;

&lt;p&gt;The difference between a Library and a Framework in Java is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your code &lt;em&gt;calls&lt;/em&gt; methods in a Library&lt;/li&gt;
&lt;li&gt;Your code &lt;em&gt;is called by&lt;/em&gt; methods in a Framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common type of Framework is a web application server, like &lt;a href="http://sparkjava.com/" rel="noopener noreferrer"&gt;SparkJava&lt;/a&gt; or &lt;a href="https://spring.io/guides/gs/spring-boot/" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt;. Using SparkJava and &lt;a href="https://commons.apache.org/proper/commons-lang/" rel="noopener noreferrer"&gt;Commons-Lang&lt;/a&gt; with our code we might see a Stacktrace like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.framework.FrameworkException: Error in web request
    at com.framework.ApplicationStarter.lambda$start$0(ApplicationStarter.java:15)
    at spark.RouteImpl$1.handle(RouteImpl.java:72)
    at spark.http.matching.Routes.execute(Routes.java:61)
    at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:134)
    at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1568)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:503)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.project.module.MyProjectFooBarException: The number of FooBars cannot be zero
    at com.project.module.MyProject.anotherMethod(MyProject.java:20)
    at com.project.module.MyProject.someMethod(MyProject.java:12)
    at com.framework.ApplicationStarter.lambda$start$0(ApplicationStarter.java:13)
    ... 16 more
Caused by: java.lang.ArithmeticException: The denominator must not be zero
    at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)
    at com.project.module.MyProject.anotherMethod(MyProject.java:18)
    ... 18 more
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK that is getting quite long now. As before we should suspect our own code first, but it's getting harder and harder to find &lt;em&gt;where that is&lt;/em&gt;. At the top there is the Framework's Exception, at the bottom the Library's and right in the middle is our own code. Phew!&lt;/p&gt;

&lt;p&gt;A complex Framework and Library can create a dozen or more &lt;code&gt;Caused by:&lt;/code&gt; sections, so a good strategy is to jump down those looking for your own code: &lt;code&gt;Caused by: com.myproject...&lt;/code&gt; Then read that section in detail to isolate the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;Learning how to understand Stacktraces and read them quickly will let you home in on problems and makes debugging much less painful. It's a skill which improves with practise, so next time you see a big Stacktrace don't be intimidated - there is a lot of useful information there if you know how to extract it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UpmcL_Uq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/EoZw5ArTbpyelA35Ks8FjjsrJCRq3tIDTNNjszf3qXJoCWIW63b0ePJMSNAXFlwfafRE2kFyKkL4Gy" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UpmcL_Uq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/EoZw5ArTbpyelA35Ks8FjjsrJCRq3tIDTNNjszf3qXJoCWIW63b0ePJMSNAXFlwfafRE2kFyKkL4Gy" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any tips or tricks about dealing with Java Stacktraces I'd love to hear about them so get in touch with me and let's share what we know.&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:mgilliard@twilio.com"&gt;mgilliard@twilio.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/maximumgilliard" rel="noopener noreferrer"&gt;@MaximumGilliard&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>errors</category>
    </item>
  </channel>
</rss>
