6 Reasons Not to Switch to Java 8 Just Yet

DukeXray

Java 8 is awesome. Period. But… after we had the chance to have fun and play around with it, the time has come to quit avoiding the grain of salt. All good things come with a price and in this post I will share the main pain points of Java 8. Make sure you’re aware of these before upgrading and letting go of 7.

1. Parallel Streams can actually slow you down

Java 8 brings the promise of parallelism as one of the most anticipated new features. The .parallelStream() method implements this on collections and streams. It breaks them into subproblems which then run on separate threads for processing, these can go to different cores and then get combined when they’re done. This all happens under the hood using the fork/join framework. Ok, sounds cool, it must speed up operations on large data sets in multi-core environments, right?

No, it can actually make your code run slower if not used right. Some 15% slower on this benchmark we ran, but it could be even worse. Let’s say we’re already running multiple threads and we’re using .parallelStream() in some of them, adding more and more threads to the pool. This could easily turn into more than our cores could handle, and slow everything down due to increased context switching.

The slower benchmark, grouping a collection into different groups (prime / non-prime):

Map<Boolean, List<Integer>> groupByPrimary = numbers
.parallelStream().collect(Collectors.groupingBy(s -> Utility.isPrime(s)));

More slowdowns can occur for other reasons as well. Consider this, let’s say we have multiple tasks to complete and one of them takes much longer than the others for some reason. Breaking it down with .parallelStream() could actually delay the quicker tasks from being finished and the process as a whole. Check out this post by Lukas Krecan for more examples and code samples.

Diagnosis: Parallelism with all its benefits also brings in additional types of problems to consider. When already acting in a multi-threaded environment, keep this in mind and get yourself familiar with what’s going on behind the scenes.

2. The flip-side of Lambda Expressions

Lambdas. Oh, lambdas. We can do pretty much everything we already could without you, but you add so much grace and get rid of boilerplate code so it’s easy to fall in love. Let’s say I rise up in the morning and want to iterate over a list of world cup teams and map their lengths (Fun fact: it sums up to 254):

List lengths = new ArrayList();

for (String countries : Arrays.asList(args)) {
    lengths.add(check(country));
}

Now let’s get functional with a nice lambda:

Stream lengths = countries.stream().map(countries -> check(country));

Baam! That’s super. Although… while mostly seen as a positive thing, adding new elements like lambdas to Java pushes it further away from its original specification. The bytecode is fully OO and with lambdas in the game, the distance between the actual code and runtime grows larger. Read more about the dark side of lambda expression on this post by Tal Weiss.

On the bottom line this all means that what you’re writing and what you’re debugging are two different things. Stack traces grow larger and larger and make it harder to debug your code.

Something simple like adding an empty string to list turns this short stack trace:

at LmbdaMain.check(LmbdaMain.java:19)
at LmbdaMain.main(LmbdaMain.java:34)

Into this:

at LmbdaMain.check(LmbdaMain.java:19)
at LmbdaMain.lambda$0(LmbdaMain.java:37)
at LmbdaMain$$Lambda$1/821270929.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)
at java.util.stream.LongPipeline.sum(LongPipeline.java:396)
at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)
at LmbdaMain.main(LmbdaMain.java:39)

Another issue that lambdas raise has to do with overloading: since lambda arguments have to be cast into something when using them to call a method, and they can be cast to multiple types, it may cause ambiguous calls in some cases. Lukas Eder explains this with code samples right here.

Diagnosis: Just stay aware of this, the traces might be a pain from time to time, but it will not keep us away from them precious lambdas.

3. Default Methods are distracting

Default methods enable a default implementation of a function in the interface itself. This is definitely one of the coolest new features Java 8 brings to the table but it somewhat interferes with the way we used to do things. So why was this introduced anyway? And what not to do with it?

The main motivation behind Default Methods was that if at some point we need to add a method to an existing interface, we could do this without rewriting the implementation. Making it compatible with older versions. For example, take this piece of code from Oracle’s Java Tutorials where they add an ability to specify a timezone:

public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
    return ZoneId.of(zoneString);
} catch (DateTimeException e) {
    System.err.println("Invalid time zone: " + zoneString +
    "; using default time zone instead.");
    return ZoneId.systemDefault();
    }
}

default public ZonedDateTime getZonedDateTime(String zoneString) {
    return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

And that’s it, problem solved. Or is it? Default Methods mix up a bit the separation of interface and implementation. In the wrong hands, As if type hierarchies don’t tend to tangle up on their own, there’s this new creature now that we need to tame. Read more about it on Oleg Shelajev’s post on RebelLabs.

Diagnosis: When you hold a hammer everything looks like a nail, keep in mind to stick to their original use case, evolution of an existing interface when a refactor to introduce a new abstract class doesn’t make sense.

Moving on to some things that are either missing, still with us or not exactly there yet:

4. Wherefore art thou Jigsaw?

Project Jigsaw’s goal is to make Java modular and break the JRE to interoperable components. The motivation behind this first comes from a desire for a better, faster and stronger Java embedded. I’m trying to avoid mentioning the “Internet of Things”, but there I said it. Reduced JAR sizes, performance improvements and increased security are some more of the promises this ambitious project holds.

So where is it? Jigsaw entered Phase 2 just recently, passed the exploratory phase and is now switching gears to a production quality design and implementation, says Mark Reinhold, Oracle’s Chief Java Architect. The project was first planned to be completed in Java 8 and was deferred to Java 9, expected to be one of its flagship new features.

Diagnosis: If this is the main thing that you’re waiting for, Java 9 is due in 2016. In the meantime, take a closer look and maybe even get involved in the Jigsaw-dev mailing list.

5. Issues that are still around

Checked Exceptions

No one likes boilerplate code, that’s one of the reasons why lambdas got so popular. Thinking of boilerplate exceptions, regardless of whether or not you logically need to catch or have something to do with a checked exception, you still need to catch it. Even if it’s something that would never happen, like this exception that will never fire:

try {
    httpConn.setRequestMethod("GET");
} catch (ProtocolException pe) { /* Why don’t you call me anymore? */ }

Primitives

They are still here, and it’s a pain to use them right. The one thing that separates Java from being a pure Object Oriented language, criticized to have no significant performance hit for their removal. None of the new JVM languages has them, just saying.

Operator Overloading

James Gosling, the father of Java, once said in an interview “I left out operator overloading as a fairly personal choice because I had seen too many people abuse it in C++”. Kind of makes sense but there are lots of split opinions around this. Other JVM languages do offer this feature but on the other hand, it could result in code that looks like this:

javascriptEntryPoints <<= (sourceDirectory in Compile)(base =>
    ((base / "assets" ** "*.js") --- (base / "assets" ** "_*")).get
)

An actual line of code from the Scala Play Framework, ahm, I’m a bit dizzy now.

Diagnosis: Are these real problems anyway? We all have our quirks and these are some of Java’s. A surprise might happen in future versions and it will change, but backwards compatibility among other things is keeping them right here with us.

6. Functional Programming – not quite there yet

Functional programming has been possible with Java before, although it is pretty awkward. Java 8 improves on this with lambdas among other things. It’s most welcome but not as huge of a shift that was earlier portrayed. Definitely more elegant than in Java 7 but some bending over backwards is still needed to be truly functional.

One of the most fierce reviews on this matter comes from Pierre-yves Saumont where in a series of posts he takes a close look at the differences between functional programing paradigms and the way to implement them in Java.

So Java or Scala? The adoption of more functional modern paradigms in Java is a sign of approval for Scala who has been playing with lambdas for a while now. Lambdas do make a lot of noise, but there’s a lot more features like traits, lazy evaluation and immutables to name a few, that make quite a difference.

Diagnosis: Don’t be distracted by the lambdas, functional programming is still a hassle in Java 8.

Reference: 6 Reasons Not to Switch to Java 8 Just Yet from our JCG partner Alex Zhitnitsky at the Takipi blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

9 Responses to "6 Reasons Not to Switch to Java 8 Just Yet"

  1. JAmes says:

    Not to mention that many static code analysis tools aren’t yet Java 8 friendly.

  2. Dev says:

    Thanks,

    Somehow I never had a soft corner for lambda expressions. Those are cool and really fun to play with however not sure what exactly it solves. Number of lines of code, is not issue for most of the people. May be scala seems too impressive with one liner but its use is still limited. Not many production deployments use it.

    I would care about features that speed up development and performance instead of cool looking ones.

    In general, I do not really prefer to jump on the bleeding edge until its been tried and tested out. your post helps. Thanks

  3. Yannick Majoros says:

    4/5/6 are just things you are missing. Why should this hold you from using Java 8? They aren’t there in 6 and 7, why stay?

    Points 1/2/3 are about the fact that you can do dumb things. Should it really hold you from using lambdas in intelligent ways?

  4. Andrew says:

    The other point that we do not have a code base with high-quality code examples.

  5. Mike says:

    I guess the title of this post is strictly hyperbole and was just supposed to be eye-catching, because there certainly aren’t 6 reasons here to avoid Java 1.8.

    1) A valid thing to be aware of, but not a reason to avoid Java 1.8
    2) A valid thing to be aware of, but not a reason to avoid Java 1.8

    (if you don’t like lambdas just don’t use them)

    3) I am supposed to avoid Java 1.8 because you don’t like default methods? API developers will probably love default methods. I think default methods are a reason to start using Java 1.8 so they certainly aren’t a reason to avoid Java 1.8.

    (if you don’t like default methods just don’t use them)

    4) Avoid Java 1.8 because it doesn’t include Project Jigsaw? That makes no sense because Java 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, and 1.1 don’t include Project Jigsaw either. Should I avoid them too?

    5) Avoid Java 1.8 because it still has checked exceptions and primitive types and still doesn’t have operator overloading? This makes no sense either for the same reason item 4 didn’t make any sense.

    6) So don’t use Java 1.8 because, yes it has lambdas, but it still isn’t a functional language? Again see item 4.

    How about reasons to use Java 1.8:

    1) New DateTime API, I already love this api.
    2) removal of PermGen
    3) A Base64 encoder in the JDK that isn’t in sun.misc
    4) Better hashing algorithm when lots of collisions (uses tree map instead of linked list)

  6. veggen says:

    These are remarkably bad reasons for not using Java 8.

  7. McPudding says:

    I expect better from JCG, than a post like this.

Leave a Reply


1 × = eight



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close