Sometimes it's easiest to learn by doing. In this chapter we'll walk you through a workday with Seedling, showing you the basic workflow and design concepts step by step.
We're going to start with a fresh workspace based on the Seedling Software Development Kit. Begin by going to the Seedling Web site and downloading the latest SDK distribution.
Unpack the SDK archive and place it anywhere in your file system.
Go ahead and rename the directory if you want. As you'll see, the Trellis
build system on which Seedling is built provides a very self-contained
workspace, you can move it around as you wish and nothing's going to
break. For the purposes of this tutorial, we'll assume that your workspace
is located at the path ~/tutorial
. Once you've got
the archive unpacked, things should look like this:
[tutorial]$ ls
LICENSE.TXT bin/ build.xml seedling/ src/
Welcome.html build/ lib/ setup
Before you do any work, you need to setup your shell environment.
This process defines some environment variables so the various tools know
where the workspace lives. It also adds the workspace's
bin
directories to your path, so you can run the
tools easily.
To setup the environment, just source the setup
file:
[tutorial]$ source setup
Running Ant to install supporting tools and libraries...
Buildfile: build/setupTools.xml
BUILD SUCCESSFUL
Total time: 0 seconds
PROJECT_HOME is /Users/todd/tutorial
To see project targets, type 'ant -projecthelp'
[tutorial]$
OK, we're lying here. The first time you go through this process, it's going to be a bit more complicated:
You'll get an error saying that Ant wasn't found, along with directions about what to put where. Just do as you're told, eat your vegetables, and you'll grow up big and strong.
When you setup
again as instructed (Sir, Yes,
Sir!), the script will download and install a number of third-party
packages into your workspace.
From then on out, the setup will look as short and sweet as we say above.
Despite our minor subterfuge, you should now be ready to run. Let's go for the gold and build the whole system:
[tutorial]$ ant modules
Buildfile: build.xml
...
module:
Building jar: /Users/todd/tutorial/target/modules/ticker/lib/ticker.jar
BUILD SUCCESSFUL
Total time: 4 seconds
[tutorial]$
Guess what? You just compiled a Seedling module! Let's run it!
[tutorial]$ runseed ticker
This is Ticker version DEV-todd-200403202332
//tasks/MemoryMonitor: Active memory: 543K/1984K (27%)
//tasks/ClockTicker: The current time is Wed Oct 20 23:18:43 PDT 2004
//tasks/ClockTicker: The current time is Wed Oct 20 23:18:44 PDT 2004
//tasks/ClockTicker: The current time is Wed Oct 20 23:18:45 PDT 2004
...and so on. You've just built and run a very simple Seedling application that prints the time every second. Not bad! As simple as it seems, at the very least you've verified that you have a functional workspace, which gives us a good baseline for much bigger things to come.
Warning | |
---|---|
This is rough, sorry. |
$ cp -r src/ticker src/hello
Edit build.xml:Add hello to subprojects
Edit hello/build.xml: Set project name. Clear predecessors.
Edit hello/module.properties: Update requires (if necessary).
Now wipe the main and config trees.
$ant modules
$runseed hello
Nothing happens! Well, of course not, our module is empty.
Let's give the module something to do: the insipid yet obligatory
“Hello World” application. Everyone knows how to do this,
right? Create a new file called HelloWorld.java
inside the empty main
directory of the
hello
module. The main
directory
is the root of the module's main Java code; any subdirectories here will
correspond to the Java package hierarchy. For now, we'll keep things
simple and just define a class in the default package.
// file: tutorial/src/hello/main/HelloWorld.java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }
Wait! Stop! No! Have you forgotten everything you learned in the
last chapter? The goal here is not to write procedural applications, but
to write component applications. A good component almost never has
static
things, and certainly shouldn't have
main
! Let's try again, placing the output statement in
the first available place, the constructor:
// file: tutorial/src/hello/main/HelloWorld.java public class HelloWorld { public HelloWorld() { System.out.println("Hello, Seedling!"); } }
There now, doesn't that feel good? We have a nice little component, just waiting to be instantiated into a welcoming world.[1] Let's create another file that will cause just that to happen. The following file declares a Seedling node that will be our first component.
# file: tutorial/src/hello/config/Hello.properties .this = new HelloWorld
Some explanation is in order.
This file is in the config
directory, not
the main
source directory. The
config
directory is the root of the module's
Seedling configuration layer. You'll learn a lot more about it as we
work through this tutorial.
The name of the file corresponds to the name of the Seedling
node it configures. This file, Hello.properties
,
configures a node called Hello
.
This is a normal Java properties file.
This means that comments begin with the hash character,
#
.
The only property here looks a little strange, since it starts with a period. This denotes a meta-property, meaning that it's an instruction to the container rather than a value being assigned to a property of the component.
The .this
meta-property declares an expression
that will be evaluated when this node needs to be instantiated.
In this case, the
Hello
node will be an instance of the
HelloWorld
class.
This one little file with one little line is all that's necessary to enable Seedling to construct and install our component. Shall we try it? Don't forget to rebuild the module first.