Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

10 Reasons Why Java Now Rocks More Than Ever: Part 1 – The Java Compiler

When I was away from Java to work on the software of the Eigenharp instruments, I had to develop cross-platform real-time audio software with massive data throughput and constant latency. The development was mainly done in C++ with the Juce library and some glue code in CPython. Given the requirements to develop musical performance software, these technology choices were inevitable but they did make me realize how many things I had taken for granted in the Java ecosystem.

But could I think of ten things that make Java rock? It wasn’t too terribly hard to prepare a list of 10 aspects of Java that maybe we take for granted. You’re most certainly aware of all these, but saying them out loud can serve as a nice feel-good moment about your platform of choice when times get tricky during development. Here are my favorite things about Java:

  1. The Java Compiler
  2. The Core API
  3. Open-Source
  4. The Java Memory Model
  5. High-Performance JVM
  6. Bytecode
  7. Intelligent IDEs
  8. Profiling Tools
  9. Backwards Compatibility
  10. Maturity With Innovation

Let’s now take a look at #1, the Java Compiler, in more detail and we’ll cover the other reasons in follow-up posts.

What rocks about the Java Compiler

The Java compiler is probably the first component of the platform that you encounter as a developer. You’ll have to use it to compile your first ‘hello world’-type examples and when using the Java language, it’s your gateway towards turning your source code into an executable format.

Obviously, the Java compiler can’t exist without bytecode. Apart from the many benefits of bytecode itself, which we’ll cover in detail later, this intermediate representation also allows the JIT (Just In Time compiler) to kick in at runtime.

The JVM’s JITting like a champ

You might think that the JIT is just a performance improvement to leave interpreters in the dust and rival with native performance speeds, but it goes much further than that. When compiling straight to native, like with C++, you have to deal with static optimization that has to be decided upon at compilation-time. Having to enable profiling up front drastically differentiates builds with run-time inspection capabilities from those that are targeted at distribution. The ahead-of-time optimization shifts around many instructions, moving the compiled form sometimes very far away from what you expressed in your source code, sometimes even introducing new problems that have no clear relation to logic that you’ve written.

It’s quite common practice to actually just step through the optimization levels with manual testing of the produced binaries, hoping to find one that works. Without deep understanding of the compiler internals, it’s often impossible to predict how the profilers will change the execution of your code and which optimization levels will work or not. Sometimes, the only way to identify why some features stopped working is to step backwards in time through changesets, since there’s no relationship anymore between your code and problems that are manifested. As projects grow over time, it’s quite common to be stuck in less aggressive optimization levels since it has become almost impossible to determine why higher optimizations introduce problems.

All this is only worsened by the ‘black box’ nature of the optimization level switches. For example, this is everything you’ll find about optimization in the clang manual, good luck figuring out what exactly is going on:

Code Generation Options
  -O0 -O1 -O2 -Os -Oz -O3 -Ofast -O4
    Specify which optimization level to use.  -O0 means "no
    optimization": this level compiles the fastest and generates the
    most debuggable code.  -O2 is a moderate level of optimization
    which enables most optimizations.  -Os is like -O2 with extra
    optimizations to reduce code size.  -Oz is like -Os (and thus -O2),
    but reduces code size further.  -O3 is like -O2, except that it
    enables optimizations that take longer to perform or that may
    generate larger code (in an attempt to make the program run
    faster).  -Ofast enables all the optimizations from -O3 along with
    other aggressive optimizations that may violate strict compliance
    with language standards. On supported platforms, -O4 enables link-
    time optimization; object files are stored in the LLVM bitcode file
    format and whole program optimization is done at link time. -O1 is
    somewhere between -O0 and -O2.

Focus on your code, not on the compiler architecture

Since the Java compiler only has to transform source code into bytecode, it’s very simple to operate the javac command itself. Usually, all you have to be concerned about is providing the correct classpath information, deciding about the VM version compatibility and tell it where you want the class files to be placed, a total of three different compiler options: -classpath, -target and -d.

With C++ this is vastly more complex, here’s an example of a relatively simple g++ compiler invocation. Granted there are some project-specific define flags in there, as well as -I flags for the header inclusion paths, which could be compared to the javac classpath. These are all standard practice in C++ and often the only way to modularize your builds or get platform independence.

g++-4.2 -o tmp/obj/eigend-gpl/piagent/src/pia_buffer.os -c -arch i386
  -DDEBUG_DATA_ATOMICITY_DISABLED
  -DPI_PREFIX=\"/usr/pi/Python.framework/Versions/2.5\"
  -mmacosx-version-min=10.6 -ggdb -Werror -Wall -Wno-deprecated-declarations
  -Wno-format -O4 -fmessage-length=0 -falign-loops=16 -msse3 -DALIGN_16
  -DBUILDING_PIA -fvisibility=hidden -fPIC -Isteinberg -Ieigend-gpl/steinberg
  -Ieigend-gpl -I. -I/usr/pi/Python.framework/Versions/2.5/include/python2.5
  -Itmp/exp
  eigend-gpl/piagent/src/pia_buffer.cpp

The main problem though is that all this is different for each compiler that you use. G++ is different from Clang, which is different from the Intel C++ compiler, which is again different from the Visual Studio C++ compiler, … They all have their own names for common command-line switches, support a different version or subset of the C++ standard, and have their own flags to tune the compiler features.

If you really want to get the best performance, you’ll have to wade through hundreds of options for each compiler, sometimes requiring very low-level knowledge of the target hardware. Worse still is that you have to do all this up front and hope that it will work on all the platforms or processor architectures that you want to support–all without any real visibility to track down what went wrong when your program fails. I dreaded every release since it’s a major undertaking to figure out why your software crashes from customer reports. On a few occasions we literally had to track down the exact same processor architecture to be able to reproduce the problem and experiment with compiler options to make the binary stable.

No static nor dynamic linking, just run-time linking

When you produce native binaries, you have the option to decide how you’re going to link with libraries or modules of your own. Static linking packages everything into a single executable but prevents you from independently updating the libraries and can generate very large binaries. It has the advantage to be easier to distribute and to get none of the problems that are associated with dynamic linking. In practice though, it’s impractical for larger products to ship a single statically-linked executable. Sooner or later you will have to deal with dynamic linking, even if it’s just to split your build up or to deal with third-party libraries.

Dynamic linking is complex and quite troublesome. Independently from the visibility of code inside your sources (private, public, …) you have to explicitly compile parts of your API so that the appropriate symbols are exported by the dynamic library that you create. On the other hand, you’ll have to declare that you want to import these symbols into the code that actually uses the library. If you use the same header files for the library and the client, as most people do, you’ll have to parametrize the declaration of your API based on the compilation phase you’re in.  Additionally, the exact semantics of how all this works is different on MacOSX, Linux and Windows, you’ll be ripping your hair out and littering your code with macros to handle all of this, certainly if you’re concerned with maintaining a common codebase that compiles to different platforms. In no time, you’ll see that linking, an actual compiler concern, has bled into every declaration of your source code and sometimes even dictates the actual class structure you end up using.

Even with all this in place, there are many complications with shared libraries, particularly on Windows platforms, where every user has had to deal with DLL version incompatibilities. While later versions of Windows are less prone to this, usually your binary is bound to a particular version of a DLL and some seemingly minor changes to an API can make the dynamic linking incompatible. Some ways around this are to privately bundle the DLLs with your application, if you’re allowed to distribute them, or to explicitly dynamically load them at runtime. The latter requires particular attention to linking and symbol resolution inside your application, while you really should not have to be concerned with any of this.

Java bypasses all of this by deferring linking to run-time. Everything is dynamic and since the symbols are exported through bytecode while being isolated with packages, you rarely have to be concerned with the linking phase at all. If needed, you can still dynamically load classes or methods, but that’s very uncommon. The bytecode symbol representation is very stable and as versions of classes evolve, your older code will continue run without problems unless the library author purposely changes the API.

Next up

This was Java’s Rockin’ Reason One … please leave comments below or tweet @gbevin to connect with me. Next up will be The Core API and has even more profound implications … stay tuned!

 

  • Jesus Bejarano

    Only reason why Java Rocks…Clojure.

  • nbevans

    The Java Compiler: no structs/value-types, no lambdas, to start naming its flaws.
    The Core API: hideously overcomplicated and fragmented.
    Open-Source: are you kidding me? Oracle’s Java is anything but. They are basically using Java to patent troll out of anybody that dares use it these days. See: Google’s Davlik Android VM.
    The Java Memory Model: you mean all that hideous double locking required to make a thread-safe singleton? Whereas the .NET CLR needs none of it because it has a strict memory model?
    High-Performance VM: not really. Lack of struct/value-types puts paid to that. Compare Scala vs F# performance. No contest.
    Bytecode: um, okay? Feels like you’re clutching at straws now. Basically all non-native languages use bytecode these days.
    Intelligent IDEs: great, but none of them as intelligent as Visual Studio with Resharper.
    Profiling Tools: straw clutching. These are not unique to Java.
    Backwards Compatibility: pass.
    Maturity With Innovation: what does this even mean? Is it a way to justify why it still doesn’t have lambdas? And why the ones it is receiving in vNext are inherently broken?

  • arhan

    “In telligent IDEs: great, but none of them as intelligent as Visual Studio with Resharper”

    IntelliJ IDEA is created by the same company who created R#. Just in case if you didn’t know.

  • nbevans

    I did :) Doesn’t mean it’s better than the VS+R# combination though…

  • arhan

    Doesn’t mean the opposite either.

    You have made a subjective statement with no arguments. You’re free to do so. I’m free to say that you’re wrong without additional arguments either.

  • bob

    hmm… I am missing the “now more than ever” part.. what makes this more relevant to current times than say.. 10 years ago.. nothing you mention is recent, and most of the arguments may well be from Java 1.2.

    What makes this article useful? Why should a developer choose Java? Are you presenting the shortcomings of Java? Are you comparing with other languages? Otherwise, sorry, but I am tempted to say “good story bro..”.

  • nbevans

    Agreed. The premise of this article is very shaky indeed. One would hope that no language has “regressed” since 10 years ago.

  • AnonWins

    This is a sad attempt to convince people that the horribly exploited and bloated framework is still awesome.

    I suggest that you just look for an alternative and leave this academic language to die please.

  • PAUL Miller

    Lets not forget that bytecode enables easy decompiling back to source code. Look at apktool for examples. Also, bytecode implies interpreted. I’d rather be using g++ and know that my code is natively executed on the chip rather than going through an intermediate scripting language (JVM) to execute the code, as this ads to the latency. Don’t get me started on the Oracle debacle that has moved millions of programmers away from Java due to their stance on ownership and distribution of java code, libraries, and usability of java in general. Java is not open to use, its closed at this point, and anyone distributing code with it is done at their own peril. As you become larger, you become a direct target by Oracle.

  • njs

    I’d rather work with Java Core API for next 50 years, then a month with C/C++ API.

  • gbevin

    Guess you’ll have to wait for the next ones in the series :-)

  • nbevans

    Me too. Everything’s relative. Or maybe, putting up with a month of pain (of C/C++) to then have a trouble free remainder of life where both C and Java can be entirely avoided?

  • gbevin

    Since now, more than ever, Java is still relevant, still has all these things going for it and … is still moving forward to make constant great improvements. This is to me really about all those things combined, not every single one of them separate. Sure, you’ll be able to pick holes into everything I’ll write about and find negatives to each feature I mention. I just didn’t realize how good they were until I had to leave them behind.

  • gbevin

    That depends on the application. Many applications don’t need this smaller latency, some do. This is exactly why the real-time audio software I worked on that requires constantly latency, was written in C++ … and also how I was reminded at how many Java features I had taken for granted over the years.

  • gbevin

    about openness: http://openjdk.java.net/

  • Benjamin Gruenbaum

    That’s this thing. All these things made Java great 10 years ago. Now _every_ language that’s not static has a JIT, JavaScript has jits, Python has jits, C# has jits, lua has jits. Having a JIT is not an “impressive Java feature”. I completely agree with nbevans.

  • gbevin

    Sure, but C hasn’t, C++ hasn’t, Objective-C hasn’t, … for other features that I’ll write about this list will be totally different. To me, at the end, Java as a platform is still the only one checking all the dots, dotting all the i’s and still continuously being improved.

  • Nick

    Awesome article! As a newcomer to Java Web Development, I find I have the most difficulty with simply configuring the JVM for production deployments, so thanks for the information.

  • http://thomasgeraghty.wordpress.com/ johnnycbadde

    Other awesome stuff about VS and C#:

    * Actually has a package manager and it’s really good. Third-party package management is serious pain in Java.
    * Code Contracts from MS Research allow strict precondition checks at compile-time. Guava and one of the Apache common libs does these too but at runtime so there’s a perf hit.
    * Xamarin brings the mono runtime to iOS, Android, Linux and OS X. As nbevans said, Google brought the JVM to Android and just got sued.
    * Delegates, Lambdas, LINC and Properties. Yeah these are always mentioned, and there’s a reason for that.

    If you throw enough third-party libs at Java it can feel pretty good to write in. You can say the same for JavaScript and Perl but it doesn’t make them good languages. Java 8 is gonna be the last nail in the coffin I think, most of it sounds horrible.
    Nearly every post I see defending Java is written by people who barely program in other languages. Maybe you guys should abstract that and create a ShakyJavaArgumentFactory? :)

  • Rhuidean

    Java is good for some things, not so great for others. As mentioned already, it lacks many features that are useful in the high-performance areas in which C++ is used; structs, manual memory management, stack-allocated objects, direct compilation.

    I work in the mobile gaming space and have found writing games in Java for Android to be a frustrating experience; having to code around garbage collection pauses by using object pools and other measures is painful and makes me yearn for the control that C++ grants.

    At the same time, Java has huge advantages over C++, not least of which is its comprehensive library and tool support as well as its cross-platform capabilities. As with every article I’ve read that tries to push one language or tool over another, I recommend learning as many as you can; all have their uses.

  • Hugo Firth

    Java has its problems. However I *ABSOLUTELY* call BS on any assertion as to the superiority of Visual Studio. What possessed them to make VS 2012 & 2010 incompatible? Severe brain damage is the only plausible answer that comes to mind. I spent hours and hours crossing that particular hurdle on a recent project where a bunch of students had used both versions.

    IntelliJ IDEA (professional) is easier to use, more extensible, cross platform and just as powerful. The moment Jetbrains finish their, long promised, C++ IDE I’m done with MS for good.

    /rant – Sorry – I really needed to get that off my chest :)

  • Hugo Firth

    It is – so I guess it does.

  • nbevans

    That’s fine. Everyone has different IDE tastes. I was calling out the “Intelligent IDEs” point in the article. Most popular languages have what can be considered an “intelligent IDE” these days. I assume the article author was referring to built-in refactoring tools etc. Find an IDE that doesn’t have any of that these days?

  • Maycon Oliveira

    Realy nice article.

    But after almost 10 years using java I still think that the language have 2 major problems to solve:

    1 – A lot of boilerplate code for simple things.

    – OK. The IDE can do the code automation, but, after a while create get and setters is really annoying.

    – Java 7 solved some problems with new classes like ‘Files’, and with new features like ‘try with resources’. They need to continue to make these facility features.

    2 – EAR and WAR deployment could be partial. Today I need to deploy the whole application just to get a new field on a page. I know that i could use some framework to solve this, but im expecting a native solution.

    PS: Sorry for my terrible english.

    Nevertheless i agree that java rocks!

  • Max Thomas

    The whole Android thing was years ago and has been sorted out, so that’s not a good argument. And Mono just flat out sucks to put it out there. Half of the time most programs won’t run provided they don’t use any native hooks (in which cases most highly optimized .NET apps will use them). Not to mention that Lambada and Delegates will be shipped with Java 8.

    And as for the factory thing, I’ll admit that I hate factories. Luckily I rarely encounter them and I never write any factories in my code (because they suck).

  • http://nikdudnik.com Nek

    Then the title is misleading and should be “Why Java now rocks more than ever compared to C/C++/Objective-C”. Which would be rather fun title ’cause all those techs are pretty old.

  • http://nikdudnik.com Nek

    …but but isn’t it the reason why JVM not Java rocks?

  • http://nikdudnik.com Nek

    It’s totally corp/enterprise technology.

    It’s popular as a learning tool in academic circles but it’s not academic in a sense of being something strictly formalised and mathematical. I hope Java dies as soon as possible.

  • http://thomasgeraghty.wordpress.com/ johnnycbadde

    >The whole Android thing was years ago and has been sorted out, so that’s not a good argument.
    Last time I checked 2012 was only one year ago.
    https://en.wikipedia.org/wiki/Oracle_v._Google
    >Half of the time most programs won’t run provided they don’t use any native hooks
    If you’re writing for multi platform and using native hooks you are an idiot, what kind of argument is that?!
    >Not to mention that Lambada and Delegates will be shipped with Java 8.
    And they look really horrible. I’ve looked at plenty of Java 8 stuff and most of it is just people with horrible jobs getting super excited that they’ll get an opportunity to rewrite massive amount of code to make it less readable and maintainable.
    A good language starts with a good syntax. If Oracle really cared they’d break backwards compatibility and focus on getting it right this time. Most serious Java operations aren’t even running 7 anyways! Do yourself a favor and go learn Clojure or Scala which both have communities where people care because nobodies going to be writing anything substantial in Java after a few years.

  • ASSHOLE

    structs/value-types are a flaw – why would java have a fail like that? That’s for shit like .net.

    You clearly don’t know what you’re talking about. VS is crap compared to IntelliJ only morons like you think otherwise.

    Keep building EXEs in DLL hell you idiot.

  • arhan

    dude, you don’t even write LINQ properly :)

    >>Third-party package management is serious pain in Java.
    Awwyeah? Tell me more about it.

    >>Code Contracts

    Static code checks can be applied to any language. DbC was built into Eiffel ages ago

    >>Java 8 is gonna be the last nail in the coffin I think, most of it sounds horrible.

    I’m all ears and waiting for a blog post from you that would explain how bad lambdas are for Java and how everyone will suffer from it. I can write terrible code without lamdas too, so who cares. If you think that lamdas are all about syntax in Java, then you just didn’t spend enough time figuring it out.. Well, why would you? :)

    >>> Nearly every post I see defending Java is written by people who barely program in other languages.

    I hope you checked Geert’s profile before compiling this statement. Go do your homework.

  • http://thomasgeraghty.wordpress.com/ johnnycbadde

    I didn’t check it out because it’s the quality of your post that matters, not who you are, so I’ll excuse myself from any homework thank you very much.
    I’ll also excuse myself from commenting further because you come across as quite rude. I apologise if that wasn’t your intent but next time you want a serious debate on the merits of a language try to make some proper arguments instead of implying the other party “didn’t spend enough time figuring it out”.

  • arhan

    Well, that is what I would expect from you – proper arguments. I do acknowledge all the benefits of .NET platform (LINQ et al – I would love to have that in Java, though it is never going to happen) compared to Java, but it seems you don’t want to try to add weight to the doubtful arguments you brought above, i.e. package management and VS superiority.

    BTW, bringing an IDE into the language debate isn’t very bright.

  • nbevans

    I don’t think you’re qualified to even be reading this article, let alone commenting on it. Run along now little whipper…

  • redbrain

    I can’t bite my tounge much longer. If you you really consider oh using G++ and Clang vs SunCC and ICC oh its just so complicated as a reason to only use java you must be retarded. Java has HORRIBLE problems across compiler versions!!!!

    Oracle Java 1.5/1.6/1.7/1.8?
    vs
    OpenJDK …
    IceTea
    GCJ

    Fucking hell they all work differently and have their own inconsistencies! There are TONNES of used java compilers out there each with their own compiler specifics.

    Java is hellaslow runtime linking in projects like hadoop create stupidness of oh i am loading 130+ jars into memory at load time and its takes 1 G of memory just to do something as basic as start a socket and a logger. over the course of about 2 minuites.

    Not to mention that java really does like to over-complicate things look at maven. No you can’t just say i want groovy and my sources are in this dir and my tests are in this dir. No i need to write about 300 lines of xml which is almost not debuggable at all and to top it off we will add ssomething retarded like oh build hooks i do a mvn clean compile and look i’ll send you an email on your laptop to say if it completed who the flying fuck balls though that was a good idea. I mean seriously whats the point of jenkins then?

    Java is so disgusting that its just compounded by the fact its swamped with 90% of the worlds most substandard programmers and is enforced by the fact its the only thing in university that is taught these days.

    Java has destroyed the love and excitement that software development used to give people. there is Jar for anything under the sun and each jar is up its own arse with convention its completely forgot about the problem at hand.

    Not only this but every project out there wants to develop out ‘nice’ object models and forget where things should be scaleable and where and how things should be run in production!

    So developers get so wound up talking about factories that they forget yeah for this to be scale able i need some kind of prevalance and sockets here and shit here then it turns into a disgusting beast of shit. Look at hadoop!

    I could go on for days but if your seriously saying that Jit’s are better because it offloads the build time static analysis to runtime you must be meantally retarded you literly know nothing about Compilers! And the mere fact you are saying shit like this and people are loving you for it shows how broken the java community is.

    Let Java die for goodness sake its the worst piece of technology in software engineering. Suffering from 15+ years of bad design and the same goes for C++.

    C Python and Go are the only sensible technologies these days!

  • remmelt

    As for the boilerplate, try Lombok. Our business objects are now just the fields and a bunch of annotations. Very clean. Java8 will also remove lots of boilerplate once you get the hang of lambdas.

  • http://tataryn.net/ Craig Tataryn

    @arhat have you checked out Slick? Although not Java, very nice LINQ-like DSL for Scala http://slick.typesafe.com/

  • arhan

    Craig, you answered it yourself. I wan’t the same thing in Java. Not in Scala :)

  • Prashant

    Completely agree with you Geert.

  • Seth @ FBT

    Hey Geert, Thanks a lot for sharing this post on why Java rocks. I too belive that Java absolutely rocks even though it has some vulnerability issues. Looking forward to the second part. In the meanwhile I think your readers can find more sources on Java at: http://www.fireboxtraining.com/java

  • julien

    Well I was expecting something more consistant criticism, but if it is to quote some MS trashable crap …

  • vramirez122000

    The CLR is great, C# is great. Both in many ways superior to Java. It’s too bad it’s Windows only.