Enterprise Java

Java Is Superior To React Native In Practically Every Way

I got into a discussion with a colleague on the Java vs. JavaScript subject, which is a problematic subject to begin with. He then mentioned how great React Native is, I decided I have to look into it and maybe grab some ideas for Codename One…

There are some nice ideas there, but none of them is revolutionary or exceptional and most of them are pretty old news for Codename One developers running in Java 8.

One thing I did like was how short the React demo code seemed to be, so I ported it to Codename One and ended up with roughly the same amount of code and arguably better/simpler code!

Check out the full listing at the end of the article or in the github project here, but lets first review why the Java code is “better”.

Synchronous Execution

JavaScript fans hate this but its still a fact that synchronous code is simpler to read, follow and debug. E.g. this is the React Native version of the code that fetches the data:

fetchData: function() {
  fetch(REQUEST_URL) 
        .then((response) => response.json()) 
        .then((responseData) => { 
             this.setState({ 
                  dataSource: this.state.dataSource.cloneWithRows(responseData.movies), 
                  loaded: true, 
             }); 
         }) 
  .done(); 
},

I have well over 20 years of professional programming experience and this is still hard to follow. Apparently if done() is omitted you won’t get any error handling?

Its weird and error prone. I feel like a lot of code is hidden behind this which makes the terseness more confusing than simplifying (kind of like following a political debate thru Twitter). To me our code is way simpler:

react.add(BorderLayout.CENTER, new InfiniteContainer() {
    public Component[] fetchComponents(int index, int amount) {
        try {
            Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get("movies");
            Component[] response = new Component[data.size()];
            int offset = 0;
            for(Object movie : data) {
                response[offset] = createMovieEntry(Result.fromContent((Map)movie));
                offset++;
            }
            return response;
        } catch(IOException err) {
            Dialog.show("Error", "Error during connection: " + err, "OK", null);
        }
        return null;
    }
});

Notice that this isn’t the exact equivalent of the code above as we also create components, add them to the UI and handle the resulting error! a more fair comparison would be:

try {
    Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get("movies");
    ...
} catch(IOException err) {
    ...
}

That’s effectively one line of code that could even be shorter after which we have the result… No flow, no callback!

Developers often pour hate on the Java checked exceptions feature and I have to agree that they are sometimes painful (f’ing InterruptedException is stupid) but this is a great example of why checked exceptions matter. We MUST handle errors properly and we can’t just ignore it until our code reaches production with this lovely “TODO” comment that no one bothered reading.

One Language – Less Code

The listings seem roughly equivalent in size but you will notice the react code ignores the native platform specific code when dealing with the JavaScript code. Our listing is all encompassing, no additional code is needed and no further boilerplate, projects etc.

React Native takes this even further by mixing tags with the JavaScript code effectively mixing declarative code into the regular flow. Yes it shortens the code, but also removes a huge part of the value of declarative programming which is the separation of responsibilities.

Reload == Apply Code Changes

React Native can be debugged by reloading which is there to help when working with the awful Android emulator. Luckily Codename One doesn’t need that emulator, you also don’t need to restart your app to reload compiled changes… E.g. in NetBeans just use “Apply Code Changes” in the debugger and your changes are instantly mirrored into a running app.

Scripting Languages Are Problematic “On Device”

This isn’t quite a “React Native” specific rant, its related to all tools packaging JavaScript in the app bundle. Scripting languages are great for the web, they are like “duct tape”. Show me a hacker who doesn’t LOVE duct tape!

The temptation to ship an app built with such duct tape is big, but unlike the web where you can just fix that “weird undefined” bug in production by deploying a new update. With apps you need to go thru Apples approval process… This means production bugs that stay while you watch your rating drop.

Yes, unit tests, lint and a lot of other solutions are supposed to catch those things but when you use a modern IDE and it detects potential null inference thanks to the strict language syntax its pretty amazing!

E.g. a great example for JavaScripts over simplification of problems would be in code like this:

function reduce(var a) {
      if(...) {
         a = a - 1;
      } else {
         a = a + 1;
      }
}

If this was Java code we could tell exactly what would happen here… In JavaScript this isn’t quite the case! Lets assume that due to a bug a was somehow a string that is "11" as long as the condition is true (which might be the case in all test cases) this will act like a number. E.g. a will become "10". But in production if the condition becomes false for some reason a would become "111". If a represents something of value (e.g. debt, credit etc.) having an app with this bug in the store could be really painful.

Environment

React native uses the native development environments which means it needs a Mac for iOS development. It also means you do part of the work in the Android IDE, part of it in Xcode and the JavaScript work using a text editor. Its amazing to me that developers are willing to throw away 30 years of IDE evolution for some syntactic candy??? Are we that traumatized by Eclipse? Todays IDE’s are amazing and the fact you can track/debug your entire code via a single IDE is invaluable. The ability we have as a team to instantly see who used what and for what purpose is astounding, I can’t fathom how something like this can be used by a team of more than 2 people especially in a distributed workforce.

What I Liked About JavaScript

The one thing I really like about working with JavaScript is the ease of working with JSON, while in the code below I reduced it significantly almost to the same size its still not as elegant. I’m still not a fan of duck typing or scripting languages but I’d really like to get something like property objects into Codename One and improve the integrated parsing.

Final Word

One of the problems I find with terse programming is that people use it to hide basic concepts so too much happens in an “unspoken” way. This makes terse code as easy to read as a Tweet, unfortunately if you need to express even a moderately complex idea Twitter just doesn’t cut it and that’s a big problem with some of these API’s.

React native has its fans, after all its probably better than PhoneGap which has its own set of limitations. But its still a limited concept standing on the chicken legs of a scripting infrastructure. It has no real advantage when compared to Codename One and has some obvious potential issues.

Java Listing

public class ReactDemo {
    private static final String REQUEST_URL = "https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json";
    private Form current;
    private EncodedImage placeholder;

    public void init(Object context) {
        UIManager.initFirstTheme("/theme");
    }
    
    public void start() {
        if(current != null){
            current.show();
            return;
        }
        placeholder = EncodedImage.createFromImage(Image.createImage(53, 81, 0), false);
        Form react = new Form("React Demo", new BorderLayout());
        react.add(BorderLayout.CENTER, new InfiniteContainer() {
            public Component[] fetchComponents(int index, int amount) {
                try {
                    Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get("movies");
                    Component[] response = new Component[data.size()];
                    int offset = 0;
                    for(Object movie : data) {
                        response[offset] = createMovieEntry(Result.fromContent((Map)movie));
                        offset++;
                    }
                    return response;
                } catch(IOException err) {
                    Dialog.show("Error", "Error during connection: " + err, "OK", null);
                }
                return null;
            }
        });
        react.show();
    }
    
    Component createMovieEntry(Result data) {
        Container entry = BorderLayout.center(
                BoxLayout.encloseY(
                        new SpanLabel(data.getAsString("title"), "Line1"), 
                        new Label(data.getAsString("year"), "Line2"))).
                add(BorderLayout.WEST, 
                        URLImage.createToStorage(placeholder, data.getAsString("id"), 
                                    data.getAsString("posters/thumbnail")));
        return entry;
    } 

    public void stop() {
        current = Display.getInstance().getCurrent();
    }
    
    public void destroy() {
    }
}

Shai Almog

Shai is the co-founder of Codename One, he has been programming professionally for over 20 years and developing in Java since 96. Shai worked for countless industry leaders including Sun Microsystems where he was a part of the original WTK (Wireless Toolkit) team & the co-creator of LWUIT. He worked with most major device operators/manufactures including Nokia, Samsung, Sony Ericson, Sprint, Vodafone, Verizon, NTT DoCoMo etc. Shai is a blogger and writer who often speaks at conventions. He is a Java One rockstar and top rated speaker for JavaZone, corporate conventions from Oracle, IBM and many others.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
vladap
vladap
9 years ago

I’m Java/Scala developer and have a little experience with Javascript. No offence, but the Javascript Promise based code is so clean and is pretty self-explanatory what it does. Promise is well defined reusable abstraction, once developer properly understand how it works (together with anonymous functions) your code is simple to follow. Even Java 7 Future understanding doesn’t help much because of missing composability and support for functions as first-class citizen. My experience is that going with Java mindset to Javascript is painful, or Java programmer just programs Java in Javascript. The same might apply for going to Python, Ruby or… Read more »

Shai Almog
9 years ago
Reply to  vladap

I agree that JavaScript requires a pretty different mindset. My point there is that the indirection is a bit deeper than it should be and it takes a moment to follow since the flow isn’t exactly top to bottom. Miss a curly bracket and you got the flow all wrong. As experienced developers we can understand the concept of promises and it makes sense but even for us the indirection is harder to handle. Synchronicity is hands down, simpler to follow since its always top-down. E.g. error handling which was my chief point there, is just unintuitive and based on… Read more »

Graham Wheeler
Graham Wheeler
9 years ago

The fact that you claimed equivalence between a synchronous, blocking piece of code and the asynchronous non-blocking code pretty much discredits your comparison from the get-go.

Shai Almog
9 years ago
Reply to  Graham Wheeler

Thanks! I think you just clarified to me why JavaScript developers have such a bad knee jerk reaction against my code… You don’t understand it!

Its synchronous but its non-blocking! You will still get events and still do everything, sort of like a queue for futures but listed top/bottom like you would expect the code to look.

We can do that in Java/CodenameOne thanks to a pretty neat trick we have called invoke and block see:
http://www.codenameone.com/blog/callserially-the-edt-invokeandblock-part-1.html
http://www.codenameone.com/blog/callserially-the-edt-invokeandblock-part-2.html

Shai Almog
9 years ago
Reply to  Graham Wheeler

Double posting because apparently including links to invoke and block triggered moderation… Ugh.

Thanks! I think you just clarified to me why JavaScript developers have such a bad knee jerk reaction against my code… You don’t understand it!

Its synchronous but its non-blocking! You will still get events and still do everything, sort of like a queue for futures but listed top/bottom like you would expect the code to look.

We can do that in Java/CodenameOne thanks to a pretty neat trick we have called invoke and block. Please search for that as including the links triggers moderation.

Kent
Kent
9 years ago

Very interesting though that your article title proclaims to compare Java to React Native, but instead drops that comparison right after the first point. Every single one of your arguments boil down to you not really understanding Javascript, Therefore It Must Suck. Pretty much the same argument against Javascript since the beginning of its time, that it’s not this or not that, however none of those arguments actually prove that one language is better than the other, just different. Learn the language and how it operates, then you can form a better opinion about how it might compare to your… Read more »

Shai Almog
9 years ago
Reply to  Kent

Why do people assume to know what I understand/read? I don’t see where the points don’t represent the current Java vs. React development environments? Synchronous code is Java vs. JavaScript style. Second point is more Codename One but that’s still Java. The fact that reload isn’t a benefit unique to JavaScript but available for Java tools is very much a Java benefit. Environment – the fact that React requires a native OS and isn’t WORA (the most core attribute of Java) that’s Java. So I think 4 of the points are clearly Java vs. JavaScript/React. The points about the scripting… Read more »

Back to top button