Quantcast
Channel: T. C. Mits 108 » java
Viewing all articles
Browse latest Browse all 36

Java ‘hello world’ using RxJava library

$
0
0

A simple RxJava example that uses an array of strings and combines them to create the traditional first program.

RxJava is a NetFlix open source library that they developed as part of optimizing their architecture. The library is related to the “Reactive programming” pattern: “RxJava is an implementation of Reactive Extensions – a library for composing asynchronous and event-based programs using observable sequences for the Java VM”.

I thought I would try my hand at it. I used the ‘Hello world’ example on the RxJava wiki’s getting started page:

public static void hello(String... names) {
      Observable.from(names).subscribe(new Action1<String>() {
          @Override
          public void call(String s) {
              System.out.println("Hello " + s + "!");
          }
      });
}

With the above, one can start using more of the library to get a feel for the syntax and how it relates to the underlying concepts.

Example
Below I created a JUnit test class in Java that creates an Observable from an array ["Hello", "world"], and each test subscribes to it. That is, the test is the Observer. RxJava has a rich API, thus there are many ways to take that array and create the “Hello world!” string. The first test “reduces” the results from the Observables. The inline class’ call method adds each result to the previous result, and then the final result is passed to the subscribe’s inline Action1 (that is, it has only one argument) method.

Code snippet of first test

        observable.reduce( new Func2<String, String, String>() {            
            public String call(String t1, String t2) {
                return t1 + " " + t2;
            }
        }).subscribe(new Action1<String>() {
            public void call(String s) {
                String actual = s + "!";
                Assert.assertEquals("Hello world!", actual);
                System.out.println(actual);
            }
        });

The second test below also accomplishes the above, however it uses an explicit inline Observer which has the three methods, onCompleted, onError, and onNext. Here we have to build the final result from the invocations of the onNext(T) method. There is a problem with this test. It fails. The final string is built by appending a blank to each result, and in the onCompleted() method a “!” is appended. This creates the string “Hello world !”, thus the assertion fails.

Code snippet of second test

        observable.subscribe(new Observer<String>() {
            StringBuilder buf = new StringBuilder();
    
            public void onCompleted() {
                try {
                    String actual = buf.append("!").toString();
                    Assert.assertEquals("Hello world!", actual);
                } catch (Throwable e) {
                    onError(e);
                }
            }

            public void onError(Throwable e){
                thrown =new RuntimeException(e.getMessage(),e);
            }

            public void onNext(String args) {
                buf.append(args).append(" ");                
            }
        });

It was a little tricky getting the second test to fail. When the onCompleted method throws an exception, the onError method is not invoked since the Observable is done generating any data. Thus, I had to wrap the assertion fail in a try catch, then manually invoke the onError method. Probably semantically incorrect approach. But, that still would not make the JUnit test fail, I had to set a field so that the last statements in the test would use that to fail the test.

Full Source

import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import rx.Observable;
import rx.Observer;
import rx.util.functions.Action1;
import rx.util.functions.Func2;

/**
 * @author jbetancourt
 */
public class HelloRxTest {
    
    private Observable<String> observable;
    private Exception thrown;
    
    @Before
    public void before() {
        observable = Observable.from(new String[]{"Hello","world"});
    }

    @Test
    public final void test1() {
        
        observable.reduce( new Func2<String, String, String>() {            
            public String call(String t1, String t2) {
                return t1 + " " + t2;
            }
        }).subscribe(new Action1<String>() {
            public void call(String s) {
                String actual = s + "!";
                Assert.assertEquals("Hello world!", actual);
                System.out.println(actual);
            }
        });
    }    
    
    /**
     * Should fail.
     * @throws Exception 
     * 
     */
    @Test(expected=RuntimeException.class)
    public final void test2() throws Exception {
        observable.subscribe(new Observer<String>() {
            StringBuilder buf = new StringBuilder();
    
            public void onCompleted() {
                try {
                    String actual = buf.append("!").toString();
                    Assert.assertEquals("Hello world!", actual);
                } catch (Throwable e) {
                    onError(e);
                }
            }

            public void onError(Throwable e){
                thrown =new RuntimeException(e.getMessage(),e);
            }

            public void onNext(String args) {
                buf.append(args).append(" ");                
            }
        });
        
        if(null != thrown){
            throw thrown;
        }        
    }
}

Summary
Have not grokked RxJava yet, so the above is probably not idiomatic use or correct.

RxJava looks very useful and approachable. I did find some documentation issues:

  1. Not enough examples in pure Java. The JUnit tests are not really usable, but they help
  2. The Wiki code examples are not up to date with the API as present in the latest source.
  3. The Javadocs are old too. They don’t even show some packages.

These are minor doc issues. Or maybe I’m looking in the wrong place?

Options?
There are many Reactive libraries available. Another is Pivotal’s Reactor. See this article “Pivotal’s Reactor Goes GA” A review of Reactor is “Playing with Reactor“.

Links


Listening to Jake Bugg: “Broken”

On youtube:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Viewing all articles
Browse latest Browse all 36

Trending Articles