How does Codename One work?
Asked Answered
N

2

51

I'm prospecting alternatives to develop for multiple mobile platforms, and have found Codename One, that uses Java as lingua franca, instead of HTML/CSS/JS or scripting languages.

What I couldn't find is how does it work. Does it bundle a JVM with the application for iOS and Win7, and uses Dalvik in Android? Does it translates source code to native, and do we have access to this source code? Is there other magic, considering they promise "no compromise"? What limitations should I be aware while coding agnostic Java?

Preemptive strike: this is a question about Codename One, not about which cross-platform should I choose or if I should go native or if I should go web.

Newsome answered 17/5, 2012 at 16:34 Comment(0)
K
80

Codename One has an optional SaaS approach so this might (and probably will) change in the future to accommodate improved architectures. Notice that Codename One also provides an option to build offline which means corporations that have policies forbidding such cloud architectures can still use Codename One with some additional overhead/complexity. It also means you can use it for free without ever working with the build servers.

Currently on Android the standard Java code is executed as is. Java 8 syntax is translated using retrolambda for all platforms when its used. This allows it to be compatible to all Android versions as well as other ports.

On iOS Codename One built & open sourced ParparVM which is a very conservative VM. ParparVM features a concurrent (non-blocking) GC and it is written entirely in Java/C. This effectively means that an xcode project is generated and compiled on the build servers so its effectively as if you handcoded a native app and thus "future proof" for changes made by Apple. E.g. with recent 64bit and bitcode changes to iOS builds ParparVM needed no modifications to comply with those changes.

In the past Codename One used XMLVM to generate native code in a very similar way but the XMLVM solution was too generic for the needs of Codename One.

iOS builds are compiled and signed on Macs in the cloud using xcode (the official Apple build tool). This makes them compatible with current/future changes from Apple and allows developers to use Windows/Linux while targeting iOS. You can read more about the compatibility of ParparVM to iOS here.

In the past Codename One supported Windows Phone using a C# translator that relied on XMLVM but it was not an ideal approach. Notice that the XMLVM backend that translates to C# is very different from the one that was formerly used to translates to iOS. Codename One chose to discontinue that old backend as it wasn't as powerful as the new UWP backend and doesn't match Microsofts goals moving forward and focusing on UWP (Universal Windows Platform).

For Windows 10 desktop and Mobile support Codename One uses iKVM to target UWP (Universal Windows Platform) and has open sourced the changes to the original iKVM code in the Codename One github repository.

Notice that UWP builds are done on a Windows 10 machines in the cloud thus allowing developers to use Mac/Linux or older versions of Windows when building native windows apps...

JavaScript build targets which are available on the enterprise level subscribers use TeaVM to do the translation statically. TeaVM provides support for threading using JavaScript by breaking the app down in a rather elaborate way. To support the complex UI Codename One uses the HTML5 Canvas API which allows absolute flexibility for building applications.

For desktop builds Codename One uses javafxpackager, since both Macs and Windows machines are available in the cloud the platform specific nature of javafxpackager is not a problem.

What makes Codename One stand out is the approach it takes to UI where it uses a "lightweight architecture" to allow the UI to work seamlessly across all platforms and be developed almost entirely in Java. It is augmented by the ability to embed "heavyweight" widgets into place among the "lightweights". You can learn more about this in this blog post. Notice that at this time peering is undergoing some improvements and now supports more elaborate usages such as layering.

A lightweight component is written entirely in Java, this allows developers to preview the application accurately in the simulators & GUI builder.

Codename One achieves fast performance by drawing using the native gaming API's of most platforms e.g. OpenGL ES on iOS.

The core technologies behind Codename One are all open source including most of the stuff developed by Codename One itself e.g. ParparVM but also the full library, platform ports, designer tool, device skins etc. You can learn more about using the Codename One sources here.

FYI Shai Almog, the author of this answer, is the CEO of Codename One.

Kory answered 18/5, 2012 at 3:28 Comment(10)
Thanks for your attention, Shai! I think you should put it in your FAQ, we know there's no real magic happening and like to know how the perceived magic works. I'll probably give it a try in evaluation phase!Newsome
There is no evaluation phase for Codename One, our intention is to always have a reasonable free option for developers no strings attached. Since the product is open source its important for us to carry some of that freedom into the SaaS services as well.Kory
Sorry, I expressed myself wrong :P I'm currently only searching for alternatives, then we'll have an evaluation phase, to see how the technologies meet our needs.Newsome
@ShaiAlmog You should've disclosed your affiliation with CodeName One in the Answer itself. Only on reading the answer does one realize this factKalgoorlie
Notice its highlighted in my bio and pretty much everywhere so its not as if I tried to hide. I think it doesn't warrant being part of the answer since the answer should be judged by the facts rather than the bias of the author (so I'm moving that to the bottom but keeping the bold). I think the article is pretty objective.Kory
They are very disingenuous on their web page codenameone.com/compare.html, criticising Xamarin "on most of the devices in the field it would require a 3rd party VM to be installed." which is technically true - Android IS "most of the devices". They don't mention that Xamarin compiles down to native code on iOS in contrast to the Codename VM described above.Pointenoire
We compile to C code which is effectively native. Its a VM in the sense that it "feels" like a VM just like Xamarin compiles directly to native but "feels like" a C# VM. E.g. there is a GC, bound arrays etc. despite being native code. I think we showed a lot of respect to Xamarin in the compare page if a specific sentence seems out of place I'd appreciate if you quote that specific entry.Kory
FYI @AndyDent see my reply here: forums.xamarin.com/discussion/55129/… at Xamarin's own forum. Our comparison page is totally fair as far as I can tellKory
So, this VM is compile time, right? There is no VM running and executing java bytecode. I assume you translate java bytecode to your VM's statements and then you translate it to ObjC/Swift?Stark
Yes but we translate to C which is much faster than Swift/ObjC. We do have a GC written in C and don't use ARC.Kory
J
13

Codename one took very balanced approach to portability. I would like to add a pragmatic comment.

From the user interface side, CN1 does paint all its UI on platform-provided canvas. It tries to mimic platform native look and feel, if you choose it, but has as much success as Swing had with its "native platform look and feel", because native platform constantly changes, and "native l&f" always lacks behind and in most cases feels not quite right.

But, if you choose platform-independent look and feel (which is the sort of the trend today), you are not restricted by Codenameone's default component set set in any way: it's just like Swing with its cross-platform look and feel ("Metal" etc.). Which is good.

From the language side: on iOS it is java compiled to C which is then tied to hand-written Objective-C, and it does not bundle VM, only portability layer. Most important here is the fact that java is compiled to C and not Objective-C, which make it faster then idiomatic Objective-C code, because it does virtual or, more often, direct method invocations instead of slow Objective C message dispatch. Which is good.

It also may seem little faster on Android, because, while using Dalvik/Art, it does not use Android native UI which is bulky compared to CN1's. This can make dynamic UI creation faster in runtime, which is good.

One of the strongest points of CN1 approach is its emulator (implemented over desktop JavaFX canvas) which you use to develop software. Emulator makes use of same UI code and portability APIs as on mobile platforms and lets you use IDE of choice for debugging. It restarts quickly, and edit-compile-run cycle is very sustainable compared to android. Which is good.

Second very strong point (main one!) is open nature of their UI library, all native code and bytecode-to-C translator. If you spend some effort, you can avoid building Android/iOS ports on their farms and untie yourself from their particular revision of product (but not from quite a few value-added services they offer, which are not open source!). Depending on your situation, this may (or may not!) be quite good for you!

Weak point of Codenameone is its less-then-ideal maturity, which means you can easily shoot yourself in the foot using basic UI components, if you use them the way they were not indended to be used. Also it means that its java portability layer is not big enough (and has holes in it) to cover everyone's need, and you may have to use native in some places, and port other pure java libraries, too.

Also, current state of graphics performance is sub-optimal; if you get bunch of text on screen, you'll easily miss 16msec fluid animation/repaint time limit, this can be worked around by double-buffering, but it also has its limits. Luckily, there is still room for optimization in implementation on both main platforms, hopefully they will improve it.

Overall, Codenameone has good niche as a cross-platform framework for several classes of applications; you may find a value in their services, too.

Jochbed answered 12/10, 2015 at 23:35 Comment(2)
How do you implement the double-buffering you mentioned?Unsought
there's some built-in stuff, but i used my own. Idea is that you cache your paint result into image. If you have component which is mostly non-changing but is layed out with complex layout + texts (which means it paints slowly), you paint it into cache image in the paint() method or similar, then paint that image into current graphics. Next time you just paint the image into current graphics. This way you need to manually track when the changes must be re-painted and discard cache image. This approach has slow 1st paint and needs memory,but is ok when you're about to animate,for example.Jochbed

© 2022 - 2024 — McMap. All rights reserved.