8

A fat binary is a binary that can be run on more than one architecture. Basically, it consists of a program compiled twice, once for each architecture, then written to the same file. Probably the best known example is Apple's "universal" binaries, allowing programs to be compiled for both Intel and Power PC architectures, and run from the same executable file.

This was never an issue for Java, since Java runs on the JVM, allowing it to be run from any JVM-supported computer. However, Android is now very popular, and Android's VM (Dalvik), is not compatible with the JVM. Is there some way of compiling the code twice, and creating a class file that can be executed by both the JVM and Dalvik? And if not, is this even possible?

MvG
  • 57,380
  • 22
  • 148
  • 276
  • 5
    If you distributed a Java + Dalvik class file on Android, there is no way in hell I would use your app. Mobile applications should be tiny and include as little useless data as possible. – cdhowie Aug 01 '12 at 18:52
  • 1
    @cdhowie This technique works pretty well for hardware architectures. The binary doesn't take up as much space as other resources your app uses, like images for example. I guess it depends on the app. –  Aug 01 '12 at 18:54
  • 2
    Is this going to be shown as evidence in the trial? – Flexo Aug 01 '12 at 18:54
  • The Sun/Oracle JVM will not recognize a .class file that contains irrelevant "junk", unless you can somehow disguise it as string data or whatnot. Android's developers could presumably modify the Dalvik VM to accept the hybrid file, but it would be pretty ugly. – Hot Licks Aug 01 '12 at 19:02
  • 1
    (To my knowledge, nothing such as you describe currently exists.) – Hot Licks Aug 01 '12 at 19:03
  • The solution is probably to run an Android VM on the target hardware. – Marvo Aug 01 '12 at 19:05
  • @HotLicks I don't think either team is going to care enough to make such significant changes to their projects. It sounds like it's not possible. –  Aug 01 '12 at 19:11
  • @Marvo You're right, but running Dalvik on your computer is unfortunately [not yet supported](http://stackoverflow.com/questions/3542268/how-can-i-compile-dalvik-to-run-it-locally-on-linux). –  Aug 01 '12 at 19:12
  • Dalvik was specially designed with constrained resources in mind. Having a fat binary would be a complete desecration of that goal, wouldn't it? I don't see why there would be any incentive to support such a thing today. In the future, when Dalvik will be nothing but a legacy format, this may happen, though. – Marko Topolnik Aug 01 '12 at 20:07
  • @HotLicks: actually, there is a way to pack "junk" into a `.class` file, and it's called [attributes](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7). That's how annotations are stored and some debug information. You could theoretically put any amount of junk in there and the VM is *required* to ignore unknown attributes (for example you could have class files with annotations running on a pre-Java-5 VM, as long as the class files didn't claim to require Java 5). – Joachim Sauer Aug 01 '12 at 20:18
  • What's the point? You'll double the size of the "binary", to what end? The build process can trivially build both apps. What specifically are you trying to avoid? It's only compiled once, btw, then converted to Dalvik. – Dave Newton Aug 01 '12 at 20:21
  • @DaveNewton Android is being used more in increasingly different environments. Having an executable that works unmodified between your computer and one of the many devices that Android runs on could be hugely beneficial. Also, I just referred to the conversion between Java bytecode and Dalvik bytecode as "compiling", but I suppose that's not completely accurate. –  Aug 01 '12 at 20:31
  • @Hassan Hugely beneficial for who? It wouldn't be beneficial for the vast majority of people that install Android apps via a store. I only *barely* see any real benefit to this, and the cost in terms of size far outweighs it. Not to mention that anything outside of core Java (e.g., nothing with a GUI) would be portable anyway. Still not clear to me where the win is. – Dave Newton Aug 01 '12 at 20:35
  • I mostly agree, but I think that in the near future there will be more of a need for it. I'm mostly thinking about Android being run on laptops/desktops, which is already starting to happen. –  Aug 01 '12 at 20:41
  • It would be fairly straight-forward to include both .class and Dalvik files in the Android "package" (forgetting what it's called at the moment), enabling it to be installed on either phone or desktop. The unneeded version would be discarded during the install process. No need to pack the two files together. – Hot Licks Aug 01 '12 at 22:22
  • @Hassan But when it's run on laptops/nettops, it's the only OS--still no need for a dual binary. I still think this is a solution looking for a problem. – Dave Newton Aug 02 '12 at 17:42
  • "I still think this is a solution looking for a problem." <- I 100% agree with you there, but I don't think that's such a bad thing. –  Aug 02 '12 at 17:43
  • @HotLicks That may be the Java way of doing it. Thanks! –  Aug 02 '12 at 17:46
  • It should be noted that Java applications are not shipped as bare .class files, but as JAR files. And the Android "package" (whatever it's called) is, IIRC, a variant on a JAR file. Should be a relatively straight-forward task to create a single JAR file that could handle both architectures, with both the .class and Dalvik files, but only one copy of images, text files, and the like. – Hot Licks Aug 02 '12 at 19:14

1 Answers1

5

Answer: Yes.

You can create a universal .jar file that contains both JVM-friendly .class files and an Android-friendly classes.dex file. The dx tool included in the Android SDK will emit such files if you use the --keep-classes command line option.

Note that although such .jar files can be consumed on JVMs and on Android, packaging code in this way is not very useful. Android applications are packaged as .apk files include an Android manifest XML file. They use Android-specific APIs like Activity that are not available on the JVM.

A universal .jar file would mostly be useful if you wanted to do runtime class loading of a library.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128