When working on big projects I often create little projects to support the larger effort. Sometimes these little projects turn into something great on their own. It's time for me to tell you about one of them: AppBundler.
AppBundler is a small tool which packages up Java (client side) apps with a minimum of fuss. From a single app description it can generate Mac OSX .app bundles, Windows .EXE files, JNLPs (Java Web Start), double clickable jars; and as of yesterday evening: webOS apps! I started the project to support Leonardo Sketch but I think it's time for AppBundler to stand on it's own.
Packaging Java apps has historically been an exercise in creative swearing. The JVM provides no packaging mechanism other than double clickable jars, which are limited and feel nothing like native apps. Mac and Windows have their own executable formats that involve native code, and Sun has never provided tools to support them. Java Web Start was supposed to solve this, but it never took off the way the creators hoped and has it's own idiosyncrasies. Long term we will have more a more environments with Java available but with different native package systems. Add in native libs, file extension registration, and other metadata; and now you've got a real problem. After hacking Ant files for years to deal with the issue I decided it was finally time to encode my build scripts and Java lore into a new tool that will solve the issue once and for all. Thus AppBundler was born.
How it works
You create a simple XML descriptor file for your application. It lists the jars that make up your app along with some metadata like the App name and main class. It can optionally include icons, file extensions, and links to native libraries.
<?xml version="1.0" encoding="UTF-8"?> <app name="Amino Particles"> <jar name="Amino2.jar"/> <jar name="amino_sdl.jar"/> <jar name="examples.jar" main-class="com.joshondesign.amino.examples.Particles"/> <property name="com.joshondesign.amino.impl" value="sdl"/> <native name="sdl"/> </app>
Then you run AppBundler on this file from the command line along with a list of directories where the jars can be found. In most apps you have a single directory with all of your jars, plus the app jar itself, so you usually only need to list two directories. You also specify which output format you want or --all for all of them. Here's what it looks like called from an ant script (command line would be the same).
AppBundler will then generate the executable for each output format.
<java classpath="lib/AppBundler.jar;lib/XMLLib.jar" classname="com.joshondesign.appbundler.Bundler" fork="true"> <arg value="--file=myapp.xml"/> <arg value="--target=mac"/> <arg value="--outdir=dist/"/> <arg value="--jardir=lib/"/> <arg value="--jardir=build/jars/"/> </java>
What it doesFor Mac it will create a .APP bundle containing your jars, then include a copy of the JavaApplicationStub and generate the correct Info.plist files (Mac specific metadata files), and finally zip up the bundle. For Windows it uses JSmooth to generate a .EXE file with an icon and class path. For Java WebStart it will generate the JNLP file and copy over the jars. For double click jar files it will actually squish all of your jars together into a single jar with the right META-INF files. And all of the above works with native libraries like JOGL too. For each target it will set the correct library paths and do tricky things like decompress native libs into temp directories. Registering for file extensions and requesting JREs mostly works.
What about webOS?All of the platforms except webOS ship with a JVM or one can be auto-installed on demand (the Windows EXEs do this). There is no such option for webOS, however. webOS has a high level HTML 5 based SDK and a low level C based PDK. To run Java on webOS you'd have to provide your own JVM and class libraries, so that's exactly what I've done. The full OpenJDK would be too big to run on a lightweight tablet, and a port would take a team of people months to do. Instead I cross compiled the amazing open source JVM Avian to ARM. Avian was meant to be embedded and already has an ARM port, so compiling it was a snap. Avian can use the full OpenJDK runtime, but it also comes with it's own minimal classpath.jar that provides the bare minimum needed to run Java code. Using the smaller runtime meant we wouldn't have a GUI like Swing, but using Swing would require months of AWT porting anyway, which I wasn't interested in doing. Instead I created a new set of Java bindings to SDL (Simple DirectMedia Layer), a low level graphics API available on pretty much every platform. Then I created a port of Amino (my 2D scene graph library) to run on top of SDL. It sounds complicated (and it was, actually), but the scripts hide the complexity. The end result is a set of tools to let you write graphical apps with Java on webOS. Amino already has ports to Java2D and HTML 5 Canvas (and OpenGL is in the works), so you can easily create cross platform graphics apps. And now with AppBundler you can easily package them as well. Interestingly, Avian runs on desktops nicely, so putting Java apps into the Mac App Store might now be possible. There's already some enterprising developers trying to get Avian working on iOS.
How you can help.While functional, I consider AppBundler to be in an alpha state. There's lots of things that need work. In particular it needs Linux support (generate rpms or debs?) and a real Ant task instead of the Java exec commands you see above. I would also like to have it be included in Maven and any other useful repo. And as a final request (as long as I have you here), I need some servers to run builds tests on. I have already have Hudson running on a Linux server. I'd love it if someone could run a Hudson slave for me on their Windows or Mac server. And of course we need lots of testing and bug fixes. If you are interested please join the mailing list.
Client Java FreedomAppBundler is another facet of my efforts to let help Java provide a good user experience everywhere. Apps should always feel native, and that includes the installation and start experience. I've used AppBundler to provide native installs of Leonardo Sketch on every desktop platform. I hope AppBundler will help you do the same. Enjoy! -Josh
posted Fri, 23 Sep 2011 03:39:20 +0000
Over the weekend I moved app bundler to its own project. It is now hosted on GitHub and has a real Ant task.
In brief, AppBundler is a small tool to turn your collection of jars into a native executable for Mac and Windows, as well as JNLPs and single jar apps. With the new ant task you just define a small XML file listing your jars and the main class, then make this call from ant:
<appbundler bundle="bundle.xml" target="mac" destdir="dist" libdir="build/jars;lib" />
That's it. Now that App Bundler is independent I'm looking for some help improving it. In particular I'd like to support native Linux executables (shellscripts? rpms? debs?), JavaFX apps, bundling native libs (partly working), and embedding a JRE with the app. If you are interested in helping please join the GitHub project.
posted Mon Mar 26 2012
Mmmwaa haa haa. It lives! I've gotten Java to run on webOS natively with a new set of Java SDL bindings. That means it just *might* time to start a new project. Read on for how it works and how you could help.
For a while I've been following an open source project called Avian. It's a very lightweight and highly portable JVM that can run almost anywhere. Recently I tried a new build and was able to get the ARM port running on webOS! This is good news because Avian can run pretty much any Java code if you supply it with the right runtime (it can optionally work with the OpenJDK libs).
Now, of course getting a command line app it run is not very interesting. Really we want to talk to the screen to make some real graphical applications. So that brings us to part two: SDL.
If you've been doing desktop programming for a while you've probably heard of SDL, the Simple DirectMedia Library. It's a fairly low level graphics and audio API that runs pretty much everywhere, including on webOS. But, of course, like many low level APIs it's built in C. So if I want to use Java I need to some wrapper to call it. The existing wrappers out there are very old and didn't work well on Mac, so it was time to build my own.
Over the weekend I learned how to use Swig, a JNI wrapper generator and successfully ran my new SDL wrappers on Mac, Linux, and webOS. Here's a quick screenshot:
it's not much but it proves that everything is working.
So what's the next step? Honestly... I don't know. I created this specifically to let me code Java on webOS, but the SDL bindings would probably be useful for cross platform desktop applications as well. We could port Amino to it, or do some funky multitouch stuff. It would certainly be great for people creating games. I need your advice.
What would you like to do with this library? What higher level APIs would you like? If you have any ideas of what you'd do with this lib, or would like to contribute to the project (help on Windows compilation would be greatly appreciated), then please message me on twitter: @joshmarinacci.
posted Wed, 31 Aug 2011 22:35:21 +0000
The book is done!
I am happy to announce that I have finished writing my new book for O'Reilly on GWT and PhoneGap. Well, not completely finished; my final draft is submitted but O'Reilly's talented team still has to work their technical magic to get it prepped for sale.
Oh yeah, and I got a cool animal as well!
The book covers everything you need to get started with GWT and PhoneGap, including how to use the native SDKs for iOS, webOS, and Android. Then we dive into customizing the interface for mobile devices and using open source libraries to access device features. I also cover app UI design and optimization. Finally the book ends with a video game project where we use HTML Canvas to build a tilting physics game with a cartoon blob hero.
I am quite proud of the book though I often find the process of long form writing painful. The first 90% is super fun but the second 90% seems to take forever! I hope you enjoy the results. The book will soon be available for order on O'Reillys website and wherever ebooks are sold.
posted Fri, 17 Feb 2012 20:55:21 +0000
Building Mobile Applications with Java Using GWT and PhoneGap
I'm happy to announce that my new book Building Mobile Applications with Java Using GWT and PhoneGap has been published in both print and ebook editions. While I love having a print edition, the ebook Kindle version, at $9.99 is half the price for the exact same content. Sure, you can't write on it with a marker, but the convenience and price is well worth it.
If you didn't catch it in one of my earlier blogs, Building Mobile Apps w/ Java, GWT, and PhoneGap is a shortish book (~80pgs) that gives you the good stuff and none of the fluff. GWT and PhoneGap are two great open source tools that, combined, let you use Java to make apps for non-Java platforms. This good gives you everything you need to know, starting with building a simple GWT app and compiling it for iOS, Android, and webOS. After we get familiar with the tools I'll walk you through some 3rd party libraries that make your apps feel more native. Then we will finish up with a 2D video game using the accelerometer and a physics library.
My goal was to give you everything you need to get started in as short a time as possible. You are busy people who need to get back to coding, so I don't want to waste your time. I think the finished work is right on target.
You can buy it here as well as download the source to the projects.
HTML Canvas : A Travelogue
I have also updated my self published app-book on HTML Canvas. It gives you a gentle walk through of what Canvas, how to use the APIs from drawing to pixel pushing, and then shows you how to build a simple game with 2D sprites and particle effects. The book also uses an experimental form of interactive code where you can change the values of variables in examples then see how the graphics update in real time.
I call this book an EverBook, meaning updates will always be free. The book itself is an app so if you already bought just check in your app catalog for the update. I've fixed a bunch of bugs, improved performance, and fleshed out a few sections. Also, stay tuned for a few more interactive features I've got up my sleeve.
You can buy the book here. $4.99 for iOS and $0.99 for webOS. (Shoutout to my webOS peeps!)
posted Mon Apr 16 2012