The Java Implementation Guide
Requirement
The system requirement of Beanbag is:
- Windows XP/Vista or Linux with Bash Shell
- Java Runtime Environment 5.0 or higher
Directory Structure
|synclib.jar|The main file of Beanbag.| |:--------------|:------------------------| |aspectjrt.jar, antlr-runtime-3.0.1.jar|The dependent libraries of Beanbag.| |compile.bat, compile.sh|The command to compile a Beanbag source file into a Java source file.| |run.bat, run.sh|The command to invoke a Beanbag program in console mode.| |examples/ |This directory includes the standard library, an EJB example and a UML2RDBMS example. The two examples are both described in the paper.| |license/ |The license description. | |source/ |The source code of Beanbag. Type "ant compile -lib dependency/antlr3.jar" to compile.| |Readme.html|This page. |
Walkthrough
In this walkthrough we will invoke the EJB example and synchronize some updates in the command line in Windows. Readers will see how to invoke a Beanbag program in console mode and how to pass updates to the system. Note a Beanbag program can also be compiled into a Java program can be invoked through Java method calls.
First ensure the current directory is the Beanbag directory and type the following command to invoke the EJB example:
run examples\EJB.sync
The Beanbag tool will compile the example and start an interactive environment. An prompt ">>
" will appear to indicate that the environment is ready to accept commands. Type "name
" and we will see the current synchronizer is "main
".
Before making actual updates, we need to initialize the synchronizer. Type the following command to initialize the parameters to three empty dictionaries, which indicates initially the system has no EJB, no module, nor entity bean.
```
initialize {},{},{};void,void,void ```
Now we can update the data in the system. Let us first create an entity bean. Type the following command:
```
sync void, void, {__new->{EJBName->UserEJB, ModuleName->SignOn}} ```
Here we created an entity bean whose "EJBName
" is "UserEJB" and "ModuleName
" is "SignOn". The keyword "__new
" is used to indicate an new reference and will later be replaced by an uniquely assigned integer.
After we type this command, the system will produce the following output:
__new=1
{2->{Name->!UserEJB, Persistent->!true, Module->!3}},{3->{Name->!SignOn}},{1->{E
JBName->!UserEJB, ModuleName->!SignOn}}
The first line indicates "__new
" is replaced by 1 and the second line is the output updates of the synchronizer. We can see that an EJB named "UserEJB" and a module named "SignOn" are created. The EJB is assigned a reference "2" and the module is assigned a reference "3". By typing "val" we can see the result after we apply the updates to the data.
```
val {2={Name=UserEJB, Persistent=true, Module=3}},{3={Name=SignOn}},{1={EJBName=User EJB, ModuleName=SignOn}} ```
Next let us add an EJB. Type the following command and we will see an corresponding entity bean is created.
```
sync {__new->{Name->DepartmentEJB, Module->3, Persistent->true}}, void, void __new=4 {2->{Module->!3}, 4->{Name->!DepartmentEJB, Persistent->!true, Module->!3}},{3-> {Name->!SignOn}},{1->{ModuleName->!SignOn}, 5->{EJBName->!DepartmentEJB, ModuleN ame->!SignOn}} ```
Again, by typing "val
" we can see now the data contains two EJBs, two entity beans and one module.
```
val {2={Name=UserEJB, Persistent=true, Module=3}, 4={Name=DepartmentEJB, Persistent= true, Module=3}},{3={Name=SignOn}},{1={EJBName=UserEJB, ModuleName=SignOn}, 5={E JBName=DepartmentEJB, ModuleName=SignOn}} ```
Then let us modify the name of the module. Type the following command and we will see all "ModuleName
s" of the corresponding entity beans are also changed.
```
sync void, {3->{Name->SignOnModule}}, void {2->{Module->!3}, 4->{Module->!3}},{3->{Name->!SignOnModule}},{1->{ModuleName->! SignOnModule}, 5->{ModuleName->!SignOnModule}} val {2={Name=UserEJB, Persistent=true, Module=3}, 4={Name=DepartmentEJB, Persistent= true, Module=3}},{3={Name=SignOnModule}},{1={EJBName=UserEJB, ModuleName=SignOnM odule}, 5={EJBName=DepartmentEJB, ModuleName=SignOnModule}} ```
Note modifying an attribute does not always result in the modification of other attributes. Let us modify the "Persistent
" attribute of "PersonEJB
" and see what will happen.
```
sync {2->{Persistent->false}}, void, void {2->{Persistent->!false}},void,{1->!null} ```
The corresponding entity bean is deleted. This is because only persistent EJBs have corresponding entity beans, and non-persistent EJBs do not have corresponding entity beans.
Finally, let us delete the module. Type the following command and we will see all EJBs and entity beans belonging to the module are deleted. The current values become three empty dictionaries again.
```
sync void, {3->null}, void {2->!null, 4->!null},{3->!null},{5->!null} val {},{},{} ```
After you have tried all the updates, type "exit
" to exit the interactive environment.
Usage Guide
Beanbag can be invoked in two modes. One is compilation mode, where a Beanbag program is compiled into a Java source file and the Java source file can later be used in other projects. The other one is console mode, where a Beanbag program is loaded into an interactive console, where users can pass updates to synchronizers through commands.
The description below assumes that you are familiar with the Beanbag language. Please refer to the technical report for more information
Compilation Mode
To invoke Beanbag in compilation mode, use the following command in the Beanbag directory:
compile sourceFileName tagetJavaClassName
For example, you compile the EJB example program into a Java-based synchronizer by typing "compile.bat examples\EJB.sync EJB
" in Windows or "./compile.sh examples/EJB.sync EJB
" in Linux.
The synchronizers defined in the Beanbag source file will be converted a set of static methods in the Java source file. Users can use "getXXXFactory().create()
" to get an instance of a synchronizer whose name is "XXX
". The synchronizer implements the "ac.jp.u_tokyo.SyncLib.Sync
" interface. "int Sync.getParaCount()
" returns the number of variables the synchronizer synchronizes. "Mod[] Sync.resynchronize(Object[], Mod[])
" intializes the synchronizer. "Mod[] Sync.synchronize(Mod[])
" synchronizes input updates based on the current state of the synchronizer.
"ac.jp.u_tokyo.SyncLib.Mod
" is the interface for all modification operations. "Mod.apply()
" applies the modification operation to a plain Java data object.
The follows show the relationship between the modification operations defined in the paper and the Java classes in the implementation.
Update: !23
Java Code:
import ac.jp.u_tokyo.SyncLib.*;
new PrimMod<Integer>(23);
Update: {1->!23}
Java Code:
import ac.jp.u_tokyo.SyncLib.*;
import ac.jp.u_tokyo.SyncLib.dictionaries.*;
DictModFactory f = new DictModFactory();
f.addPut(1, new PrimMod<Integer>(23));
f.create();
The follows show how to simulate the first two invocations of the above example in Java. To compile the code, the synclib.jar, aspectjrt.jar and the compiled Java file must be in the classpath. ``` import ac.jp.u_tokyo.SyncLib.; import ac.jp.u_tokyo.SyncLib.dictionaries.; import ac.jp.u_tokyo.SyncLib.util.*; import ac.jp.u_tokyo.SyncLib.language3.GlobalIncrementalFactory; Object[] values = new Object[] {new HashMap(), new HashMap(), new HashMap()}; // data to be synchronized Mod[] mods = new Mod[] {NullMod.INSTANCE, NullMod.INSTANCE, NullMod.INSTANCE}; // initial updates Sync sync = YourClassName.getmainFactory().create(); //create the synchronizer from the compiled code mods = sync.resynchronize(values, mods); //initialize Helper.applyMods(values, mods); // apply the updates to data
//create new modifications DictModFactory f = new DictModFactory(); f.addPut("EJBName", new PrimMod("UserEJB")); f.addPut("ModuleName", new PrimMod("SignOn")); mods = new Mod[] {NullMod.INSTANCE, NullMod.INSTANCE, DictModFactory.createPut(new GlobalIncrementalFactory().createNewKey(), f.create())};
mods = sync.synchronize(mods); //synchronize Helper.apply(values, mods); //apply the updates to data ```
Console Mode
To invoke a Beanbag program in console mode, use the following command in the Beanbag directory:
run sourceFileName
For example, run.bat examples\EJB.sync
invokes the EJB example in Windows, and ./run.sh examples/EJB.sync
invokes the EJB example in linux.
After entering the console mode, Beanbag will first compile the console a prompt >
will indicate that the Beanbag console is ready to accept command. The following table shows a list of command available.
|initialize values; updates
|Initialize the current synchronizer with initial values and updates. For example, initialize {}, {}, {}; void, void, void
provides three empty dictionaries as initial values to the EJB example.|
|:---------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|sync updates
| Pass updates to the current synchronizer and get output updates |
|switch synchronizerName
| Switch to another synchronizer. The synchronizer loaded at the start is main
. |
|name
| Show the name of the current synchronizer. |
|val
| Show the current values of the parameters of the current synchronizer. |
|trace [off|on]
| Enable/Disable trace. |
|depth number
| Control the depths of the trace. |
|exit
| Exit the console. |