%% -*- mode: LaTeX -*-
%%
%% Copyright (c) 2002 University of Utah and the Flux Group.
%% All rights reserved.
%% This file is part of the JanosVM documentation.
%% 
%% Permission to use, copy, modify, distribute, and sell this
%% documentation for any purpose is hereby granted without fee,
%% provided that the above copyright notice(s) appear in all copies.
%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% A lot of the information in here is probably duplicated from other chapters
% but I imagine a lot of people would skip them and go right here anyways.

\chapter{Tutorial}
\label{cha:Tutorial}

This chapter takes you through the steps needed to run and write some simple
example programs.  Complete source code for each of the examples is located in
the \file{doc/janosvm/tutorial} subdirectory of the \JanosVM{} software
distribution.  It is advised that you make a copy of the directory and try out
the \JanosVM{} as you read the chapter.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{A Hello World Kernel}
\label{sec:A Hello World Kernel}

First, compile \file{HelloWorld.java}:

% bah, a lot of the command lines are pretty long, especially the jsihey ones.
% So, we need to manually break them up at the 80 column mark.

% XXX Note that 'jikes' is a drop-in replacement for javac, available
\begin{transcript}
buffy@ucsd tutorial> jikes -classpath <install dir>/share/kaffe/JanosVM.jar \
  HelloWorld.java
\end{transcript}

Note that you have to use the \file{JanosVM.jar} \JAR{} file since it contains
the \JanosVM{} specific classes, as well as the basic Java classes.  Next, run
the class file with the following command:

\begin{transcript}
buffy@ucsd tutorial> janosvm -config tutorial.config HelloWorld
[Ignore any warnings for now]
Hello World!
\end{transcript}

This will execute the \janosvm{} script which starts up the main \Kaffe{}
binary with \file{JanosVM.jar} in the class path.  The \JVM{} then goes through
some extra initialization steps:

\begin{itemize}
  \item The \JanosVM{} extensions become enabled when they detect their classes
  in \file{JanosVM.jar}.

  \item The extensions configure themselves using the configuration file
  specified by the \option{-config} option.

  \item The ``kernel'' team is created, where team is the \JanosVM{} name for
	the process abstraction (think team of threads).  %% XXX bleh

  \item The main thread migrates into the kernel team and executes the ``Kernel
  Main'' class file, \file{HelloWorld.class} in this case.
\end{itemize}

This method of starting up the \JVM{} is useful for simple kernels like ``Hello
World'' or fully capable kernels that can run for a long time and communicate
with users.  However, not having some mechanism to communicate with running
\JVM{}s would likely make the process of developing kernels and services
extremely hard.  Thus, we have developed the \JanosVM{} Scripting Interface
(\JSI{}) in order to help mitigate these issues.  The interface is modeled
after AppleScript and the BeOS scripting interface so its pretty simple and can
function over a number of communication mediums.  To help you get comfortable
with its usage we'll be using \JSI{} to drive the \JVM{} in the rest of the
tutorial.  First, though, we'll need to learn some of the jsi-specific \janosvm{}
command-line options (described in \autoref{subsec:Command Line Options}):

% Duplicated here to bulk up the page count :)
\begin{optionlist}
  \item[-jsitcpport]
  %
  Specify the \TCP{} port used to send and receive \JSI{} messages.

  \item[-noexit]
  %
  Causes the \JVM{} to continue running even though the only live threads are
  daemons.

  \item[-name]
  %
  Binds a name to this instance of the \JVM{}.  This name is then used to store
  the \TCP{} port value in a simple registry in \file{~/.janosvm/registry/}
  that can be referenced by other programs.
\end{optionlist}

With these options we can now run an instance of the \JVM{} that won't exit
immediately and doesn't need a kernel class file:

\begin{transcript}
buffy@ucsd tutorial> janosvm -config tutorial.config -name janosvm \
  -jsitcpport 14000 -noexit &
buffy@ucsd tutorial> jsihey janosvm execute run of team 1 with \ 
  class HelloWorld then nothing
Hello World!
\end{transcript}

% Hey!  Why isn't the kernel pid 0 like it should be!  :)

After starting the \JVM{} we used the \jsihey{} command to create and send a
\JSI{} message.  This particular message tells team one, the kernel, to execute
the HelloWorld class with no arguments.  If you wanted to pass arguments to the
class you'll need to add some data to the message by appending a number of
identifier/value pairs to the command line.  In the case of the \jsiheyid{run}
message, it can contain the \jsiheyid{arg} and \jsiheyid{args} identifiers
which specify a single argument and separate arguments grouped together within
quotes, respectively.  For example:

\begin{transcript}
buffy@ucsd tutorial> jsihey janosvm execute run of team 1 with \
  class HelloWorld args "xander anya" arg "Willow Rosenberg" then nothing
Hello xander
Hello anya
Hello Willow Rosenberg
\end{transcript}

Since we're done with the \JVM{} for this section we'll send it a
\jsiheyid{shutdown} message so that it quits.

\begin{transcript}
buffy@ucsd tutorial> jsihey janosvm shutdown
\end{transcript}

% XXX link up to jsihey section in this document as well.
The \jsihey{} tool can send a number of other messages also; check out its man
page or \autoref{cha:Using jsihey} for more details.  There is also a simple
python binding for \JSI{} in the \file{janosvm/libraries/unsupported/jsi/pylib}
directory if you don't like shell scripts.  
%Anyway, let's move on to the next
%section...


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Creating a new Team}
\label{sec:Creating a new Team}

In the previous section we created a simple HelloWorld kernel, so now it's time
to start creating our own teams and playing with them.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Using Java}
\label{subsec:Using Java}

For this example we'll be using the \file{HelloNewTeam.java} program, so
compile and run it.

\begin{transcript}
tservo tutorial> jikes -classpath <install dir>/share/kaffe/JanosVM.jar \
  HelloNewTeam.java
tservo tutorial> janosvm -config tutorial.config HelloNewTeam
kernel says hello
Child says hello
\end{transcript}

From the source code we can see that the first thing to print something is:

\begin{javacode}
System.out.println(Team.current().getName() + " says hello");
\end{javacode}

Since the class is being run in the kernel the call to \javaid{Team.current()}
will return the handle associated with the kernel, hence we get its name.  Next
we create a child with the default resource requirements and the name "Child".

\begin{javacode}
TeamHandle child = Team.create("Child");
\end{javacode}

However, besides the \GC{} threads there is nothing else executing within the
context of this team, so we need to visit the team in order to get something
done.  The \javaid{child.switchTo()} call accomplishes this by switching the
context of the current thread to the child team, now we can execute the same
printing code and yield a different result.  Next, we need to back out of the
child team using \javaid{child.returnFrom()} call.  Finally, we use
\javaid{child.terminate()} to terminate the child team and return its resources
to the \JVM{}.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Using \JSI{}}
\label{subsec:Using JSI}

In addition to the Java interface we can also use \JSI{} to create and
terminate teams.

\begin{transcript}
tservo tutorial> janosvm -config tutorial.config -name janosvm \
  -jsitcpport 14000 -noexit &
tservo tutorial> jsihey janosvm create team with name "Parent" \
  then print "%(result:d)\n"
2
\end{transcript}

The \jsihey{} line tells the \JVM{} to create a team with the name "Parent" and
print out the unique identifier associated with the team.  This id is then used
for all interactions with the team when using \JSI{}.  To get a listing of all
the teams and their id's just execute the following:

\begin{transcript}
tservo@satolove tutorial> jsihey janosvm list teams
Normal Reply:
  id = `1'
  name = `kernel'
  description = `'
  id = `2'
  name = `Parent'
  description = `'
\end{transcript}

Now that we have our new team let's run HelloNewTeam and see if its output has
changed:

\begin{transcript}
tservo tutorial> jsihey janosvm execute run of team 2 with class \
  HelloNewTeam then nothing
Parent says hello
Child says hello
\end{transcript}

Well it seems to work, now let's terminate the parent:

\begin{transcript}
tservo tutorial> jsihey janosvm delete team 2 then nothing
\end{transcript}

That should be enough for now, shutdown the \JVM{} and let's move on to the
next section.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{A Client/Server HelloWorld}
\label{sec:A Client/Server HelloWorld}

The ability to create new teams means we can experiment with sharing objects
via cross-team pointers.  This example implements a client/server HelloWorld
using the \file{HelloBackEnd.java} class to export an object from the kernel
and the \file{HelloHandle.java} class to import that object into the current
team.  These classes make use of the \javaid{Exportable} and
\javaid{Importable} system classes which manage references into other teams.

\begin{transcript}
stewie tutorial> jikes -classpath <install dir>/share/kaffe/JanosVM.jar \
  HelloBackEnd.java
stewie tutorial> jikes -classpath <install dir>/share/kaffe/JanosVM.jar \
  HelloHandle.java
\end{transcript}

Now, start up the \JVM{} and run \javaid{HelloBackEnd} in the kernel to export
the server object.

\begin{transcript}
[Terminal 1]
  stewie tutorial> janosvm -config tutorial.config -name janosvm \
    -jsitcpport 14000 -noexit

[Terminal 2]
  stewie tutorial> jsihey janosvm execute run of team 1 with class \
    HelloBackEnd then nothing
\end{transcript}

Let's divert our attention for a second to the \file{tutorial.config} file
because it's working some magic required for all this to work.  The major part
of the config file defines which classes can be exported from a team in order
to be imported by others. Basically, it lists what classes can be shared
between teams.  Near the bottom you might have noticed that
\javaid{HelloBackEnd} is listed as one of the exports.  The export is needed
because any teams that import a \javaid{HelloBackEnd} object are going to do a
cast from \javaid{Object} to \javaid{HelloBackEnd} so they'll need the same
class.  If this export wasn't there a different \javaid{HelloBackEnd} class
will be loaded by each team and the cast wouldn't work, so we wouldn't be able to use
the object as anything more specific than a \javaid{java.lang.Object}.  
The actual process of exporting the classes was already done by
the kernel and the \javaid{HelloBackEnd} main, so we just need create a team
that imports the classes and run \javaid{HelloHandle}:

\begin{transcript}
[Terminal 2]
  stewie tutorial> jsihey janosvm create team with name "hello-client" \
    namespace 1:kernel:identity namespace 1:tutorial-hello:identity \
    then print "%(result:d)\n"
  2
  stewie tutorial> jsihey janosvm execute run of team 2 with class \
    HelloHandle then nothing

[Terminal 1]
  Client hello-client says `Hello World'
\end{transcript}

Cool.  The first \jsihey{} line created the team and imported the kernel
classes and the \javaid{HelloBackEnd} class using the \jsiheyid{namespace}
arguments.  The \jsiheyid{namespace} argument is a bit complicated, it
specifies what team to import the classes from (1 == the kernel), the group of
classes as listed in the config file, and the team's view of the classes.
There will be more detail about class groups and views later, but for now, lets
shutdown the \JVM{} and continue with the tutorial.  Or, if you're adventurous,
create a new team without the \jsiheyid{namespace}
\jsiheyid{1:tutorial-hello:identity} argument and see what happens.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Terminating an uncooperative Team}
\label{sec:Terminating an uncooperative Team}

This is a quick example; we just want to show that you can kill a misbehaving
team.  We'll be using \file{HelloSpaz.java} for this example:

\begin{transcript}
msmart@control tutorial> jikes -classpath <install dir>/share/kaffe/JanosVM.jar \
  HelloSpaz.java
\end{transcript}

The program doesn't create its own team so we'll have to start one for it.

\begin{transcript}
[Terminal 1]
  msmart@control tutorial> janosvm -config tutorial.config -name janosvm \
    -jsitcpport 14000 -noexit

[Terminal 2]
  msmart@control msmart> jsihey janosvm create team with name "Kaos" then \
    print "%(result:d)\n"
  2
  msmart@control msmart> jsihey janosvm execute run of team 2 with class \
    HelloSpaz then nothing
  msmart@control msmart>

[Terminal 1]
  hihihihihihihihihihihi
  hihihihihihihihihihihi
  hihihihihihihihihihihi
  ...
\end{transcript}

Now we just delete the team and the output should be stopped:

\begin{transcript}
[Terminal 2]
  msmart@control msmart> jsihey janosvm delete team 2
\end{transcript}

Well, this is the end of the tutorial.  You can also look in
\file{test/janosvm} for more code examples.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% End of file.

