A method to reduce binary size, results in java 8 desktop app in less thann 5MB

274 views
Skip to first unread message

Shashaank Tulsyan

unread,
Apr 7, 2015, 4:19:33 AM4/7/15
to rob...@googlegroups.com
Hi,

I am extremely excited to share something unimaginable.
Inspired by the approach robo vm follows for iOS, I tried to create custom vm distribution targetting desktop platform based on Oracle JVM.

The result :
Java 8 FX app in less than 5MB !!!!!

Don't believe me, just see it for yourself :
https://github.com/s...0application.7z
Note1 : This app has been packaged using javafx packer and for some reason will not run on 32bit OS.
Note2 : This app does nothing, it will just show a javafx window, with a button that does nothing.

For me having a desktop java app, along with java runtime, in less than 5MB is a big deal.
I would like to share how I achieved this.

I used following this to my advantage :
  • Java classes are loaded in lazy fashion. So even if there is dependency to a class because of an import statement, the class itself will not be loaded until it is required !
  • Xbootclasspath can be used to change runtime classes. So instead of using heavy rt.jar and other heavy jar files we can use a highly stripped down runtime which has exactly those classes which we require. (Inspired by robovm, retrolamba and proguard)
  • So now the last part remains, is how to find which classes are actually used. For this purpose I don't use anything related to javavm. Instead I use kernel level virtual filesystems!!! This way I am also able to remove native libraries (dlls) and resources (configuration files etc) which are not required.
  • Finally these options can be set very easily in configuration file of a native java application created using javafx packager. Only 2 lines need to be added to do the trick.


Here I am not going to share the details.
But I am here to share the excitement. This is really insanely small !
A Javafx application in 5MB!! That is crazy small.

What do you guys think?
BTW if you are interested in knowing the exact steps, check out https://github.com/s...nktulsyan/spyfs .

Thanks
Shashank :D :D :D

Niklas Therning

unread,
Apr 7, 2015, 4:38:23 AM4/7/15
to Shashaank Tulsyan, rob...@googlegroups.com
Interesting approach! :-) We're working on improving the stripping done by RoboVM to reduce file sizes. Recording which classes are actually used at runtime is something we could do easily by patching RoboVM slightly. We're currently looking into an approach which is much less aggressive, using static analyses. One nice advantage with the dynamic approach is no special handling is required for classes loaded via reflection. Maybe we could use this for generating forceLinkClasses patterns automatically for users. The drawback is of course that you have to make sure you touch all codepaths of your app when recording.

Thanks for the info and links. We'll see where we end up eventually...


--
You received this message because you are subscribed to the Google Groups "RoboVM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robovm+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jeffrey Backes

unread,
Apr 22, 2015, 6:54:08 PM4/22/15
to rob...@googlegroups.com
My only concern is that with this wouldn't I'd need 100% code coverage to make sure I have exercised every possible code path?

jeff

JavaRoboVM

unread,
May 9, 2015, 8:37:16 AM5/9/15
to rob...@googlegroups.com, shashaan...@gmail.com
proguard can output useless classes,maybe it can help it.
I don't if it is license reason .


在 2015年4月7日星期二 UTC+8下午4:38:23,Niklas Therning写道:

Christopher Graham

unread,
May 9, 2015, 10:38:59 AM5/9/15
to rob...@googlegroups.com, shashaan...@gmail.com

"One nice advantage with the dynamic approach is no special handling is required for classes loaded via reflection. Maybe we could use this for generating forceLinkClasses patterns automatically for users."


That'd be great - AFAIK, at least in the case of Clojure coding, it looks as though this is the only practical - and severely bloating - option:


<forceLinkClasses>

    <pattern>clojure.**</pattern>

    <pattern>bar.foo.robovmapp4.core__init</pattern>

  </forceLinkClasses>

Mario Zechner

unread,
May 9, 2015, 4:39:25 PM5/9/15
to rob...@googlegroups.com
Clojure's dynamic nature makes it hard to determine a static tree of dependencies. Groovy has the same problem.

It appears that the Clojure team is looking into a form of AOT compilation: http://clojure.org/compilation Maybe this can be applied to your use case?

People running Clojure on Android also appear to use Proguard:https://www.deepbluelambda.org/programming/clojure/creating-android-applications-with-clojure--slimming-things-down-with-proguard

Maybe you can try modifying your force-link configuration to only include the namespaces you need? I'm afraid I only know a little bit of Lisp, and nothing about Clojure's mechanics.

John Girvin

unread,
May 19, 2015, 5:53:02 PM5/19/15
to rob...@googlegroups.com
Just for fun, I built a simple libGDX game (just display a map and a sprite) for OSX desktop (for convenience), packed it with packr -minimizejre "soft", then used the techniques described by the OP with the opensnoop tool to trace the classes it loaded.

The rt.jar minimised by packr was 26.7Mb and contained 18685 classes, but tracing showed only 762 actually being loaded. A new rt.jar containing only the loaded classes was 4.6Mb.

For reference, the stripped OSX .app was 35Mb on disk for little more than "Hello World", and a JET Windows .exe was still 15Mb. A robovm default 1.2 built .app weighed in at 18Mb (6.7Mb IPA) but I don't know how many "rt" classes were included.

Makes me want robovm for desktop libGDX though :)

Edu García

unread,
May 19, 2015, 11:12:52 PM5/19/15
to rob...@googlegroups.com
I've been trying to do the same for a long while, and basically the main problem is LibGDXs reliance on AWT classes (for the LWJGL backend). LWJGL3 uses GLFW instead of AWT (well, they can use AWT but I think only GLFW is done right now) so maybe a LibGDX using LWJGL3 might work woth RoboVM. Somebody implemented that here, in case you want to try running it through RoboVM (I haven't done it yet so I'm not sure if you'll find some other roadblock): http://www.badlogicgames.com/forum/viewtopic.php?f=17&t=18280

I'm not so worried about size (well, it's a very nice improvement), but this also brings the possibility of using native C libraries with good performance. As a test, I made bindings for LibTCOD with JNA and with RoboVM. Obviously, JNA is not JNI and I'm not sure if the overhead is going to improve tenfold, but with RoboVM I got the same performance as with C, while JNA was dead slow (more than an order of magnitude slower)

So if you do test, please post results :)

Jan Blok

unread,
May 20, 2015, 2:01:59 AM5/20/15
to rob...@googlegroups.com
You actually measured the same performance as c code? Niklas posted on the group a while ago that mojang did tests en concluded with half the speed of hotspot which is ~10% slower than c code.

Jan Blok

unread,
May 20, 2015, 2:05:24 AM5/20/15
to rob...@googlegroups.com

Jan Blok

unread,
May 20, 2015, 2:08:31 AM5/20/15
to rob...@googlegroups.com

Edu García

unread,
May 20, 2015, 7:03:16 AM5/20/15
to rob...@googlegroups.com
No, I didn't take precise measurements. My simple test was running the same C & Java code using LibTCOD (their sample) and checking the FPS. IIRC I got the same or near the same. In any case, FPS with JNA was terrible and unplayable, so even if get half of C performance, it will still be heaps better.

I'll check that post you mention, anyway. I'm really curious about RoboVM performance (I've already done some posts regarding that on this mailing list, a while ago :D)

Shashaank Tulsyan

unread,
May 20, 2015, 7:33:52 AM5/20/15
to rob...@googlegroups.com
:D
Good to see people catching up with the concept of thin VMs.
Lately even I was contemplating of having android-vm (api) based desktop apps (also using libgdx if you are into game development). That would be more cross platform than javafx or what oracle has been struggling to achieve.
It would be tricky to achieve write once run anywhere in this fragmented scenario that we have today.
I see great potential in robo vm.
A little thinning of the runtime + native compilation + open apis = java utopia
:D
Too much greed makes you crazy I suppose.
I will just leave it at this point.

--
You received this message because you are subscribed to a topic in the Google Groups "RoboVM" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/robovm/-LEeLkGJodA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to robovm+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages