Creating an app in any new framework can sometimes be a bit of a chore. Have you looked at the files that come form a new Hello World JavaFX app from NetBeans? Not very dry at all and a lot of esoteric stuff in side directories is created, you know just in case you want to customize it. And the problem isn’t NetBeans, they are doing the best they can with Ant.
The Ideal Build
To me the ideal build setup for a JavaFX application would involve putting your source files in a specific directory layout, placing supporting files in a similarly conventional manner, adding a minimal build script, pressing a button, and catching my .app or .exe as it falls out the other side.
One of the keys here is the minimal build script. If I am doing things the standard way then my actions should be presumed. Presumed without comment. Part of the legacy of the ant build system is you cannot simply say ‘my Java code is here, make a jar.’ You have to hand walk the build from where your source code lives, to where you want the compiled class files to go, to where you want the jar to go, to what you want to name it. And heaven forbid if you use other peoples libraries, or expect other people to use yours.
I’m being a little harsh on Ant here. Let’s roll back our memory to 13 years ago and realize how Ant was eight kinds of awesome compared to a make file. Many builds I saw used to drop class files in the source tree. And if you had to add a package you either had to update the make file or hope some side voodoo script could sniff it out, and the mess leftover was barely tolerable. Recursive file sniffing and a separate build directories were the gold standard back at the turn of the century. But the problem with higher standards is eventually they become the baseline expectation. Consider how much building software stunk before even make existed!
Hand Cranked to Configurable to Conventional
The evolution we are witnessing here is one of increased automation, and the standardization. This is just like the industrial revolution and the classic example of firearms. You can hand craft a rife, and it will work just fine. If anything breaks, however, you have to hand craft a replacement and often craft other pieces to make sure it continues to work. When the parts were standardized, in both assembly and interface, you can mass produce many different rifles and do many interesting things with the various add ons. If you want a slightly different grip or trigger, you can replace it because if the interface. If you find a broken rifle you can figure out what is wrong with it because of the standard assembly, And if you stick to the standards, ammunition is readily interchangeable between any rifle.
One of the key issues with interchangeable parts, however, is the need for a critical mass. With a small audience conventions are merely incidental. In large groups and with enough adoption they become the rules of society, for example what side you pass someone on the sidewalk.
To take us closer to the industrialized build we need to agree on some conventions. Even though I am building a Gradle plugin, I feel we need to accept and adopt widely some Maven conventions. Specifically the
src/<set>/<language|role>/... pattern for source files. Gradle already adopts this pattern by default, which is good from the viewpoint of interchangeable parts.
<root>/ +--src/ +--main/ +--java/ | +--<Java Classes by package> +--resources/ | +--<Resources, like CSS and image, by package> +--package/ +--win/ | +--<Bundle specific files> +--macosx/ | +--<Bundle specific files> +--linux/ | +--<Bundle specific files> +--<icon files for bundles>
This is notional, and I am more than willing to hear comments as to where I am getting stuff wrong. This is currently the file layout I am using for my Gradle JavaFX plugin, and I’ve pulled three of the JavaFX sample apps into this directory format, and the build files are all quite short (after the yak shaving to install the plugin). Brickbreaker just installs the plugin. ConferenceScheduleApp only names the executable (with bonus Java Version yak shaving) while Ensemble2 has the most to do, and none of it involved JavaFX but it is peculiar to how the app works.
My goal here, is to make all of the JavaFX yak shaving transparent, so you can focus on indexing your samples in your build rather than remembering the syntax of the ant deploy task.