JAC is still beta software
released for developers who know what they are doing. It is
developed and tested under Linux and should work out of the box
on any Unix-like system. It should be very easy to make it run on
Windows by using the furnished scripts/org.objectweb.jac.bat
script
(however, the compilation scripts should be ported).
To use JAC, download a JAC release at the downloads section. JAC uses several libraries that you can find on the Internet.
Simple installation: you can simply download the JAC version with libraries included (since version 4.1). With this choice, the JAC installation is easier and you do not need to install all the following (except JDK1.3).
Complex installation: download the JAC version with no libraries included and install the following libraries separatly from JAC.
and to compile JAC:
Once you have installed all you need, install JAC and initialize the environment:
cd <work_dir> tar zxf org.objectweb.jac.xxx.tar.gz
scripts/init_env
and then source it in the root
directory of the distribution:
source scripts/init_env [JAC_ROOT directory]
WARNING: under Windows, the
scripts/init_env
script will not work. You
should use the scripts/org.objectweb.jac.bat
script that sets
the class path. This script assumes that you installed JAC
in C:\jac
. If you installed it somewhere else,
you should edit org.objectweb.jac.bat
and change the
definition of JAC_ROOT
and
CLASSPATH
.
Make.rules
if
needed (for instance if you want to use javac instead of jikes),
and run make:
make
You should have performed all the needed steps described in the Installation of JAC section. Here is a quick reminder in case your samples do not work.
Each sample has a makefile in its directory that is automatically generated by the global make. If you compiled JAC, normally the samples are already compiled.
Note: to know if a sample needs the persistence
aspect, go in the sample directory and see if its contains
persistence.acc
file (i.e. a configuration file
for persistence). However, if you do not want to use
persistence at a first try, edit the .jac file of the sample,
remove the line that adds the persistence aspect to the
application (or switch the last parameter to false). The
sample will then run in a transient mode (all the
modifications you make on the objects will be forgotten if you
restart the program).
Two kinds of storage are available : filesystem and SQL. The filesystem storage allows you to store objects in plain files on your local filesystem. SQL storages allow you to store objects in an SQL database. Only Postgresql is supported for the moment, but adding other databases is very easy.
By default, the samples use the filesystem storage and stores
data files in a directory relative to JAC_ROOT
All you need to do is to specify a directory where object files will stored in the persistence.acc :
configureStorage org.objectweb.jac.aspects.persistence.FSStorage { "<directory>" };
The directory does not need to exist. It will be created if it does not exist.
The src/org/objectweb/jac/aspects/persistence/createdb.sql
script creates the tables needed by the aspect (note
that you need to have postgresql and a fully installed account
that allows you to create databases in order to perform this
step):
createdb photo psql photo < createdb.sql
Customize the configureStorage line in persistence.acc. The syntax is:
configureStorage <storage_class> { "<db_name>", "<db_user>", "<db_password>" };
Since Postgresql is the only supported database for the moment,
<storage_class>
is
org.objectweb.jac.aspects.persistence.PostgresStorage
. Note that
if you change the sample program structure, the database may become
inconsistent with the application.
In any directory, run jac with the *.jac file path as a last argument.
jac -G main src/org/objectweb/jac/samples/photos/photos.jac
It will launch JAC and the photos sample class with the Swing
GUI (-G option). The main
parameter after the
-G
is the name of the window to display. For more
details about starting
options.
If the sample can run in a distributed mode (see the
*.jac
or if a deployment.acc
file
exists to know that), then you will need other JAC containers to
be started elsewhere depending on how the deployment aspect is
configured (see or modify the deployment.acc
file
of the sample). To allow the distribution aspect to work:
jac -D serverName(the final server name is
//hostname/serverName
where
hostname
is the TCP/IP name of the host the
server is launched on and serverName
is the given
name). For more details about starting options.go
script that launches as
many servers as you need and automatically names them
(go N
launches //hostname/s1, //hostname/s2, ... //hostname/sN
)topology
property is defined in the
application descriptor file (*.jac
) of the sample.
Modify it so that it defines all the servers that you have
launched in the previous step.deployment.acc
file exists in the
sample's directory and that the deployment rules it defines
correspond to the names of the servers you have launched
(check the available aspects
for distribution). Check also that the *.jac
file declares the deployment aspect.jac -G -D
src/org/objectweb/jac/samples/ring/ring.jac
. Note that a JAC server
is then created for deployment and is named
//localhost/s0
. This deployment server is used by
the other servers as the global aspects configurations
server.Then, just launch the application with the -W
option:
jac -W default calcul.jac
In order to view an object with your browser, you just have to
enter the following URL:
http://localhost:8080/org/objectweb/jac/default
.
You can then perform any action you could perform with the swing GUI.
Once you are ok with the JAC installation and environment, let us enter into details on how to program a sample application with JAC. We choose the calcul sample since it is a very simple one (available in the latest JAC distributions).
This tutorial allows you to go through JAC programming step by step and in a very progressive way. For more general overview on the JAC's programming philosophy, see the JAC Programmer's Guide.
The base application is the functionnal or core-business
application. In other words, it is the simpliest expression of
your functionnal needs. Here, we would like to have a class that
performs some simple calculi. Wherever you want, create a new
directory calcul
and, inside of it, a file called
Calcul.java
. The code is the following:
// Calcul.java file // A simple component definition that can perform // add and sub operations... public class Calcul { protected float value = 0; public void add(float toadd) { value+=toadd; } public void sub(float tosub) { value-=tosub; } // IMPORTANT: in JAC, each instance-field better have // a getter of the form getFieldName. public float getValue() { return value; } // IMPORTANT: in JAC, each instance-field better have // a setter of the form setFieldName. public void setValue(float value) { this.value=value; } // Program entry-point public static void main( String[] args ) { // Actually launch the calcul program by creating an // instance of the Calcul class that waits to be used... Calcul myCalcul = new Calcul(); } }
Note that the need of the getters and setters comes from the aspects that will use them later-on.
In JAC, any application must have a program descriptor that we put in a *.jac file. This file declares the new application and the supported aspects to the JAC system.
// calcul.jac file applicationName: calcul launchingClass: Calcul
The launching class is a regular class that contains a static
main
method. For simplicity, we put the main()
in the Calcul
class.
Compile these files like you are used to doing in Java
(*.jac
and *.acc
files do not need to
be compiled).
javac Calcul.java
When compiled, run the JAC server and indicate to launch the calcul
sample. Note that all the classpath issues in Java are also
present in JAC -- thus, you can add the calcul directory to the
classpath (note that *.acc
files are also fetched
using the classpath, for this reason, you should beware of
conflicts when modifying the classpath). Into the calcul
directory (where Calcul.class
and
Run.class
should be found), just run (assuming that
$JAC_ROOT/scripts/jac
is in your path):
jac calcul.jac
Since no aspects are configured for the application, All you will see is this:
--- Launching Application calcul --- JAC system shutdown: notifying all ACs... Bye bye.
This is not very usefull, but is it prooves that JAC is working on your system.
org.objectweb.jac.core.rtti is a core aspect that allows the programmer to define extra type information that will be used by other aspects at runtime.
For instance, it can be very useful for other aspects to be
aware that a given method modify the object's state. Since JAC
can detect that automatically, we do not need to add specific
configurations for our sample application. All you need to do is
create an empty file rtti.acc
.
The GUI aspect allows the programmer to define some presentation information, and to parameterize the interactions between the application objects and the user. For instance, by configuring a personal GUI aspect, a programmer can define the names of the method parameters as they will be displayed by a GUI.
For our example, create a gui.acc
file:
// configuration for the Calcul class class Calcul { // Show a button for each of these methods setMethodsOrder {add,sub}; // Set the names of the parameters of add and sub methods setParameterNames add { "Value to add" }; setParameterNames sub { "Value to sub" }; // Set a default value for add setDefaultValues add { 1 }; } // Says that all the methods of class Calcul can be called interactively askForParameters "Calcul"; // The GUI main window configuration window default { registerCustomized; setTitle "Calculator"; // A real simple GUI setSubPanesGeometry 1 VERTICAL { false }; // Display the object named "calcul0" in the panel "0" of the window. setPaneContent 0 Object { "calcul0" }; }
Once you have created you ACC files, you must declare them to the
application by modifying the calcul.jac
file as
following:
// calcul.jac file applicationName: calcul launchingClass: Calcul aspects: \ rtti rtti.acc true \ gui gui.acc true
You can then launch the application with the following command:
jac -G default calcul.jac
And you should see a window like this:
As you can see, the calcul instance is being
introspected by the GUI aspect of JAC that offers a default view
on it. It shows the fields of the calcul0
object
(here value
, and the methods that can be
called on the object (the two buttons add
and sub
)). The pencil-like
button on the right of
the field means that you can edit the field value by calling the
field's setter. Click on it to change the value of the
value
field. The following box pops-up. Type
a new value:
When you click on OK, you can notice that the view is
automatically refreshed. Indeed, thanks to bytecode analysis,
JAC knows that setValue
is a setter for the
value
field. Thus the MVC (Model-View-Controller)
underlying framework of the GUI aspect refreshes the view.
Let us now try the add
button:
You will first notice that the default value to be added is
"1". This is because of the setDefaultValues
instruction in the gui.acc
. When you click on OK, once again the
view of the main window is automatically refreshed because JAC
detected that the add
method modifies
the field value
.
All this configuration works also with the WEB. If you launch JAC with the WEB-GUI server:
jac -W default calcul.jac
You will see the following output on the console:
--- Launching Application calcul --- WARNING: Resource rtti.acc not found 13:34:52.863 EVENT Starting Jetty/4.1 13:34:53.832 EVENT Started HttpContext[/jac] 13:34:53.841 EVENT Started HttpContext[/org/objectweb/jac/resources] 13:34:54.295 EVENT Started SocketListener on 0.0.0.0:8088 13:34:54.306 EVENT Started org.mortbay.http.HttpServer@100bac2 WARNING: Web server already started
Then, with you favorite web browser, go to http://localhost:8088/org/objectweb/jac/default
:
Other aspects are available and can be configured using the same process that the one depicted for the RTTI and GUI aspects.
Some other useful aspects to configure are:
NOTE: This tutorial will be soon completed with other aspect configurations and programming. For the moment, you can follow the same rules to configure other aspects (see the furnished samples) and you can refer to the JAC Programmer's Guide and to the JAC API documentation for further details.
JAC provides full support for distributed AOP. This means two things:
org.objectweb.jac.aspects.distribution
packageBasically, the deployment aspect provides a set of deployment rules that the programmer can use to deploy its application over a set of containers.
If we take again the calcul example, you may intend to launch JAC
in a distributed mode where a set of clients will access to one
unique instance of calcul (here, calcul0
) located
on a server host.
To allow this, first modify the application descriptor to tell that the application knows a set of two other containers, and activate the deployment aspect.
// calcul.jac file applicationName: calcul launchingClass: Run aspects: \ rtti mydirectory/rtti.acc true \ gui mydirectory/gui.acc true \ deployment mydirectory/deployment.acc true topology: //localhost/s1 //localhost/s2
This means that, including the master host (called
//localhost/s0
), your JAC system will contain three
local sites s0, s1, s2
. If you want to locate
calcul0
on s1
, just write an ACC file,
deployment.acc
:
// deploy the calcul0 object from s0 to s1 deploy ".*s0" "calcul0" ".*s1"; // create stubs to access calcul0 on s0 and s2 createStubsFor "calcul0" ".*1" ".*0 || .*2";
Then start 2 JAC servers (if an error occurs, check section Run the sample in distributed mode).
go 2
Then start the application in a distributed mode (this starts the
master server) -- do not forget to move into the
calcul
directory if needed:
jac -G -D calcul.jac
If everything goes okay, you should be able to perform remote call
from s0
and s2
to
calcul0
on s1
. To check this, you can
launch remote GUIs on s1
and s2
from
the master GUI by using the menu: System -->
Containers
and by selecting the remote container you need
to start a GUI on, and by clicking the "Launch remote
GUI"
button.
What is revolutionary with JAC is the ability to change the way the
application is distributed without having to change the
application's code or even to restart the servers (this is one
of the benefits of our Dynamic and Distributed Aspect-Oriented
Framework). For instance, if you finally want to say that
calcul0
is replicated on all the sites of the
topology and in strong consistency, then you can change the
deployment file:
// replicate the calcul0 object from s0 to all replicate ".*s0" "calcul0" ".*";
And add a consistency protocol by configuring the consistency aspect (you must declare it in
your .jac
file).
addStrongPushConsistency "calcul0" MODIFIERS ".*";
The replicated-strong protocol maintains the replicas in a
consistency called strong, i.e. as soon as a modification
occurs on one site, all the replicas on the other sites are
modified the same way (the last two parameters indicate that the
methods that modify the object state
--MODIFIERS
-- are pushed to the other
replicas). To better understand how it works, you can play with
this rule and change the MODIFIER
argument into
"setValue(float):void || add(float):void"
to not
push the modifications when the sub
method is
called (in our case, MODIFIERS
equals to
"setValue(float):void || add(float):void ||
sub(float):void"
) (for more details about pointcut
expressions that are allowed when denoting methods sets, see the
MethodPointcut class.
To apply this rule at runtime, you must declare the consistency
aspect in your .jac
class. Then you can (un)weave
aspects at runtime. To (un)weave an aspect, (un)check the checkbox that
corresponds to the aspect in the
Aspects
lower-left subwindow of the master host's
GUI. You can replace an aspect configuration by modifying and
saving the ACC file, unckecking the
checkbox, then, when the unweaving is finished, check
the checkbox again to activate the new configuration.
Once you have fully understood how it works, you are ready to play
with more advanced features. For instance, you can use the
load-balancing aspect (see
org.objectweb.jac.distribution.aspects.LoadBalancingAC) to increase the
load capability of your applications. For instance you can
program a load-balanced calculator only by slightly changing the
distribution aspects, and by adding a new ACC
(load-balancing.acc
):
// deployment.acc replicate ".*s0" "calcul0" ".*";
// consistency.acc addStrongPushConsistency "calcul0" "MODIFIERS" ".*[1-2]";
// load-balancing.acc addRoundTripLoadBalancer "calcul0" ".*s0" ".*[1-2]";
With these three configurations, the calcul instance of
s0
is a load-balancer that performs a rountrip
load-balancing algorithm to dispatch on s1
and
s2
.
With the JAC software, we furnish a bunch of useful aspects that can be advantagely used to program distributed applications. However, since JAC is a young project and that we cannot think in advance of all the possible uses you can make out of such a software, most of the aspects we provide may lack useful configuration method or may not work fine for specific usages.
Here is a uncomplete list of the aspects that can be provided to create more specific applications:
Moreover, existing aspects need extensions to be complete. For instance:
As an example, we next show how to add a simple fault-tolerence support to the load-balancing aspect provided in the JAC distribution (see org.objectweb.jac.distribution.aspects.LoadBalancingAC).
Let us first recall the structuration of an aspect by showing
the code for an aspect that checks that the add
or
sub
method invocations on the calcul0
instance so that it raises an error if the added value is
greater than 100 or if the substracted value is greater than
50.
// MyCheckingAspect.java // the aspect declaration: class MyCheckingAspect extends AspectComponent { // at instantiation-time, you should define the pointcuts public MyCheckingAspect() { // this pointcut will make the add method of calcul0 // wrapped by an instance of checkingWrapper (an // inner wrapper of this aspect), and more specifically // by the wrapping-method "checkAdd" pointcut("calcul0","Calcul","add(float):void", CheckingWrapper.class.getName(),"checkAdd", false); // same principles for sub... pointcut("calcul0","Calcul","sub(float):void", CheckingWrapper.class.getName(),"checkSub", false); } // then define the wrappers (if you think that these // wrappers can be used by other aspect, you can make // them public within a standalone class-file) public Class CheckingWrapper extends Wrapper() { // see the programmer's guide for details on the // wrapping methods semantics... public Object checkAdd() throws Error { if( ((Integer)args(0)).intVal()>100 ) { throw new Error("bound excedeed when calling add!"); } } public Object checkSub() throws Error { if( ((Integer)args(0)).intVal()>50 ) { throw new Error("bound excedeed when calling sub!"); } } } }
Note that this aspect is very specific since it can only be applied
to the calcul0
instance. To program generic
aspects, you may refer to the JAC programmer's
Guide. Configuration methods are a first step towards
genericity since they allow the system to dynamically create the
pointcuts with the interpretation of the Aspect-Component
Configuration (ACC) files (*.acc
).
In this case, you can parametrize the creation of the pointcuts
instead of hardcoding them in the aspect-component
constructor. For instance, the following two files have exactly
the same effect than the previous hardcoded aspect-component
except that a simple change of the object's name in the
configuration file allows the user of this aspect component to
make it work on other instances of the Calcul
class.
// MyCheckingAC.java: class MyCheckingAC extends AspectComponent { // at configuration-time (just after the instantiation), // this configuration method can be called to define the // pointcuts public void checkCalcul(String name) { // this pointcut will make the add method of the // instance named "name" wrapped pointcut(name,"Calcul","add(float):void", CheckingWrapper.class.getName(),"checkAdd", false); // same principles for sub... pointcut(name,"Calcul","sub(float):void", CheckingWrapper.class.getName(),"checkSub", false); } // then, same as the hardcoded aspect... Class CheckingWrapper extends Wrapper() { (...) } }
// my-checking.acc: checkCalcul "calcul0";
NOTE: to be able to use and declare your new aspect
component in *.jac
file, you should first declare
them in the global org.objectweb.jac.prop
file located in
$JAC_ROOT
(see the org.objectweb.jac.acs
property).
The load-balancing aspect used in section Using AOP to program distributed applications follows the same structuration rules:
package org.objectweb.jac.aspects.distribution; import org.objectweb.jac.core.*; import org.objectweb.jac.core.dist.*; import gnu.regexp.*; import java.util.*; /** * This Aspect Component allows the programmer to easily implement * load-balancing features for its application when JAC is running in * distributed mode. * * @author Renaud Pawlak * @version 0.5.2 */ public class LoadBalancingAC extends AspectComponent { /** * This configuration method allows the user to define a round-trip * load-balancer on a replication group. * * It assumes that a replication group exists on a set of host * denoted by replicaExpr. It also assumes that an * uncorrelated replica called wrappeeName exists on * hostName. Note that this distributed scheme can be * easilly obtained by configuring the deployment aspect for an * object myObject like this: * * replicated "myObject" ".*[1-6]"; * * This means that myObject is replicated on all * the hosts one to six and that the replicas are strongly * consistent. Then, you can configure the load-balancing: * * addRoundTripLoadBalancer "photorepository0" ".*" "s0" ".*[1-6]"; * * Note that the round-trip balancer (located on s0) changes the * replica it uses for each invocation. The followed sequence is * 1,2,3,4,5,6,1,2,3,4,5,6,1,... * * An alternative to the round-trip load-balancer is the random * load-balancer that randomly picks out the next replica to * use. This can be useful when a total decoralation is needed for * all clients. * * @param wrappeeName the name of the object that is replicated and * that will act as a load-balancer proxy * @param methods a pointcut expression for the method that perform * the load-balancing (others perform local calls) * @param hostName the host where the proxy load-balances * @param replicaExpr a regular expression that matches all the * hosts of the topology where the replicas are located * * @see #addRandomLoadBalancer(String,String,String,String) */ public void addRoundTripLoadBalancer( String wrappeeName, String methods, String hostName, String replicaExpr ) { pointcut( wrappeeName, ".*", methods, new LoadBalancingWrapper( replicaExpr ), "roundTripBalance", hostName ); } /** * This configuration method allows the user to define a random * load-balancer on a replication group. * * It follows the same principles as a round-trip balancer but * picks up the next replica to use randomly. * * @see #addRoundTripLoadBalancer(String,String,String,String) */ public void addRandomLoadBalancer( String wrappeeName, String methods, String hostName, String replicaExpr ) { pointcut( wrappeeName, ".*", methods, new LoadBalancingWrapper( replicaExpr ), "randomBalance", hostName ); } /** * This inner-wrapper handles the load-balancing wrapping methods that * actually implement the load-balancing algorithms. */ public class LoadBalancingWrapper extends Wrapper { int count = 0; Vector replicas = null; Random random = new Random(); String hostExpr; boolean doFill = true; public LoadBalancingWrapper( String hostExpr ) { this.hostExpr = hostExpr; } public void invalidate() { doFill = true; } /** * Performs a round-trip load-balancing. */ public Object roundTripBalance() { if( doFill ) { replicas = Topology.getPartialTopology(hostExpr) .getReplicas( this.wrappee() ); } if( replicas.size() == 0 ) { // none replicas where found, we perform a local call and // will try to get them again on the next call doFill = false; return proceed(); } if( count >= replicas.size() ) { count = 0; } return ((RemoteRef)replicas.get(count++)).invoke(this.method(),this.args()); } /** * Performs a random load-balancing. */ public Object randomBalance() { if( doFill ) { replicas = Topology.getPartialTopology(hostExpr) .getReplicas( this.wrappee() ); } if( replicas.size() == 0 ) { // none replicas where found, we perform a local call and // will try to get them again on the next call doFill = false; return proceed(); } return ((RemoteRef)replicas.get(random.nextInt(replicas.size()))) .invoke(this.method(),this.args()); } } }
In the latest distributions, JAC provides an IDE that supports UML-like and UML for aspects so that it greatly simplifies the programmer's task.
Since the IDE is a JAC application, you must make sure that the JAC distribution is correctly installed and configured as depicted in the tutorial.
This IDE is still in a beta version. The core model is quite stable and you should be able to read your projects with upcomming JAC releases, however, class diagrams could be lost.
The supported modeling language is a subset of UML (it only supports class diagram), plus a set of new concepts to model aspects (aspect classes, pointcut relations, and groups).
We claim that when using aspect-oriented technology, the whole UML language is not actually needed since the program is expressed with its simpliest core-business form. All the complexity related to implementation and design is handled in the provided aspects. As a consequence, you might be disapointed if you try to use this IDE whithin a regular development process on regular OO or CB technologies (however, this IDE could be easily extended to support these if needed).
Make sure that JAC is correctly installed and launch the
application descriptor located in org/objectweb/jac/src/org/objectweb/jac/ide
:
jac $JAC_ROOT/src/org/objectweb/jac/ide/ide.jac
When launched for the first time, the IDE appears as a window separated in 4 sub-panels. In the upper-left pannel, one can see a treeview that contains one single node called "projects". This sub-panel is the most important since it allows you to navigate in your projects and all the projects entities such as packages, diagrams, classes, or applications. The following list shows the hierachy of all the different entities manipulated by the IDE:
Using the treeview is simple. You can double-click on a given node to open it. You can use the right-click to show the available treatements on the entity. For instance, to create a new project, just right-click on the "projects" node and choose the "Add project" item.
The upper-right panel is used to edit diagrams. Once you have created a package in your project (using right-click on the treeview), create a diagram in this package. The upper-right panel will show a diagram editor that allows you to create and edit the entities of the owning package.
The two lower panels are used to provide a Widget-based representation of the currently selected entity in a diagram. The left one shows classes, aspects, instances, or groups. The right one shows relation and pointcut links, attributes, or methods. These two panels can be used to edit the model elements without using a graphical diagram editor (which is sometimes useful to avoid using the mouse to much).
First create a new project using the right click on the "projects" node of the treeview. Call it "myProject" and choose the generation path (the directory where the Java code will be generated).
You then need to create a new package in your project to define the business classes. Right-click on "myProject" node and add a package that you can call "invoices".
Since it is nicer to model graphically, right-click on "invoices" and add a new diagram. Call it "business" since it will represent the core-busines model of the application. A diagram editor component should then open in the upper-right sub-panel.
Click on the "New class" button () of the diagram editor toolbar and then
click on the desktop where you want to locate the new class. A
new class should appear with a default name (NewClass). You can
modify its name by using the "Text tool" (
) button and click
on the title or by using the lower-left sub-panel. Just call it
"Invoices". This class represents a container for a set of
invoices.
Now create in the same way an "Invoice" class. You can add an
attribute by using the "Add attribute" button () of the
toolbar. Using the text tool, you can edit this attribute. You
MUST follow the conventions in the attribute definition,
i.e. attribute_name:attribute_type. The available types
are the classes that are already created and all the builtin
types (see in the main menu:
Tools --> Type
repository
). Just set the attribute to
"amount:double". With the same process, create an attribute
"date:Date".
You can now create another class "Client" with an attribute "name:String".
We can now relate the three classes together. Use the "New
relation" button (). Press the left button down on the "Invoices"
class and, without releasing, move to the "Invoice" class and
let the button up. A new relation link should be created with
its default roles, names, and cardinalities. You can edit them
on the diagram using the text tool, or in the lower-right
sup-panel. Set the end cardinality to "0-*". Do the same to
create a relation between "Invoice" and "Client" set the start
cardinality to "0-*".
Please, also set the role names as shown in the following screenshot.
Once the core business is modeled, you should create a new application to make a running JAC program.
Right-click on the "myProject" node and choose "Add
application". Call it "myFirstApplication" for instance. You can
also program the launching code of the program (this code
corresponds to the static void main(String[] args)
method that is used as an entry point for the Java program).
In JAC, the idea of a lauching code is to create the root objects of the application that can be used to reach or create other objects via collections (relation links with "0-*" end cardinality) or references (relation links with "0-1" end cardinality).
In this case, we only need to create an "Invoices" instance since all the other objects are reachable from it (regarding the model). Thus, in the launching code editor, type the line:
new invoices.Invoices();
Note that the full name of the class is as expected the parent package path concated with the class name (this follows the Java conventions).
At this step, the application is ready to run. Validate and use the "Generate code" and the "Compile" commands by right-clicking on the "myProject" node. If something goes wrong, some error message(s) should appear in an errors dialog. If you do not figure out how to solve the problem, do not hesitate to contact us.
Since the application does not perform any treatment, it is not very interesting to launch it as is. Thus, we should add at least a GUI aspect so that the user of the application can create and manipulate the business objets.
The GUI aspect is one of the most useful aspect provided by JAC since it allows the programmer to configure how the business objects should be rendered and how the final user can interact with the application.
As any aspect in JAC, the GUI aspect provides a configuration interface GUIConf that defines all the configuration methods that can be used during the configuration process. The programmer can refer these interfaces to know the available commands that can be used.
To add an aspect configuration to an application, right-click on the application node of the treeview and add a new aspect configuration.
First create an RTTI aspect (choose rtti for the aspect name and leave the aspect blank --- this is used when a personnal aspect is created in the IDE). No configuration is required for the moment.
Then, create and configure the GUI aspect as shown in the following screenshots.
Before starting, ensure that the code generation is ok by right-click on the project's node and "Generate code"+"Compile".
The application code and classes is then available in the generation directory (GEN_DIR) that you have choosen when you have created the project (you can change it by asking a view on the project).
Ensure that GEN_DIR/classes
is in your
classpath.
Launch JAC with the application's desciptor that was automatically generated.
jac GEN_DIR/myFirstApplication/myFirstApplication.jac
The JAC's IDE helps the programmer to design JAC applications and allows him to easily configure existing aspects (the ones that are provided by the JAC distribution). However, for the moment, the knowlege of the aspect configuration interfaces is still needed. In a short future, the IDE will provide some graphical customization means that will make the programmer task easier.
With the IDE, the programmer can also create entirely new aspects despite it is not documented yet.