Reproduced below is the email exchange I have recently had with a reader of my article on Java to EXE conversion:
I have one question about java to exe approach and case when we should use it. I will appreciate if you find time to answer.
Let’s say we have decided to use JNI for some reason in our java project and native library is available for one platform only (windows dll for example). Using it we definitely kill java platform independence since our app will work only on 1 platform. Is there any reason to use java at all in this case? Or it’s better to write all the app in native code?
Thanks in advance for answer!
I’d say that the choice of programming language is influenced by many factors. Portability is just one of them and not necessarily the most important. After all, you can write a fairly portable C++ program using Qt or the like, or you can write it in C# and use Mono on platforms other than Windows.
For instance, if your existing developers are most proficient in Java, it would likely take them less time to produce code of the same quality compared to any other language. But if you will be assembling a new team for the project, you may need to learn more about the job market first.
Then, you may already have some Java code that you could reuse, and there may be open source or commercial libraries, components, or frameworks available for Java the use of which would save you a lot of time and efforts.
It all boils down to cost/benefit analysis in the end. How long will it take to bring that program to market if you write it in Java vs C#/C++/RealBasic/Delphi/whatever? How many developers would you need and what are the associated costs? How expensive will it be to maintain that program? How difficult will it be to grow the engineering team in the future or replace the engineers that will inevitably switch teams, leave the company, retire, or (sic!) get promoted to management? In three years, in five years, in ten years? These are just some of the questions I think you should ask yourself.
Hope this helps,
Thanks a lot for your quick response and explanation. From now on I will look at this case from different side. I think I was mainly confused by earliest Java books where Java was promoted as platform independent language and this was main advantage and reason to choose it instead of existing solutions like C++.
Have a nice day!
To be honest, I find it quite surprising that platform independence is still being marketed/perceived as the only purpose and strength of Java.
I think the remaining major disadvantages inherent to managed-code-centric platforms such as the JVM or .NET compared to C/C++ are bloat, inconsistent latency, and low resistance to reverse engineering.
Java and .NET runtimes are big and their standard libraries are huge, plus different apps may need different versions of those, so users end up with multiple copies. Then, linking is dynamic, so you have to include the entire jars/assemblies with your apps just to be safe. JIT compilers need memory, and the list goes on. The net result is a much bigger disk and memory footprint. Not that much of a problem for an enterprise app that has an entire high-end server at its disposal, or a really fat client coming with hundreds of megabytes of data, but a pretty valid concern for smaller apps targeting consumer PCs, mobile devices, and embedded systems.
.NET used to have Client Profile, but as of version 4.5 that feature is gone. And with Project Jigsaw delayed (at least) until Java 9, Java developers should not expect any breakthroughs soon either. Sounds like nobody cares about the problem? We do.
Our implementation incorporates a unique technology that can reduce the Java bloat to some extent. There are some natural limits going beyond which would break compatibility and make the apps less reliable; hopefully Project Jigsaw will expand those limits.
Bloat also results in slower startup, especially when the app is cold-started from a hard drive or optical media. We counter that by optimizing disk access, with ahead-of-time native compilation driving down the warm startup time and initial response time.
All the Good Things come with a price, and the goodies delivered by automatic memory management are no exception. Stop-the-world garbage collection inevitably causes pauses, flickering, and other effects highly undesirable in many types of applications. The more sophisticated collectors are hard to tune and still do not avoid full collections completely. Real time garbage collectors used to impose a heavy tax on application performance and are only found in commercial Java implementations targeting specific verticals, such as high-speed trading. The developers have no other choice but to pick the lesser evil (that includes choosing whether to get involved with high-speed trading. 🙂 )
That said, we were able to do something about GC pauses, which may be enough for your needs.
Ease of reverse engineering
I discuss this topic at length in my other article, Protect Your Java Code – Through Obfuscation and Beyond, so won’t repeat myself here. Suffices to say that decompiling a native executable produced by our implementation from your jars is not easier than decompiling an equivalent app written in C++.
Do you think Java is a viable alternative to C++ for uni-platform development? Welcome to the comments.