Installing SOLoist
Before you start working with SOLoist, you have to prepare your system for Java EE development. You will need the following: Java JDK, Eclipse IDE, Apache Tomcat, and StarUML.
If you already have all these installed on your machine, you may skip the System Requirements section.
After installing the required software, it is recommended that you download the Empty Project which is already prepared for SOLoist development.
System Requirements
Java
Since SOLoist is a Java-based framework, you have to install Java first. SOLoist works with Java 1.6 JDK or later. It can be downloaded from Oracle Website.
Application Server
For executing SOLoist applications, you need to have an application server. This example assumes you have installed Apache Tomcat. SOLoist works with versions 5.5, 6, and 7, which can be downloaded from Apache Tomcat Website.
Eclipse
In this tutorial (and other tutorials on this site) we use Eclipse IDE, but any other Java IDE can be used. Eclipse IDE for Java EE development can be downloaded from Eclipse Website.
Please make sure to download Eclipse IDE for Java EE Developers, not the classic Eclipse package or the package for plain Java.
Database
SOLoist framework currently officially supports the following databases: MySQL, Oracle, and Sybase SQL Anywhere. Before starting working with SOLoist, you should install one of the supported databases, create a new schema and/or a user in the database, and give the appropriate privileges to the user.
In the SOLoist Tutorial, we used MySQL database, which can be downloaded from MySQL Website.
StarUML
Being an executable UML framework, SOLoist requires a UML modeling tool. At this moment, we only support StarUML (V1), but other modeling tools will be supported in the future. StarUML is an open source UML/MDA patform and can be freely downloaded form Star UML (V1) on Sourceforge.
If you have installed StarUML under C drive in Windows 7 (Vista), you may experience erratic behavior. StarUML may raise errors about accessing registry, or some completely unrelated errors (a common one is invalid class typecast exception
). You should elevate StarUML's privileges by starting it as an administrator (right click on it and select Run as Administrator, then click Yes in the User Account Control dialog). If you expirience other problems, try running it in compatibility mode (Windows XP SP2).
After installing StarUML, you have to download and install SOLoist plugin for StarUML.
Then download the Frameworks archive and extract Frameworks folder directly into ...\StarUML\modules\staruml-javasol\
(e.g. C:\Program Files (x86)\StarUML\modules\staruml-javasol\Frameworks
).
If you ever plan on reinstalling StarUML, beware that its unnistaller doesn't clean up registry behind it. A most obvious consequence is that reinstalled application won't be able to load add-ins, most importantly the add-in for exporting XMI files. You need to clean the registry yourself after unnistallation. We advise you to use a more capable utility than Windows' basic registry editor (regedit), for example RegEditX. Search for "staruml", "xmiadd", "cppadd", "javaadd", "roseadd" and "csharpadd", and delete every found key!
Running Empty Project in Eclipse
After downloading the Empty Project archive file, you should unzip it somewhere in your file system. Inside the EmptySOLoistProject folder, you will find the model folder which contains an empty StarUML model (emptymodel.uml
) that you can use to create your own domain models.
The EmptySOLoistProject folder contains an Eclipse project that can be imported into a workspace. To import this project into Eclipse, you should select Import from the File menu and choose Maven -> Existing Maven Project into Workspace.
After importing the project, right click the project and select Maven -> Update Project... and then OK. Before doing this, make sure that SOLoist libraries are already stored in your maven repository so they can be fetched during the project build process.
Navigate to the folder which contains EmptySOLoistProject
. Check it in the list and click Finish.
If the Tomcat is not already installed, you will probably see a few errors in the project. That's still fine, because you need to configure the application server.
Select the Servers tab, click on new server wizard...
or right click on the empty space and select New -> Server. Find Apache Server v7.0 (or an earlier version if you wish) in the list of the available application servers, select it, and click Next.
If you're not in the Java EE perspective you'll need to open Servers view yourself. Go to Windows -> Show View -> Other..., then choose Servers view under the Server folder.
Provide the directory where you installed Tomcat and click Next.
Configure the EmptySOLoistProject on the server by selecting it and adding it to the Configured list. Click Finish.
Make sure you have increased Tomcat's startup time. This may be necessary as SOLoist can perform various database actions while Tomcat is starting. Double click on the Tomcat server in the Server view, open Timeouts panel and enter a new value (e.g. 360) in the Start field. Save changes by pressing Ctrl + S.
Tomcat uses HTTP port 8080 by default. If there are other applications on your machine that use the same port Tomcat will not be able to start. This is a common problem if you have installed the Oracle database - their web interface service listens to the same 8080 port. If this is the case, please change the port number (e.g. 8081).
You also need to configure the targeted runtimes for your project. You can do so by going to Project's Properties (right click on the project -> Properties), Targeted Runtimes. Check Apache Tomcat v7.0 (or another version that you have installed).
This step is not necessary if you use Tomcat 7 as this project is already configured for it.
At this point, you should have no errors in your project. The structure of the project should be as in the figure below.
Note that there are two folders for the source code in this project: src
and init
. SOLoist configuration files are stored in the src
folder. SOLoist follows the convention over configuration principle, so there is a minimum of configuration required:
- Enter the database name, username and password into
db.properties
file. For more details see the SOLoist Database Configuration wiki page. - Setup the file repository path in
soloist-config.xml
. - Set the log file path in
log4j.xml
.
More details about configuration can be found on the SOLoist Configuration wiki page.
You are now ready to start you first SOLoist application. Start the server by right clicking it and selecting Start.
Now visit: http://localhost:8080/emptyproject/index.html
in your browser to see your first SOLoist app at work!
Remember to change the port number in the URL if you have made changes to Tomcat configuration earlier.
Extending The Empty Project
Now that you have a basic application running, it's now the time to build something yourself! This section will teach you how to properly set up and create a simple domain model, generate the Java code, the database schema, and initialize the database with data. We will only touch on GUI development, but you should go through our more complete tutorial.
Preparing the domain model
First, let's create a domain package. In StarUML, right click on the model in Model Explorer (StarUML's default <<designModel>> Design Model
), select Add -> Package, and name it with the stereotype <<domain>> (e.g. <<domain>>hospital
).
Create a new class diagram by right clicking on the domain package, then go to Add Diagram -> Class Diagram and give it a descriptive name (e.g. hospital).
Before we can create domain classes, we need to import the SOLoist built-in library. It is useful as documentation, but more importantly our domain model relies on its built-in datatypes, commands, etc. To import the framework in StarUML, go to File -> Import -> Framework... and choose the framework you want to import (SOLoist Framework). If you cannot find the SOLoist Framework in the list, you have probably skipped this step.
Then select the package where you want to import the framework.
You absolutely must create two nested top-level packages rs.sol
in any model and insert the SOLoist Framework in there. Otherwise, the generated Java code won't compile!
Once imported, you will see a small sheet icon next to the SOLoist package. It means that this is an imported package, and it relies on an external unit. To make an imported package an integral part of your model, right click on it, go to Unit -> Uncontrol Unit. Your model file will be somewhat larger, but it won't rely on an external unit. This is useful in team development.
Creating domain classes
Now, let's create a simple class Doctor
. We are still in StarUML. Choose the class tool from the toolbox and click on the diagram. Name the class and press Enter. Add an attribute name
of SOLoist type Text
(right click on the class and select Add -> Attribute). It is important that StarUML recognizes that Text
is the type from the previously imported framework. To verify this, select the attribute in Model Explorer, then select Type
field in the Properties tab below. Clicking on the ellipsis button will open a dialog which should show the selected type Text
from SOLoist.
Similarly to adding an attribute, add the operation heal()
.
Code generation
Now, we should generate SOLoist Java code from StarUML. We need to set the path where generated files will end up. To do that you first have to include the JavaSOL profile into the model. This will add additional options to UML elements, like the code generation path. Press Ctrl + F8
or go to Model -> Profiles..., choose the JavaSOL profile and click on Include.
Right click on your model (Design Model
) in Model Explorer and click on Tagged Values. You will see an additional JavaSOL tab with one tagged value named CodeGenerationPath
. The default value is c:\temp
, but you should change it to the source folder of your project (e.g. D:\used\EmptySOLoistProject\src
).
You can override the code generation path for different packages in the model. Set the Implementation
tagged value (it's a UMLStandard tagged value, not JavaSOL) of the package to alternative path. Beware that StarUML will always report the original generation path after successful code generation.
You can generate the code for one single class, or for an entire package, or for the entire model (note that this will generate code even for the imported SOLoist package). Right click on the domain package (hospital
), go to SOL Java Plug-In -> Generate SOLoist Code. Switch to Eclipse, refresh it, and you will find the Doctor
class inside the hospital
package.
SOL Java Plug-in also provides the Generate Java Code option for generating plain Java code. Don't confuse this with Generate SOLoist Code!
Let's take a look at the generated class. The only part that you should change manually is the heal()
method body. Notice the comments in the form // ---------<SOL id="6d3bc142-e042-4df2-96d9-b9eaa0981e9e:___body___" />
- these enclose the so-called preserved sections.
Everything written between these comments will be preserved if you run the code generator again and regenerate the code for the same part of the model. That means that method implementations should be inside the method body's preserved section. Every class has three preserved sections: cbeg
(beggining of the class), cend
(end of the class) and fend
(end of file). Additionally, every method has two preserved sections: throw
(for throws clause) and body
(for the method body).
//Generated: by JavaSol plugin package hospital; import rs.sol.soloist.modelreader.Repository; import rs.sol.soloist.server.builtindomains.builtindatatypes.Text; import rs.sol.soloist.server.builtindomains.common.ObjectOfClass; import rs.sol.soloist.server.javaimpl.runtime.SOLoistAttributeValue; import rs.sol.soloist.server.javaimpl.runtime.SOLoistCreateInstanceRequest; import rs.sol.soloist.server.uml.concepts.reflection.IClass; import rs.sol.soloist.server.uml.concepts.reflection.IProperty; import rs.sol.soloist.server.uml.concepts.runtime.IAttributeValue; import rs.sol.soloist.server.uml.concepts.runtime.IObjectID; public class Doctor extends ObjectOfClass { // -------------<SOL id="abc63313-1017-4949-9314-74a4fa5f1e4b:___cbeg___" /> // -------------<LOS id="abc63313-1017-4949-9314-74a4fa5f1e4b:___cbeg___" /> public final IAttributeValue<Text> name = new SOLoistAttributeValue<Text>(PROPERTIES.name, this); /** * Fully qualified UML class name */ public static final String FQ_TYPE_NAME = "hospital::Doctor"; /** * UML class reference */ public static final IClass CLASSIFIER = Repository.getRepository().getUMLClass(FQ_TYPE_NAME); public static final class FQPropertyNames { public static final String name = "hospital::Doctor::name"; private FQPropertyNames() { } } public static final class PROPERTIES { public static final IProperty name = Repository.getRepository().getProperty(FQPropertyNames.name); private PROPERTIES() { } } protected Doctor(IObjectID objID) { super(objID); } protected Doctor(SOLoistCreateInstanceRequest req) { super(req); } public Doctor() { this(new SOLoistCreateInstanceRequest(CLASSIFIER)); constructor(); completeRequest(); } public void heal() // -------------<SOL id="6d3bc142-e042-4df2-96d9-b9eaa0981e9e:___throw__" /> // -------------<LOS id="6d3bc142-e042-4df2-96d9-b9eaa0981e9e:___throw__" /> { // ---------<SOL id="6d3bc142-e042-4df2-96d9-b9eaa0981e9e:___body___" /> // TODO: implement this throw new RuntimeException("Not Implemented"); // ---------<LOS id="6d3bc142-e042-4df2-96d9-b9eaa0981e9e:___body___" /> } // -------------<SOL id="abc63313-1017-4949-9314-74a4fa5f1e4b:___cend___" /> // -------------<LOS id="abc63313-1017-4949-9314-74a4fa5f1e4b:___cend___" /> } // -----------------<SOL id="abc63313-1017-4949-9314-74a4fa5f1e4b:___fend___" /> // -----------------<LOS id="abc63313-1017-4949-9314-74a4fa5f1e4b:___fend___" />
Generating the database schema
SOLoist's integrated ORM automatically generates the database schema based on the domain model. It needs an XMI file as an input. To export the XMI from StarUML, go to File -> Export -> XMI... Browse to the project's src
folder, and overwrite emptyproject.xmi
.
Don't forget to refresh Eclipse!
Every time you try to export XMI, StarUML will remember the last used path, but not the filename (defaults to Untitled.xml). Don't forget to change the filename!
Open web.xml
in Eclipse and make sure that the listener demo.contextlisteners.ObjectSpaceInitContextListener
is declared. Now start the server. You will see console messages: Dropping obsolete tables
, Creating tables and indexes
. SOLoist saves the DDL into a special table, and when the server starts, it compares the current DDL with the previous one. If they are the same, the data is truncated, but if there is a difference, all existing tables will be dropped and new ones will be created.
If you don't want to lose your data every time the server starts, comment or delete the ObjectSpaceInitContextListener
declaration inside web.xml
.
Loading data into the database
After generating the schema, SOLoist can initialize the object space. Creating new objects and persisting them is easy: just open the ObjectSpaceInit
class in Eclipse and implement its init()
method. All you need to do is to create objects through SOLoist API, and they will be automagically persisted into the database. Try this:
@Override public void init() throws InitializerFailedException { Doctor d1 = new Doctor(); d1.name.set(Text.fromString("Henry Gray")); Doctor d2 = new Doctor(); d2.name.set(Text.fromString("Joseph Lister")); }
Start the server again. Now, take a look at the database (look for the doctor
table) or use SOLoistExplorer (http://localhost:8080/EmptySOLoistProject/oql
).
Next Steps
At the moment, EmptySOLoistProject has a very simple GUI - a "Hello World" label inside the vertical panel. Look for the EmptyApplication
class in Eclipse. You could explore GUI API yourself, but we advise you to go through this tutorial.