<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>JBake</title>
    <link>http://adamldavis.com</link>
    <atom:link href="http://adamldavis.com/feed.xml" rel="self" type="application/rss+xml" />
    <description>JBake Bootstrap Template</description>
    <language>en-gb</language>
    <pubDate>Sun, 1 Nov 2020 21:14:42 -0500</pubDate>
    <lastBuildDate>Sun, 1 Nov 2020 21:14:42 -0500</lastBuildDate>

    <item>
      <title>Project Reactor (Part 3 of 3)</title>
      <link>http://adamldavis.com/blog/2020/04.html</link>
      <pubDate>Sun, 1 Nov 2020 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2020/04.html</guid>
      	<description>
	&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_so_far&quot;&gt;So far&amp;#8230;&amp;#8203;&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the &lt;a href=&quot;https://www.adamldavis.com/blog/2020/03.html&quot;&gt;previous&lt;/a&gt; post we introduced Reactor testing and backpressure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To summarize all three parts:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.adamldavis.com/blog/2020/02.html&quot;&gt;Part 1&lt;/a&gt;: Getting started with Reactor: Flux, Mono, zipping, Tuples, and retry&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.adamldavis.com/blog/2020/03.html&quot;&gt;Part 2&lt;/a&gt;: Backpressure and testing with Reactor&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Part 3: Spring WebFlux, Netty, and WebClient with a dip into JHipster&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For this post you should have a good understanding of
&lt;a href=&quot;https://leanpub.com/modernjavasecondedition/&quot;&gt;Java&lt;/a&gt;
and &lt;a href=&quot;https://spring.io/projects/spring-boot&quot;&gt;Spring Boot&lt;/a&gt;
and have read the previous posts about Reactor.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_jhipster&quot;&gt;JHipster&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jhipster.tech&quot;&gt;JHipster&lt;/a&gt; is a code generation tool primarily for building Spring-Boot based projects
with either a React or Angular front end - although it can be extended via blueprints and
there are several (one allows you to create a Vue.js front-end
and one a Micronaut back-end for example).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It also has a feature allowing you to create a Spring Boot WebFlux project.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;WebFlux is Spring&amp;#8217;s framework for asynchronous, non-blocking web applications - and it works with
Reactive types, especially project Reactor (Flux, Mono, etc.).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To get started, install &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node&lt;/a&gt; (&amp;gt;10.20.1) and &lt;a href=&quot;https://www.jhipster.tech/installation/&quot;&gt;JHipster&lt;/a&gt; (latest)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Then, from the terminal, make a new directory (named &quot;hip-webflux&quot;), and run &lt;code&gt;jhipster&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow the prompts, and choose monolith and then &lt;em&gt;Reactive&lt;/em&gt; (this will create a Spring Boot WebFlux project)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For database, you can pick MongoDB, or Cassandra (the reactive generator doesn&amp;#8217;t support SQL at the moment)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For front end, you can pick React or Angular&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pick Maven or Gradle&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&amp;#8230;&amp;#8203;This takes a while since it has to load a bunch of dependencies&amp;#8230;&amp;#8203;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Then you should see output like the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;Server application generated successfully.

Run your Spring Boot application:
./mvnw

Client application generated successfully.

Start your Webpack development server with:
 npm start


&amp;gt; hip@0.0.1-SNAPSHOT cleanup /home/adavis/github/adamldavis/hip-webflux
&amp;gt; rimraf target/classes/static/

INFO! Congratulations, JHipster execution is complete!&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_jdl&quot;&gt;JDL&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;After creating the basic project, let&amp;#8217;s add some entities.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One of the cool things about JHipster is JDL (Jhipster Domain Language).
Its a DSL for creating projects and entities.
Create a file named &quot;hip.jdl&quot; and put in the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;entity Person {
  name String required
  age Integer min(0) max(142)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;(Feel free to mess around with your JDL and make it more complicated, but for this example, let&amp;#8217;s keep it simple)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Import the JDL by running &lt;code&gt;jhipster import-jdl hip.jdl&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now open the project with your favorite IDE (like IntelliJ IDEA for example) and take
a look at the PersonController.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;JHipster automatically creates an AuditEvent database for auditing (create, update, delete record events).
Open up the file named &quot;AuditResource&quot; under the &quot;com.mycompany.myapp.web.rest&quot; package (Under src/main/java/).
It should have a &quot;getAll&quot; method that looks something like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;@GetMapping
public Mono&amp;lt;ResponseEntity&amp;lt;Flux&amp;lt;AuditEvent&amp;gt;&amp;gt;&amp;gt; getAll(ServerHttpRequest request, Pageable pageable) {
    return auditEventService.count()
        .map(total -&amp;gt; new PageImpl&amp;lt;&amp;gt;(new ArrayList&amp;lt;&amp;gt;(), pageable, total))
        .map(page -&amp;gt; PaginationUtil.generatePaginationHttpHeaders(UriComponentsBuilder.fromHttpRequest(request), page))
        .map(headers -&amp;gt; ResponseEntity.ok().headers(headers).body(auditEventService.findAll(pageable)));
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;WebFlux allows you to return Reactor types like Mono and Flux from controller methods
and implements a reactive, asynchronous web server using &lt;a href=&quot;https://netty.io/&quot;&gt;Netty&lt;/a&gt; by default.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A typical web server uses a large number of Threads and handles each request in one thread.
The problem with this is Threads in Java are kind of heavyweight
(this should be fixed by project
&lt;a href=&quot;https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html&quot;&gt;Loom&lt;/a&gt; and virtual threads in Java 15+).
This allows a single Thread to block without holding back the entire application;
however, the number of concurrent requests you can handle is limited by the number of threads
your server can support.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Netty instead uses an &lt;a href=&quot;http://normanmaurer.me/presentations/2014-netflix-netty/slides.html#11.0&quot;&gt;EventLoop&lt;/a&gt;
per Thread for I/O.
WebFlux enables and simplifies the Java API using Reactive Streams (of which Reactor is one implementation).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_no_blocking&quot;&gt;No Blocking!&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Since the threads in WebFlux are meant to be non-blocking, you must be careful not to block them.
For example, don&amp;#8217;t call &lt;code&gt;block()&lt;/code&gt; or &lt;code&gt;Thread.sleep&lt;/code&gt;.
There&amp;#8217;s a project called &lt;a href=&quot;https://github.com/reactor/BlockHound&quot;&gt;BlockHound&lt;/a&gt; to help enforce this
rule throughout your application.
(This doesn&amp;#8217;t mean &lt;em&gt;no&lt;/em&gt; threads can block; only blocking should happen in dedicated threads)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To implement this, your application should be reactive &quot;all the way down&quot;.
So if you have a database, reading from it should also be reactive and non-blocking.
Projects like &lt;a href=&quot;https://r2dbc.io/&quot;&gt;r2dbc&lt;/a&gt; and Spring &lt;a href=&quot;https://spring.io/projects/spring-data-r2dbc&quot;&gt;spring-data-r2dbc&lt;/a&gt;
help, among others.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_webclient&quot;&gt;WebClient&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;WebFlux also includes
&lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.html&quot;&gt;WebClient&lt;/a&gt;
which is a reactive replacement for RestTemplate.
It makes asynchronous, non-blocking HTTP requests.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can create an instance of WebClient using the builder pattern starting from the static WebClient.builder() method.
For example:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
// later on...
WebClient myWebClient = WebClient.builder()
 .baseUrl(&quot;http://localhost:8080/api-to-call/&quot;)
 .defaultCookie(&quot;cookieKey&quot;, &quot;cookieValue&quot;)
 .defaultHeader(HttpHeaders.CONTENT_TYPE,
   MediaType.APPLICATION_JSON_VALUE)
 .build();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This builds a WebClient with given baseUrl.
It also provides a cookie and header to use for every request.
There are many more methods to configure the WebClient.
Each request starts with defining the HTTP method,
then you can specify an additional URL path (with or without path variables) and call
exchange which returns a Mono&amp;lt;ClientResponse&amp;gt;.
For example, to get a person from some &lt;code&gt;/v1/persons&lt;/code&gt; REST api:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;// get the Course with ID=1 and print it out:
myWebClient.get()
    .uri(&quot;/v1/persons/{id}&quot;, 1L)
    .exchange()
    .flatMap((ClientResponse response) -&amp;gt;
      response.bodyToMono(Person.class))
    .subscribe(person -&amp;gt; System.out.println(&quot;person = &quot; + person));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The WebClient thus enables all of your HTTP calls to be reactive.
The Spring team likes WebClient so much, they recommend everyone uses it over RestTemplate.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_schedulers&quot;&gt;Schedulers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One important type in Reactor is &lt;a href=&quot;https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Schedulers.html&quot;&gt;Schedulers&lt;/a&gt;.
Schedulers provides various Scheduler flavors usable by publishOn or subscribeOn
for a Flux or Mono. For example:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;mono.publishOn(Schedulers.elastic())&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Makes a Mono suitable for running blocking tasks like HTTP calls.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I hope you got something from this three part series.
There&amp;#8217;s much much more to learn about Reactor, but I hope this is a good introduction.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Reactive programming in Java isn&amp;#8217;t always necessary - it&amp;#8217;s for enabling thousands of
transactions a second, so you might not need it - but when any
application becomes popular enough, you tend to need high throughput and performance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Eventually when Java has virtual threads it will make threads more lightweight, however,
Reactive will still be useful due to its backpressure handling, retry logic,
and other benefits.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.adamldavis.com/blog/2020/02.html&quot;&gt;Part 1&lt;/a&gt;: Getting started with Reactor, Flux, Mono, zipping, Tuples, and retry&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.adamldavis.com/blog/2020/03.html&quot;&gt;Part 2&lt;/a&gt;: Backpressure and testing with Reactor&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.adamldavis.com/blog/2020/04.html&quot;&gt;Part 3&lt;/a&gt;: Spring WebFlux, Netty, and WebClient (and JHipster)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Project Reactor (Part 2)</title>
      <link>http://adamldavis.com/blog/2020/03.html</link>
      <pubDate>Wed, 29 Jul 2020 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2020/03.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the &lt;a href=&quot;https://www.adamldavis.com/blog/2020/02.html&quot;&gt;previous&lt;/a&gt; post we introduced Reactor and covered why reactor is important and some of the basics.
We talked about Flux, Mono, zipping, Tuples, and retry.
However, one of the most important aspects of reactive streams, is the ability to handle backpressure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Backpressure&lt;/em&gt; is a mechanism for explicitly handling the problem of having too many items to process in real time.
Without such a mechanism, you typically see the problem of services timing out and eventually
the user sees either a very slow or unresponsive system.
This is compounded by the fact that users will give up quickly if a system is slow to respond.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Many other techniques for handling concurrency do not have explicit mechanisms for handling backpressure.
Instead, system engineers and architects must hope to scale the system either horizontally
(more) servers, or vertically (a faster CPU/more cores/more memory).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_handling_backpressure_in_reactor&quot;&gt;Handling Backpressure in Reactor&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Reactor, like all implementations of Reactive Streams, has the ability to handle backpressure.
Use one of the following methods on a Flux (or others not listed) to specify which backpressure strategy you want to use:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureBuffer(): Buffers all items until they can be handled downstream.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureBuffer(maxSize): Buffers items up to the given count.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureBuffer(maxSize, BufferOverflowStrategy): Buffers items up to the given count and allows you to specify the BufferOverflowStrategy, such as onBackpressureBuffer(100, BufferOverflowStrategy.DROP_OLDEST)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureLatest(): Similar to keeping a buffer of only the last item added. If the downstream does not keep up with upstream, only the latest element will be given downstream.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureError(): Ends the Flux with an error (calling the downstream Subscriber’s onError) with an IllegalStateException from Exceptions.failWithOverflow() if more items were produced upstream than requested downstream.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureDrop(): Drops any items produced above what was requested.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;onBackpressureDrop(Consumer): Drops any items produced above what was requested and calls the given Consumer for each dropped item.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With each of these methods, the strategy only applies when the stream produces items faster than they can be handled.
If that’s not the case, for example with a cold stream, no backpressure strategy is necessary.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Also, keep in mind that Reactor is not magic and some care should be taken when considering backpressure strategies.
For example, if each item in the stream is critical, do not use onBackpressureDrop().
If you use onBackpressureError(), you will cause an Exception to be thrown when there are too many items, so use this with extreme caution.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you use any backpressure strategy, you should consider writing a test to validate
that your whole system will work as expected.
One way you could do this is to simulate a very slow downstream by using &lt;code&gt;Thread.sleep(1000)&lt;/code&gt; for example.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Luckily, Project Reactor supplies us with some great testing features.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_testing&quot;&gt;Testing&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Automated testing is always a good idea, and it would be nice to have tools to directly test Reactive Streams.
Luckily, Reactor comes with a few elements dedicated to testing which are gathered into their own artifact we already included: &lt;code&gt;reactor-test&lt;/code&gt;.
The two main uses of reactor-test are the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Testing a sequence follows a given scenario with StepVerifier.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Producing data to test the behavior of operators (including you own operators) downstream with TestPublisher.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_stepverifier&quot;&gt;StepVerifier&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Reactor’s StepVerifier can be used to verify the behavior of a Reactor Publisher (Flux or Mono).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here’s a simple example of a Junit test utilizing StepVerifier:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;@Test
public void testStepVerifier_Mono_error() {
  Mono&amp;lt;String&amp;gt; monoError = Mono.error(new RuntimeException(&quot;error&quot;)); //1
  StepVerifier.create(monoError) //2
    .expectErrorMessage(&quot;error&quot;) //3
    .verify(); //4
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create a Mono wrapping a RuntimeException imitating an actual error state.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a StepVerifier wrapping that Mono.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Declare that an onError event is expected and the Exception’s error message is “error”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We call verify() at the end. This will throw an AssertionError if any expectations are not met.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Next, we’ll create a Mono of just one string and verify it:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;@Test public void testStepVerifier_Mono_foo() {
Mono&amp;lt;String&amp;gt; foo = Mono.just(“foo”); //1
StepVerifier.create(foo)             //2
.expectNext(“foo”)                 //3
.verifyComplete();                 //4
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create a Mono wrapping one value, “foo”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a StepVerifier wrapping that Mono.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expect onNext is called with “foo”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call verifyComplete() has the same effect as verify() but also expects onComplete was called.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_verifying_backpressure&quot;&gt;Verifying Backpressure&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Next we&amp;#8217;ll test a Flux with four values and verify any additional values are dropped using backpressure handling.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;@Test
public void testStepVerifier_Flux_backpressure() {
    Flux&amp;lt;Integer&amp;gt; source = Flux.&amp;lt;Integer&amp;gt;create(emitter -&amp;gt; { //1
        emitter.next(1);
        emitter.next(2);
        emitter.next(3);
        emitter.next(4);
        emitter.complete();
    }).onBackpressureDrop();                            //2

    StepVerifier.withVirtualTime(() -&amp;gt; source, 3)      //3
            .expectNext(1)
            .expectNext(2)
            .expectNext(3)
            .expectComplete()                       //4
            .verifyThenAssertThat()
            .tookLessThan(Duration.ofMillis(50));   //5
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create a Flux of just four numbers using an emitter (this is a &quot;hot&quot; flux meaning it is time sensitive).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using &lt;code&gt;onBackpressureDrop&lt;/code&gt; to drop any items that aren&amp;#8217;t handled fast enough.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a StepVerifier with the Flux using &lt;code&gt;withVirtualTime&lt;/code&gt; and requesting only 3 items. Then call expectNext for each value expected.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then call &lt;code&gt;expectComplete&lt;/code&gt; thus verifying that the backpressure logic worked!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, we verify that the Flux is complete and the whole process took less than a 50 milliseconds.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The main point of using &lt;code&gt;withVirtualTime&lt;/code&gt; here is to specify that we only request three elements.
This emulates the real-world experience that would happen if a down-stream (Subscriber) could not keep up
with the upstream (Publisher), since the down-stream is what causes items to be requested in Reactive Streams.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Although this example only uses 1,2,3,4 you can imagine
the stream (Flux) could be composed of any objects.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Virtual time (with StepVerifier) can also be useful for testing things like the &lt;code&gt;Flux.interval&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_testpublisher&quot;&gt;TestPublisher&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;TestPublisher&amp;lt;T&amp;gt;&lt;/code&gt; class offers the ability to provide
finely tuned data for test purposes.
&lt;code&gt;TestPublisher&amp;lt;T&amp;gt;&lt;/code&gt; is a reactive-streams Publisher&amp;lt;T&amp;gt; but can be converted to
either a Flux or Mono.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;TextPublisher has the following methods:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;next(T) and next(T, T&amp;#8230;&amp;#8203;) : Triggers 1-n onNext signals.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;emit(T&amp;#8230;&amp;#8203;) : Does the same as next and terminates with an onComplete signal.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;complete() : Terminates with an onComplete signal.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;error(Throwable) : Terminates with an onError signal.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The following demonstrates how you might use &lt;code&gt;TestPublisher&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;TestPublisher&amp;lt;Object&amp;gt; publisher = TestPublisher.create(); //1
Flux&amp;lt;Object&amp;gt; stringFlux = publisher.flux();               //2
List list = new ArrayList();                              //3
stringFlux.subscribe(next -&amp;gt; list.add(next),
                     ex -&amp;gt; ex.printStackTrace());         //4
publisher.emit(&quot;foo&quot;, &quot;bar&quot;);                             //5
assertEquals(2, list.size());                             //6
assertEquals(&quot;foo&quot;, list.get(0));
assertEquals(&quot;bar&quot;, list.get(1));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create the TestPublisher instance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Convert it to a Flux.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new List. For test purposes we will use this list to collect values from the publisher.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Subscribe to the publisher using two lambda expressions for onNext and onError. This will add each value emitted from the publisher to the list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, emit the values “foo” and “bar” from the TestPublisher.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Assert the list’s size is two as expected.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that you must subscribe to the TestPublisher (which is done by subscribing to the stringFlux in the above example) before emitting any values.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_coming_next&quot;&gt;Coming Next&amp;#8230;&amp;#8203;&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this article I&amp;#8217;ve shown how Reactor can be used to handle backpressure and how to test it.
In my next article, we&amp;#8217;ll look into how Reactor integrates with the whole Spring ecosystem - especially with WebFlux and WebClient.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&amp;#8594; &lt;a href=&quot;https://www.adamldavis.com/blog/2020/04.html&quot;&gt;Part 3&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Project Reactor (Part 1)</title>
      <link>http://adamldavis.com/blog/2020/02.html</link>
      <pubDate>Tue, 7 Jul 2020 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2020/02.html</guid>
      	<description>
	&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_what_is_reactor&quot;&gt;What is Reactor?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The purpose of &lt;a href=&quot;https://projectreactor.io/&quot;&gt;Reactor&lt;/a&gt;,
and &lt;a href=&quot;https://www.reactive-streams.org/&quot;&gt;reactive steams&lt;/a&gt; in general is to enable operations on large amounts of data
to be broken down and executed on many different threads (multi-threading)
in the most efficient, scalable, and fast way possible.
Although parallel processing can be achieved simply using Java 8’s parallel stream, reactive streams add a plethora of additional functionality and customization such as error handling, retry, caching and replaying streams, handling backpressure, and more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can think of a reactive stream as having three rails, the data rail, the completion rail (whether or not the stream has completed), and the error rail. Also, each of the rails can be converted into the other: complete streams could be replaced,
an operation could throw an Exception, or an Exception could be handled and replaced with more data.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The core types of Reactor are &lt;em&gt;Flux&lt;/em&gt; (a stream of zero to any number of items) and
&lt;em&gt;Mono&lt;/em&gt; (a stream of zero or one item).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_getting_started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you have a Maven build, add the following to your pom file:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;io.projectreactor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;reactor-core&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;3.3.5.RELEASE&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;io.projectreactor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;reactor-test&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;3.3.5.RELEASE&amp;lt;/version&amp;gt;
  &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Gradle builds, add the following to your Gradle build file’s dependencies:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;implementation &apos;io.projectreactor:reactor-core:3.3.5.RELEASE&apos;
testImplementation &apos;io.projectreactor:reactor-test:3.3.5.RELEASE&apos;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_creating_a_flux_or_mono&quot;&gt;Creating a Flux or Mono&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can create a Flux from fixed data (cold) or programmatically from dynamic data (hot).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The following are some different way to create a cold Flux:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;Flux&amp;lt;String&amp;gt; flux1 = Flux.just(&quot;a&quot;, &quot;b&quot;, &quot;foobar&quot;); //1

List&amp;lt;String&amp;gt; iterable = Arrays.asList(&quot;a&quot;, &quot;b&quot;, &quot;foobar&quot;);

Flux&amp;lt;String&amp;gt; flux2 = Flux.fromIterable(iterable); //2

Flux&amp;lt;Integer&amp;gt; numbers = Flux.range(1, 64); //3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create a Flux from a list of values.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Flux from an iterable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a range from 1 to 64.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can create a simple Mono that is empty or has just one element like the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;Mono&amp;lt;String&amp;gt; noData = Mono.empty(); //1

Mono&amp;lt;String&amp;gt; data = Mono.just(&quot;foo&quot;); //2

Mono&amp;lt;String&amp;gt; monoError = Mono.error(new RuntimeException(&quot;error&quot;)); //3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create an empty Mono.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Mono with one element.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Mono wrapping a RuntimeException.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can also programmatically create a (hot) Flux using one of the generate, create, or push methods.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_tuples_and_zip&quot;&gt;Tuples and Zip&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Tuples are strongly typed collections of two or more elements and Reactor comes with them built in. Some operations such as zipWith, return reactive streams of Tuples.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Flux has an instance method &lt;code&gt;zipWith(Publisher&amp;lt;? extends T2&amp;gt; source2)&lt;/code&gt; which has a return type of &lt;code&gt;Flux&amp;lt;Tuple2&amp;lt;T,T2&amp;gt;&amp;gt;&lt;/code&gt;. It waits for both Fluxes (the initial flux and source2) to emit an element and then combines the two into a Tuple. There’s also static method Flux.zip which is overloaded to take from two to eight Publishers and zip them together.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Zipping is useful when you want to perform multiple operations that return reactive results (Flux or Mono).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Mono has two main flavors of zipping (which both have a return type of &lt;code&gt;Mono&amp;lt;Tuple2&amp;lt;T,T2&amp;gt;&amp;gt;&lt;/code&gt;):&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;zipWith(Mono&amp;lt;? extends T2&amp;gt; other) – Zips the current stream with another stream, giving the combination of each corresponding element in the form of Tuple2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;zipWhen(Function&amp;lt;T,Mono&amp;lt;? extends T2&amp;gt;&amp;gt; rightGenerator) – Zips the current Mono with another Mono, giving the combination of each corresponding element in the form of Tuple2, but only after the first stream’s operation has completed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example, given you have two methods which perform asynchronous operations &lt;code&gt;Mono&amp;lt;Course&amp;gt; getCourse(Long id)&lt;/code&gt; and Mono&amp;lt;Integer&amp;gt; getStudentCount(Course course), imagine you want to get the student count from the course Id you could do the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;Mono&amp;lt;Integer&amp;gt; getStudentCount(Long id) {
return getCourse(id)
.zipWhen(course -&amp;gt; getStudentCount(course))
.map(tuple2 -&amp;gt; tuple2.getT2());
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is a simple example but you can imagine combining two different entities, or performing logic on them before returning, or calling another method which takes two arguments, and so on.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_reactor_addons&quot;&gt;Reactor Addons&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Reactor provides additional functionality under the io.projectreactor.addons groupId. Reactor extra includes additional math functions, different ways to retry including Jitter and Backoff, and TupleUtils.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;io.projectreactor.addons&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;reactor-extra&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;3.3.3.RELEASE&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Gradle builds, add the following to your Gradle build file’s dependencies:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code&gt;implementation &apos;io.projectreactor.addons:reactor-extra:3.3.3.RELEASE&apos;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When your application fails at an integration point, such as when calling another RESTful service, to make your overall system reliable you might want to retry the call some number of times. However, to keep from overloading the failing service, you should employ Backoff, or increasing the time between each retry, and Jitter, randomly modifying the time so that the retries from many different instances do not happen at the same time (correlate). For example take a look at the following code:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;var retry = Retry.anyOf(IOException.class) \\1
 .exponentialBackoff(Duration.ofMillis(100), \\2
    Duration.ofSeconds(60))
 .jitter(Jitter.random()) \\3
 .retryMax(5)
 .withApplicationContext(appContext) \\4
 .doOnRetry(context -&amp;gt;
    context.applicationContext().rollback());

return flux.retryWhen(retry); \\5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;We create the Retry with exception value of IOException, meaning it will retry only when that exception is thrown.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We define exponential backoff with a starting value of 100 ms and maximum value of 60 seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We add random Jitter and set the retry max to 5, meaning it retry at most 5 times.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We add the Spring ApplicationContext and use it to apply rollback after each failure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally we call retryWhen(retry) on a Flux instance to apply the Retry to that Flux.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information on retries, backoff, and jitter see this excellent article from
&lt;a href=&quot;https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/&quot;&gt;Amazon’s builder library.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&amp;#8594; &lt;a href=&quot;https://www.adamldavis.com/blog/2020/03.html&quot;&gt;Part 2&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Spring Handbook</title>
      <link>http://adamldavis.com/blog/2020/01.html</link>
      <pubDate>Sun, 1 Mar 2020 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2020/01.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s been a while since I&amp;#8217;ve posted. There&amp;#8217;s been a lot going on (I&amp;#8217;ve been very busy).
I started a new position at a large corporation here near Orlando (a mouse-themed amusement park; more on this later).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Meanwhile, I&amp;#8217;ve finally started work on &quot;Spring Handbook&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_spring_handbook&quot;&gt;Spring Handbook&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I&amp;#8217;ve been using Spring for a long, long time (since 2005).
It&amp;#8217;s been there throughout almost my entire Java development career and it&amp;#8217;s evolved substantially over the years.
I&amp;#8217;ve had &quot;Spring Handbook&quot; on my check-list of books to write for a long time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.apress.com/us/book/9781484261439&quot;&gt;Spring Quick Reference Guide&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s going to be picked up by Apress, and is currently under development.
(&lt;strong&gt;*Edit\&lt;/strong&gt;* It&amp;#8217;s published!)
I&amp;#8217;m really excited about this one - there is so much to cover and it&amp;#8217;s so relevant to software development today especially with Java.
I&amp;#8217;m going to cover so many things:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Core Spring&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring Data&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring Security&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring Boot&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Webflux and Reactor&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;and tons more&amp;#8230;&amp;#8203;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_graphql&quot;&gt;GraphQL&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In other news, I&amp;#8217;ve learned a lot about &lt;a href=&quot;https://graphql.org/&quot;&gt;GraphQL&lt;/a&gt; at my new job.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s combines a typed schema with the ability for clients to tell the server exactly what they want.
This reduces the amount of unnecessary data requested, the number of HTTP requests needed, thereby increasing performance overall of a software system.
Although I was suspect at first, it&amp;#8217;s actually very clever. I&amp;#8217;ve learned a lot about it and hope that I can share more about it later on.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Groovy 3 Course and Gradle</title>
      <link>http://adamldavis.com/blog/2019/05.html</link>
      <pubDate>Mon, 30 Sep 2019 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2019/05.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As I&amp;#8217;ve mentioned I&amp;#8217;ve been working on courses on Leanpub.
I&amp;#8217;m happy to announce that the first one is complete!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It has changed a lot since my initial thought process.
Among other things, it has a new subtitle,
&quot;Go from beginner to expert Groovy Programmer with Groovy 3.0 and Gradle 5&quot;.
I decided that it needed more specifics than &quot;just Groovy&quot; and Gradle
is a popular build tool and a good reason to start learning Groovy.
Check it out: &lt;a href=&quot;https://leanpub.com/c/learninggroovy3&quot;&gt;&quot;Groovy 3 Course&quot;&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In case you&amp;#8217;re curious, this course contains tons of new material
and is not simply a copy of &lt;em&gt;Learning Groovy 3&lt;/em&gt; - far from it.
It could be seen as a companion but covers more of some topics and less of others.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I&amp;#8217;ve also decided to launch it with a very low introduction price.
I want the barrier to entry to be very low.
Please share it someone you think might benefit from it if not yourself.
As always, all feedback is welcome (adamd @ this website).
Let me know what you&amp;#8217;d like to see more about or less about.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Due to other projects I&amp;#8217;m working on, I&amp;#8217;m going to postpone for now
working on &lt;a href=&quot;https://leanpub.com/c/advancedgroovycourse&quot;&gt;&quot;Advanced Groovy&quot;&lt;/a&gt;
(I hope to cover not just advanced Groovy but also some other projects
in greater detail).
I have a lot going on (including yet another second edition book) but I hope
to get to it eventually.&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Learning Groovy 3 Released</title>
      <link>http://adamldavis.com/blog/2019/04.html</link>
      <pubDate>Mon, 5 Aug 2019 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2019/04.html</guid>
      	<description>
	&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;a class=&quot;image&quot; href=&quot;//github.adamldavis.com/books.html&quot;&gt;&lt;img src=&quot;images/learninggroovy3.jpeg&quot; alt=&quot;Learning Groovy 3&quot; width=&quot;350&quot;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The second edition of &quot;Learning Groovy&quot; (which covers Groovy 3.0 thus the name) is now available. After months of researching, writing, and editing, it has finally gone to print! I&amp;#8217;m really excited to announce this and I hope it spreads the love of Groovy far and wide.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Groovy can be used as a dynamic or static language depending on your choice, however it&amp;#8217;s hard to condense that into a short subtitle. We also wanted to include how it is closely related to Java, hence the subtitle, &quot;Java-Based Dynamic Scripting.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The twitter announcement is &lt;a href=&quot;https://twitter.com/adamldavis/status/1157685694111932417&quot;&gt;here&lt;/a&gt;. And the book itself can be found on Apress or my &lt;a href=&quot;http://github.adamldavis.com/books.html&quot;&gt;books page&lt;/a&gt; or wherever you prefer to purchase books.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Groovy 3 beta-3 should come out shortly, with release candidates soon after, so this is book is out slightly before the final 3.0 release. However, if you like to stay ahead of the curve, now is a good time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sidebarblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Courses&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I&amp;#8217;m currently in the process of creating courses on Leanpub. Please check out these two courses: &lt;a href=&quot;https://leanpub.com/c/learninggroovy3&quot;&gt;&quot;Beginning Groovy 3&quot;&lt;/a&gt; and &lt;a href=&quot;https://leanpub.com/c/advancedgroovycourse&quot;&gt;&quot;Advanced Groovy&quot;&lt;/a&gt;. There may be more in the future but they&amp;#8217;re in the beginning stages right now. These courses will include exercises, quizes, and probably video to go along with the course. All feedback is welcome.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Gr8Conf EU 2019</title>
      <link>http://adamldavis.com/blog/2019/03.html</link>
      <pubDate>Fri, 28 Jun 2019 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2019/03.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I had the great privilege of leading a workshop and two talks at &lt;a href=&quot;https://gr8conf.eu/&quot;&gt;Gr8Conf EU&lt;/a&gt; 2019 in Copenhagen, Denmark. This was also my first time attending Gr8Conf EU (I did attend Gr8Conf US 2017). My life has finally quieted down enough now that I can write about my experience.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The conference was, in a word, great. I saw a few familiar faces, like Paul King, Jeff Scott Brown, Michael Carducci, Sergio del Amo Caballero, and Jeff Beck (all of whom I’ve seen before, mostly as just another audience member), and met some great new people whom I’ve never seen before but who certainly left a lasting impression that I won’t soon forget like Vladimír Oraný, Szymon Stepniak, Jennifer Strater, Charlotte Mays, and others. For an extremely introverted person such as myself, I don’t often talk to so many people at one time, and I’m grateful for the opportunity to converse and openness of everyone at this conference. (The coffee and food was great too!)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There were too many great talks to list, but some highlights for me were Paul King’s keynote on Groovy 2.5, 3 and 4 (which is available &lt;a href=&quot;https://www.youtube.com/watch?v=B05oJjtSEVQ&quot;&gt;online&lt;/a&gt;), Jesper Steen Møller’s talk, “Reactive Web APIs with Micronaut” (which brilliantly showed how to use Reactive Streams within a micronaut based microservice including a demo of how to use a backpressure strategy), and the “Running a developer’s blog” talk by Szymon Stepniak (I hope to use some of his suggestions in the future if I ever get the time).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Oh and I did some talks too. Eventually these should make it onto youtube, but it might be many months. For now you can check out my github repo ( &lt;a href=&quot;https://github.com/adamldavis/2019-gr8conf&quot; class=&quot;bare&quot;&gt;https://github.com/adamldavis/2019-gr8conf&lt;/a&gt; ) which has all of the code related to my talks/workshop plus a bit more. I tweeted out the slides at some point but it’s up to you to find them. Just kidding. Here ( &lt;a href=&quot;https://www.slideshare.net/adam1davis/&quot; class=&quot;bare&quot;&gt;https://www.slideshare.net/adam1davis/&lt;/a&gt; ).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It was a really great conference and Copenhagen is beautiful. I hope to return again next year (or maybe in two years if not next year).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Meanwhile, I’m finished with the final updates to “Learning Groovy 3” which should be released later this year! I worked on this for several months this year and my technical reviewer gave me some great feedback so it should be a good one. In addition to updating the book for Groovy 3.0 and Grails 3.3, I’ve also updated and polished additional areas of the book based on my personal understanding of Groovy and things that have changed over the years.&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Micronaut</title>
      <link>http://adamldavis.com/blog/2019/02.html</link>
      <pubDate>Sun, 31 Mar 2019 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2019/02.html</guid>
      	<description>
	&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;images/micronaut_mini.png&quot; alt=&quot;micronaut&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://micronaut.io/&quot;&gt;Micronaut&lt;/a&gt; was built by many of same people behind Grails. It uses compile-time annotation processing to build an application with a deadly fast startup time, has support for reactive streams, netty, and a reactive http client, among other things.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It’s open-source (Apache 2) and supports applications written in Java, Groovy, or Kotlin.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Due to it’s non-reflective nature, it naturally enables applications to run on the GraalVM, which is described:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;literalblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;`&quot;GraalVM is a new universal virtual machine from Oracle that supports a
polyglot runtime environment and the ability to compile Java
applications down to native machine code.&quot;` –https://micronaut.io/&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;GraalVM compiles applications to native code allowing for incredibly fast application start-up speeds even for large applications, which makes it best suited for “serverless” applications, like AWS Lambdas or the like.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Even running on a vanilla JVM, Micronaut has very low overhead (in both memory and processor time) and has profiles for targeting different platforms: server, function (like AWS Lambda), or command-line applications.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It came out not too long ago and I’ve only made a few applications with it but so far it looks really great!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I’ve added an example of using micronaut with groocss and the asset-pipeline. Check it out.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/adamldavis/groocss/tree/master/micronaut-example&quot; class=&quot;bare&quot;&gt;https://github.com/adamldavis/groocss/tree/master/micronaut-example&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Groovy 2.5 &amp; 3</title>
      <link>http://adamldavis.com/blog/2019/01.html</link>
      <pubDate>Wed, 13 Feb 2019 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2019/01.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you have followed me for any time, you know I’m a big fan of Groovy, the super-Java-like language that runs on the JVM. You’ve probably heard of it, maybe you even use it, but what is less known is that it’s constantly evolving and has some great new features coming soon (or already here).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Inspired by some recent news, here’s all about Groovy 2.5 and 3.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_updates_in_groovy_2_5&quot;&gt;Updates in Groovy 2.5&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Groovy 2.5 added support for JDK9+, added 11 new AST transformations, and added the macro feature which makes writing AST transformations much easier.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The annotations added in Groovy 2.5 include: @AutoFinal, @AutoImplement, @ImmutableBase, @ImmutableOptions, @MapConstructor, @NamedDelegate, @NamedParam, @NamedParams, @NamedVariant, @PropertyOptions, and @VisibilityOptions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@AutoImplement: Automatically implements missing abstract methods (such as those from an Interface). You can specify an Exception to throw from those methods such as UnsupportedOperationException. It can be useful for generating test stubs or when you only need to implement a subset of inherited abstract methods.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@AutoFinal: Automatically adds final modifier to method parameters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@MapConstructor: Adds a constructor to your class that has one Map parameter and expects field-names as keys and sets the corresponding field values.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Also many annotations were improved with additional attributes. For example, @TupleConstructor now includes seven more attributes. The @Immutable annotation was updated to recognize the Date/time classes added in Java 8 are immutable, and to handle Optional.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_updates_in_groovy_3&quot;&gt;Updates in Groovy 3&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Groovy 3 sports a completely rewritten parser that brings Groovy up to parity with the latest Java 11 syntax along with new Groovy-only features. It runs on JDK 8 minimum and has better support for JDK 9/10/11.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Java-like syntax now includes Java-style lambda expressions and method references, array initialization, and do/while loops, which have eluded Groovy for many years.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Edit: There is hope that in the near future after working out some issues. The new parser also compiles to “indy” by default which uses Java’s invokedynamic feature. This has been available for years, but was not the default before. This, along with other changes, makes Groovy code more performant.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_new_operators&quot;&gt;New Operators&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Identity: === can now be used to express identity-equal and !== and not identity-equal. Since Groovy interprets == as “.equals”, it used “.is” for identity-equals in the past. The support of “===” should avoid some confusion. This is similar to JavaScript’s === operator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Negative variants of operators: !instanceof and !in are now supported. This will simplify the syntax in these situations. Before you would have to type !(x instanceof Date) whereas now you can simply type x !instanceof Date.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Elvis Assignment: You may be familiar with the elvis operator (?:) in Groovy. In many cases you would use this operation to provide a default when assigning a value. For example: name = name ?: ‘None’. Now you can shorten this expression to have the same meaning in Groovy 3 with the following: name ?= &apos;None’&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Safe indexing: Much like the safe-reference operator, there is now a safe-indexing operator, ?. This allows you to access an index of an array (or List), but if the array is null, it will return null instead of throwing an exception. For example the following would set the value to the first value of the array, or null if the array is null: value = array?[0]&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_java_parity&quot;&gt;Java Parity&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Groovy 3 support new features added from Java 8 to 11, such as lambda expressions, method references, constructor references, and even local variables (var).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All flavours of lambda expressions are supported (and currently compiled to Closures):&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No parameters: () &amp;#8594; expression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Single paramter: x &amp;#8594; expression&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explicit return is optional: (x, y) &amp;#8594; { x * y }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Types are allowed: (int x, int y) &amp;#8594; { return x + y }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Default values are allowed: (int x, int y = 10) &amp;#8594; x+y&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There’s much more….. in fact, I’m working on updating my book, &lt;strong&gt;Learning Groovy&lt;/strong&gt;, and releasing a second edition later this year, so stay tuned!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As you can see there’s a ton to be excited about with Groovy 3. Groovy 3.0.0-alpha-4 is available right now so go check it out.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Learn more at &lt;a href=&quot;http://groovy.apache.org&quot; class=&quot;bare&quot;&gt;http://groovy.apache.org&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Upgrading to Java 11</title>
      <link>http://adamldavis.com/blog/2018/04.html</link>
      <pubDate>Tue, 11 Dec 2018 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2018/04.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So you want to upgrade to Java 11?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Maybe you’ve put off upgrading Java for a while but are realizing that Oracle soon plans to stop supporting Java 8. Have no fear, since you’ve procrastinated, other people have gone through the pain already and shared what they learned!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;First of all, what’s new in Java 9, 10, and 11? The big things are JShell, modularity, local variable declarations (var), and in 11 the removal of JavaEE, xml, and corba among other things. Davide Angelocola shared a good summary of the new features, as well as his notes on upgrading to Java 11 here in this &lt;a href=&quot;https://twitter.com/the_dfa/status/1052091536484298753&quot;&gt;tweet (pdf)&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In another post by &lt;a href=&quot;http://jugsi.blogspot.com/2018/11/from-java-8-to-java-11-in-single-step.html&quot;&gt;Giacomo Veneri&lt;/a&gt; gives a good overview of features from 8 to 11 including creating immutable collections, new String methods, and more and comes with a handy chart.
image&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Finally, &lt;a href=&quot;https://winterbe.com/posts/2018/08/29/migrate-maven-projects-to-java-11-jigsaw/&quot;&gt;Benjamin Winterberg gives a great overview&lt;/a&gt; of how to upgrade to Java 11 with Maven.  The main takeaway is to update all your dependencies and add any missing libraries like jaxb and javax.annotations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Due to Oracle’s change in licensing it is highly recommended you use OpenJDK in production now (it’s mostly identical to Oracle Java and Oracle now charges for Oracle JDK in production). Other editions of Java exist or will exist in the future such as &lt;a href=&quot;https://aws.amazon.com/corretto/&quot;&gt;Amazon Coretto&lt;/a&gt; due to the changes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Happy upgrading!&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Test Driven Design (TDD)</title>
      <link>http://adamldavis.com/blog/2018/03.html</link>
      <pubDate>Tue, 27 Nov 2018 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2018/03.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When I first started to learn programming, first on a TI-89 calculator and then QBASIC, and even later in Java, I had no idea what testing was all about. I thought testing was running the program and making sure it worked. Maybe even put some debug print statements here and there. It was years later I learned about automated testing and test frameworks like JUnit.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As the years went by, mainly after starting to work, I learned the benefit of writing tests - not only to ensure the correctness of code, but also to enable future changes without the fear of breaking things. This is the strongest quality of tests: to enable change.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Writing tests also helps you think the problem you’re trying to solve and clarifies your thinking. As you write the test you have to figure out what exactly your code does, what are the edges cases, and what could go wrong. With &lt;strong&gt;TDD (Test Driven Development)&lt;/strong&gt;, it simply goes one step further: you write the tests first, then the code. Instead of blindly typing out the code for a solution you vaguely hold in your head, you specify what you want your code to do - the solution space - then go about making it happen - the implementation. It has the added benefit that your code is always well tested, since you wrote the tests first, rather than an after-thought.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The last D in TDD could also stand for “Design” since when you write tests you are often forced to design the code to be more easily testable. This helps keep code clear and concise with a good separation of concerns. You should divide you logic into the smallest units possible and TDD helps you do this.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I don’t always do TDD - many times the code is so simple that writing tests feels like repeating yourself - but when I do I find the resulting code to be clear, correct, and well designed. If you haven’t tried it, I highly suggest trying TDD today.&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Beyond Java 9</title>
      <link>http://adamldavis.com/blog/2018/02.html</link>
      <pubDate>Wed, 18 Jul 2018 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2018/02.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I’m at UberConf this week - it’s going great. Last night I sat through a talk by Venkat Subramaniam called “Beyond Java 9″. I’ve always been curious about what’s coming up (and already here in Java 10) and Venkat always is a great speaker so I was excited to go to this one. Here are my notes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;CompleteableFuture&lt;/strong&gt; was added in Java 8. Many of us missed it because we were so focused on Streams. Java 9 added modules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Oracle has decided to start releasing a new major version of Java every 6 months.Not so much for the end developers, this is to make adding new features to language easier and less stressful for the teams behind Java.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At the same time, Oracle is changing their support of previous versions to some degree. If you do not pay for service, this doesn’t effect you except that if you want to be using a “supported” version of Java at all times, you will have to upgrade every six months.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you do pay for standard support, you can get up to three years of support for long-term-service (LTS) versions of which Java 11 is the next one.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The standard reliability of Java is not changing. Despite the appearance of faster releases, the actual development of the Java the language is not getting much faster. By changing to a major release every six months, the Java language features that are in development for years (sometimes more than ten years) don’t have the added pressure of fitting into one release every three or four years. This way each release can add one or two major features, rather than cramming tons of new features into each major release - as has been the case in the past.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Meanwhile, Oracle is continuing to release OpenJDK as open source.
This allows other companies, such as Azul, to modify it and provide their own support contracts, effectively creating a marketplace for JVMs (which is a good thing for many reasons). This allows some competition and is a force towards innovation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Which comes to one of the most important points I took from this talk:
“Java will not innovate on language features. It will innovate on Implementation.”&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;openblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Java has never been on the cutting edge of language features, instead the people behind Java take a long look at what works in other languages and takes time to implement these features in the best way possible. For example, Java 8 lambdas expressions use invoke-dynamic. The behind the scenes implementation allows lambdas to be extremely performant and at the same time allow for future improvements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Venkat then went on to talk about upcoming projects in Java: Project Panama, Project Valhalla, Project Amber, and Project Loom, which I will not go into right now. This talk was both entertaining and informative (Venkat uses metaphors and jokes sprinkled throughout his talks).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Although this is a large change in the Java language development cycle, in the end this is a good thing because it will encourage Java developers to update more often and spread out new features over more time, not bundling them all at once.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Reactive Streams in Java</title>
      <link>http://adamldavis.com/blog/2018/01.html</link>
      <pubDate>Sun, 8 Jul 2018 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2018/01.html</guid>
      	<description>
	&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;images/reactivebooks.jpg&quot; alt=&quot;picture of books&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So… I’m working on a thing, Reactive Streams in Java. This has been on my back burner for a long time, and I started work on it for real early this year.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here’s the description from the book’s landing page:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&quot;Reactive Streams are a standard approach to handling concurrency in modern applications. The Java 9 release includes new support for reactive streams. This book attempts to provide an easy introduction to Reactive Streams in Java including in depth introductions to RxJava, Akka Streams, and Reactor and how they can be used.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This book will cover everything you need to know about existing projects and how they translate in Java 9 (and 10 and 11). Mainly in Java 10 they’ve introduced “var” and this can be used for intermediate variables.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This book uses a progressive publishing model. As the book grows, so does the price. This encourages early adopters, so… maybe think about buying it. I’m not expecting a lot of sales so I appreciate every reader. Feel free to ask me questions (or pester me to keep writing).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This book has been picked up by a publisher - I’d rather not say who because I’m not sure I’m allowed to :) - and will be published in a complete, edited, and polished version later this year (winter 2018). However, the only way to get it right now is from leanpub. Thanks!&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Modern Java: 2nd Edition</title>
      <link>http://adamldavis.com/blog/2017/04.html</link>
      <pubDate>Thu, 7 Dec 2017 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2017/04.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In case you didn’t know, I’ve been working on
&lt;a href=&quot;https://leanpub.com/modernjavasecondedition/&quot;&gt;Modern Java: 2nd Edition&lt;/a&gt;
 for more than a year now. Over that time I’ve decided to
add Java 9 and cover more libraries and frameworks like Hibernate and
RxJava. I’ve also fleshed out some existing sections more fully.
After many distractions and other projects getting in the way,
I finally feel like I’m coming close to finishing it!  It’s now
more of a full introduction to Java and the Java ecosystem from
features of Java 8 and 9 all the way to testing, building, web
frameworks, reactive streams, and a lot more.&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>RxJava</title>
      <link>http://adamldavis.com/blog/2017/03.html</link>
      <pubDate>Wed, 15 Nov 2017 00:00:00 -0500</pubDate>
      <guid isPermaLink="false">blog/2017/03.html</guid>
      	<description>
	&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;(This is an excerpt from &lt;a href=&quot;https://leanpub.com/modernjavasecondedition&quot;&gt;Modern Java: Second  Edition&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ReactiveX/RxJava&quot;&gt;RxJava&lt;/a&gt; is the open-source library for
reactive programming that is part of the ReactiveX project. ReactiveX includes
implementations in several different languages including rxjs, RxRuby, RxSwift,
RxPHP, RxGroovy and many more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;RxJava 2 was rebuilt to be compatible with the Reactive Streams specification and
is preferable to RxJava 1.x since it is scheduled for end-of-life. There were many
changes from version 1 to 2 that could be confusing.
To avoid confusion we will focus on RxJava 2.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;_flowable&quot;&gt;Flowable&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The basic entry class in RxJava is &lt;code&gt;io.reactivex.Flowable&lt;/code&gt;.
It implements the Reactive-Streams Pattern and offers factory methods,
intermediate operators and the ability to consume reactive dataflows.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The following example demonstrates using RxJava to do a simple calculation on a range of numbers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;prettyprint highlight&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;public static List doSquares() {
   List squares = new ArrayList();
   Flowable.range(1, 64) // &lt;b class=&quot;conum&quot;&gt;(1)&lt;/b&gt;
       .observeOn(Schedulers.computation()) // &lt;b class=&quot;conum&quot;&gt;(2)&lt;/b&gt;
       .map(v -&amp;gt; v * v) // &lt;b class=&quot;conum&quot;&gt;(3)&lt;/b&gt;
       .blockingSubscribe(squares::add); // &lt;b class=&quot;conum&quot;&gt;(4)&lt;/b&gt;
   return squares;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a range from 1 to 64.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call the method &lt;code&gt;observeOn&lt;/code&gt; to determine which &lt;code&gt;Scheduler&lt;/code&gt; to use.
This determines on which Thread the flow will run.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; method transforms each value. In this case we calculate the square.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, we initiate the flow by calling a “subscribe” method.
In this case, &lt;code&gt;blockingSubscribe&lt;/code&gt; blocks until the entire flow has
completed. This means that the &lt;code&gt;squares&lt;/code&gt; list will be populated
before the return statement. Otherwise the flow would run on a
different thread and the values in the squares list would be
unpredictable at any given time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;(This is an excerpt from &lt;a href=&quot;https://leanpub.com/modernjavasecondedition&quot;&gt;Modern Java: Second  Edition&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Gr8Conf US and other things…</title>
      <link>http://adamldavis.com/blog/2017/02.html</link>
      <pubDate>Sat, 5 Aug 2017 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2017/02.html</guid>
      	<description>
	&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I just back from &lt;a href=&quot;http://gr8conf.us&quot;&gt;Gr8Conf&lt;/a&gt; in Minneapolis last week and I had a great time. In case you missed it, I led a three hour workshop on Groovy and the &lt;a href=&quot;https://www.slideshare.net/AdamDavis30/learning-groovy-1-half-day-workshop&quot;&gt;slides&lt;/a&gt; and &lt;a href=&quot;https://github.com/adamldavis/2017-gr8conf-learning-groovy&quot;&gt;code&lt;/a&gt; are available (I did some practice screen-casts on youtube as well). Although I was pretty nervous leading up to it, I think it went really well. To those who attended: Thank you for listening and asking such great questions, I hope you
 enjoyed it! This was my first such workshop and everyone was super nice, so thank you again. I look forward to doing talks and/or
 workshops again in the future.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There were tons of great talks at Gr8Conf and although I didn’t get
to go to all of them (I wish I could) I learned a lot and loved the
 energy from the conference in general. The “hallway discussions” and lunches were great as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In other news, “Learning Groovy” is now featured on the official
&lt;a href=&quot;http://www.groovy-lang.org/learn.html&quot;&gt;Groovy website&lt;/a&gt;,
and was featured in &lt;a href=&quot;http://groovycalamari.com/issues/91?#start&quot;&gt;&quot;Groovy Calamari&quot;&lt;/a&gt;!
I can’t stress enough how
thrilled I am about this! Meanwhile, thank you to my company the
SDG for supporting me in all these endeavors as well as just being
a great company.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://leanpub.com/modernjavasecondedition&quot;&gt;Modern Java: Second Edition&lt;/a&gt;
 is still in the works
and I’ve expanded it to include Java 9. I’m sorry this one
has been in production for so long. I hope to get it wrapped
up before the final release of Java 9 in September. :-)
There’s been a lot going on in the past year …but I won’t
make excuses. The good thing is the final product is going to
be great. With all the new stuff in Java 9, plus more experience
with Java 8 and other things, it should be interesting.
 I’m also mulling over next books, but nothing to announce yet.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I met and talked with tons of people at Gr8Conf, but one in
particular is Eric Helgeson @nulleric. If you’re at all interested
in Grails 3, check out his book, &lt;a href=&quot;https://www.grails3book.com/&quot;&gt;Practical Grails 3&lt;/a&gt;.
 The cool thing about it is he’s selling his book completely on his own
and the book covers the app he wrote to sell the book.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Also, I’m still working on &lt;a href=&quot;http://groocss.org&quot;&gt;GrooCSS&lt;/a&gt;
 and have tons of ideas for it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Thanks for reading! Hopefully I’ll write again soon…&lt;/p&gt;
&lt;/div&gt;
	</description>
    </item>
    <item>
      <title>Groovy News!</title>
      <link>http://adamldavis.com/blog/2017/01.html</link>
      <pubDate>Thu, 28 Jul 2016 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">blog/2017/01.html</guid>
      	<description>
	
&lt;p&gt;Great news everyone! &lt;/p&gt;

&lt;p&gt;I can now announce, &lt;a src=&quot;https://www.apress.com/us/book/9781484221167&quot;&gt;Learning Groovy&lt;/a&gt; is
	available for pre-order on Apress!
	They have been great to work with and it is much improved from the original version due to their
	feedback and the technical editor.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;https://leanpub.com/modernjavasecondedition&quot;&gt;Modern Java: Second Edition&lt;/a&gt; is available in
	beta-mode on Leanpub! This book joins together my original
	Modern Java book, with all of the stuff on Java 8 and some new stuff will be coming soon!
&lt;/p&gt;
&lt;p&gt;I’ve launched &lt;a href=&quot;http://groocss.org&quot;&gt;GrooCSS&lt;/a&gt;, a little pet project of mine. More to come on this later. Check it out!&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;
&lt;code&gt;
&lt;/code&gt;
&lt;/pre&gt;


	</description>
    </item>

  </channel> 
</rss>
