This is a collection of questions/issues that arose from my teaching of Agent Oriented Programming, where I have assessments in SARL and SWI-Prolog, all packaged with Apache Maven.
If you think a question is worth putting it here, please let me know, I am happy to add it! THANKS!
SARL documentation includes three FAQs that you may want to check first:
NOTE: Many of the answers here are almost verbatim explanations from SARL developer Stéphane Galland to my email enquires :-)
Finally, there is also the official SARL Google Discussion Forum at:
https://groups.google.com/g/sarl
Remember to follow good online forum etiquette when posting there
- SARL FAQ and Issues
- Table of Contents
- Syntax
- HOW-TO
- Emit an event in a "compact" way
- Emit an event with a scope
- How to spawn an agent and keep its UUID identification?
- How can I know when an agent has been created fully after being spawn?
- Can I make SARL wait in the execution on some thread?
- Emitting events and spawning agents in "
on Intialize
" behaviors: be careful! - More details on how events and spawning are processed by the SARL execution engine
- Maven Usage/Support
- Useful Maven commands
- Dependencies via JitPack service
- Produce JAVADOC for the application
- Produce JAR files with all sources
- Define a booting class
- How do I install a JAR dependency manually?
- How do I tell maven to work offline (not check anything on the internet)?
- Why maven is not downloading the sources of dependencies?
- Maven can throw lots of warnings and xml messages, how do I filter them?
- How can I pass arguments to Maven? For example, variable
java.library.path
? - How to configure testing disabled by default?
- ECLIPSE IDE
- Troubleshooting
- I get "no compiler is provided" error, why?
- List of compile and run-time errors
- Discouraged use of the feature
occurrence
. You should not use the featureoccurrence
- The field
X
should be synchronized for avoiding value inconsistency due to parallel execution - I cannot pass data to the
Initialize
of a Behavior,occurrence.parameters
is always empty! - Cannot access agent owner of a skill in
Initialize
behavior, why? - SARL is giving lots of WARNINGS at compile time, how can I avoid them?
- Remove warnings when running the SARL application
- SARL & SWI-PROLOG via JPL Connectivity
- Changes SRE 2.x to SRE 3.x
- Links and Pointers
Because it uses and builds on XTEND framework.
To check particular SARL syntax and slight differences with Java, please check Section 5.1 in the documentation.
Note directly from SARL developer (Sept 2018): SARL extends a part of Xtend dialect in order to have benefits of several background features, such as the validation tests for type inheritance. Since Xtend and SARL uses Xbase, a large part of the syntax is the same, especially within the blocks of code. (The rest of the syntax is defined in parallel. SARL was inspired by languages such as Scala, Python and Ruby. Several bugs or incoherence of Xtend are fixed in SARL.
There is still a bit of an issue inside the Xbase library; check this sarl/sarl#852 (comment)
I have created an issue regarding null == value
: Issue #854. According to the associated discussion within the Xbase group #300, the error message will be updated to push the developers to use ===
.
^
is the SARL convention for escaping reserved keywords like agent
and skill
. So, if you want to use skill
as a variable name you have to say ^skill
.
Check the answer here.
So, this
is like in Java, the current object; whereas it
is the object in the lambda expression.
Instead of Java casting (X) Y
, SARL uses the format X as Y
. For example:
this.chargingStations.put(facility.name, facility as ChargingStationData)
See Cast and Type Conversions in SARL documentation.
Inspired by other modern programming languages, SARL comes with many "short-hands" to make the life of programmers easier and the code cleaner.
One of them is Active Annotations which allows, among other things, the easy definition of "getters" and "setters". For example, by writing:
@Accessors var name : String
SARL will automatically generate the methods getName()
and setName(name: String)
.
In turn, extension methods allow you to add new methods to existing types without modifying them.
So, we can write occurrence.getEntityState
to denote getEntityState(occurrence)
(as if the class of occurrence
had been extended with the getEntityState
method).
Instead of:
emit(new E_EntitySensed(last_step, entityName, percepts))
one can write:
emit(new E_EntitySensed => [it.last_step = last_step, entity = entityName, perceptData = percepts])
See how we use it.last_step
to refer to the property in the event. The compiler searches for a variable of name v
following the steps:
- if a local variable named
v
is accessible, it is used; - if an attribute for
it
, i.e.it.v
, it is used; - if an attribute for
this
, i.e.this.v
, it is used; - if a variable
v
is statically imported, it is used.
This will emit the event to agents with addresses a1
and a2
only. The it
refers to the receiver agent.
emit(new MyEvent) [ it == a1 || it == a2 ]
The above emit uses scopes with Lambda expressions and implicit variables.
Consdier for following line in the English Auction Tutorial:
emit(new Bid(newPrice)) [ it.ID == defaultContext.ID]
The objective of this line is that only the Auctioneer agent sees the bid. This is how.
The above event is emitted with a scope defined, that is, restricting the agents who will see the event. More concretely, it emits the event Bid
with the receiver agent (denoted by it
)'s id (denoted by it.ID
) equal to the ID of the default context of the Bidder agent emitting the event (that is, defaultContext.ID
).
In this particular example, because the Bidder agent emitting the event is in fact a Holon agent inside the Auctioneer agent's inner context, then the default context of the Bidder is indeed the inner context of the Auctioneer. In turn, the ID of an inner context is always the same as the ID of the corresponding agent.
All in all, defaultContext.ID
is the ID of the default context of the Bidder, which is the ID of the inner context of the Auctioneer, which is the ID of the Auctioneer agent. And the event is only seen by the Auctioneer as desired. :-)
Before 0.11.0
there was a spawning mechanism that will return the UUID
of the agent created. From 0.11.0
, one has to create a UUID
and then spawn the agent with that id:
import io.sarl.core.DefaultContextInteractions
//val agent_UUID2 = UUID::randomUUID; // more "SARLish" way
val agent_UUID = UUID.randomUUID();
spawnInContextWithID(TestAgt_Slave, agent_UUID, defaultContext, 200)
<here you can refer to agent_UUID>
An event AgentSpawned
will be emitted when an agent has been created and can be handled, say by a coordinator, to know the agent is now alive! Fo example:
on AgentSpawned {
info("Agent {0} of type {1} has been created successfully and is now alive!",
occurrence.agentIdentifiers, occurrence.agentType)
}
Yes, use something like TimeUnit.SECONDS.sleep(5)
Check here
When the event e
is received by an agent the following algorithm is applied:
if "on Initialize" is currently running then
add e to a buffer of events.
else if "on Destroy" is currently running then
ignore the event.
else
fire(e)
fi
The function fire(e)
retrieves all the "on E
" and runs them in parallel, and there is a synchronization point after the running of all the "on E
" if E
is Initialize
or Destroy
(for forcing synchronous execution of "on Initialize
" and "on Destroy
"). At the end of the "on Initialize
" (after synchronization point), all the buffered events are fired.
Observe that if the event is fired from within the "on Initialize
", the same algorithm is applied whatever the receiving agent.
Regarding spawn()
, the function runs in two parts:
- First, the spawn agent is created. This part is run in the same thread as the caller of spawn, so the spawn call blocks.
- Once the spawn agent has been created, the initialization process runs within a separated thread from the spawner agent. So, the call
spawn()
is now not locked anymore. Then, the created thread runs all the initialization process, including the synchronous execution of "on Initialize
". Consequently, the "on Initialize
" of the spawn agent will not block the spawn caller.
First, you should read the Maven Plugin for the SARL Compiler.
mvn compile
(use defaultpom.xml
) ormvn compile -f <pom file>
to compile the application. Compiled classes will be placed intarget/classes
mvn clean compile
for a clean compile from scratch.mvn jar:jar
to produce the compile output into the JARmvn source:jar
to generate the JAR with the sources (if configured in POM)mvn javadoc:jar
to generate the Javadoc undertarget/apidoc
and into a JAR file (if configured in POM)mvn package
to generate all the configured JAR packages intarget/
.mvn install
will install the generated modules in the user~/.m2/
.
If your project has dependencies then you may want the sources of such dependencies to be able to see the source code (e.g., when developing in ECLIPSE).
mvn dependency:sources
: to download sources of ALL dependencies (for example to be able to navigate to the source code when developing in ECLIPSE)mvn dependency:sources -Dartifact=groupId:artifactId:version:packaging
to get the sources of a particular artifact.- For example:
mvn dependency:sources -Dartifact=org.bitbucket.ssardina-research:sarl-agtcity-intf:-SNAPSHOT:jar
- For example:
mvn dependency:get -Dartifact=groupId:artifactId:version:packaging:classifier
to get any artifact.- For example:
mvn dependency:get -Dartifact=org.bitbucket.ssardina-research:sarl-agtcity-intf:-SNAPSHOT:jar:<javadoc|sources|...>
- For example:
This puts the given artifact into your local Maven repository, i.e. usually $HOME/.m2/repository
.
JitPack provides a service to get dependencies directly from Git repository services, like Github and Bitbucket. For example, your SARL application may use a core SARL skill interface that is provided in some Bitbucket service.
Include the JitPack under repositories* section be able to connect to bitbucket system:
<repositories>
...
<!-- JitPack used for remote installation of dependencies from Github -->
<repository>
<id>jitpack.io</id>
<name>JitPack Repository</name>
<url>https://jitpack.io</url>
</repository>
...
</repositories>
For this solution, we shall use the maven-dependency-plugin
by instructing it to package all JAR dependencies into a /dependency-jars/
special directory as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
We should then tell to add the classpath of your project to the manifest and use the special directory we just specified where all JAR dependencies will be copied:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>BootTestAgt</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
More information about how to specified classpaths here.
To be able to execute mvn javadoc:jar
use the maven-javadoc-plugin plugin within the build section of the POM:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
If you want your JAR files to include both Java and SARL sources add this to the build section of the POM:
<build>
<resources>
<resource>
<directory>src/main/sarl</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<filtering>false</filtering>
</resource>
</resources>
...
<\build>
To be able to produce a JAR file with just the sources (via mvn src:jar
) use the maven-source-plugin plugin within the build section of the POM:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
We can tell Maven to use a specific main class when running mvn java:exec
via the exec-maven-plugin plugin.
The standard way to start a SARL application is to use io.janusproject.Boot
as the main class which wil boot a given SARL agent. We can define then such class as the exec class as follows in pom.xml
:
<!-- Class to execute via maven exec:java
https://www.mojohaus.org/exec-maven-plugin/ -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<addClasspath>true</addClasspath>
<mainClass>io.janusproject.Boot</mainClass>
</configuration>
</plugin>
However, if we use a specialized booting class (e.g., BootMAS.sarl
) as explained above we can instead use:
<!-- Class to execute via maven exec:java
https://www.mojohaus.org/exec-maven-plugin/ -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<addClasspath>true</addClasspath>
<!-- THIS WOULD BE THE DEFAULT CLASS TO BOOT
<mainClass>io.janusproject.Boot</mainClass>
-->
<mainClass>BootMAS</mainClass>
</configuration>
</plugin>
Now, when issuing mvn exec:java
class BootMAS
will be started. See above an example of such class that will ask the user what agent to boot-up.
Suppose your application need version 1.2.0.7.2
of artifact sarl-agtcity-mw
from group id org.bitbucket.ssardina-research
, but for some reason it cannot be gathered automatically from the cloud.
Suppose you can get a hold of that dependency and obtain file sarl-agtcity-mw.jar
. How do you install it in the repo? Here it is:
mvn install:install-file -Dfile=sarl-agtcity-mw.jar -DgroupId=org.bitbucket.ssardina-research \
-DartifactId=sarl-agtcity-mw -Dversion=1.2.0.7.2 -Dpackaging=jar
Use the -o
option for offline mode (e.g., mvn -o clean package
): https://www.packtpub.com/mapt/book/application_development/9781785286124/8/ch08lvl1sec81/working-in-offline-mode
Note you will still need to build the system online at least one, so that your system has the chance to get all the dependencies and store them under ~/.m2/
ECLPSE IDE seems to download all sources by default. To get the sources via CLI: mvn dependency:sources
To state the POM to get all sources (and javadocs) of dependencies, check this post
To remove the WARNING mesages:
mvn exec:java | grep -v -e WARNING
mvn clean package | grep -v -e WARNING
To also remove all the print out of xml messages (e.g., the ones thrown by the Massim EIS for the Agents in City game):
mvn exec:java | grep -v -e \<.*> -e WARNING -e '^ sent' -e '^ received'
You can use the MAVEN_OPTS
environmnt variable that will apply to all calls to Maven. For example:
export MAVEN_OPTS=-Djava.library.path=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/
We use the Maven Surefire Plugin with skipping by default:
<properties>
<skipTests>true</skipTests>
</properties>
<!-- JUNIT testing framework -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--<scope>test</scope>-->
</dependency>
<build>
<testSourceDirectory>src/java/org/jpl7/test</testSourceDirectory>
...
<plugin>
<!-- Unit test execution -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<!-- Check this: https://maven.apache.org/surefire/maven-surefire-plugin/examples/skipping-tests.html -->
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
....
</build>
Then, we can enable the tests via mvn surefire:test -DskipTests=false
- Make sure the JRE for the project is 1.8, not below.
Some plugins you may find useful:
- Prolog Development Tool. For Prolog development, though it may be best to use VSCODE. May not be compatible with the latest IDEs.
- Markdown text editor. There are other similar options in ECLIPSE Marketplace.
- EasyShell: allows to open a shell window or file manager from the popup menu in the navigation tree or editor view.
The ECLIPSE IDE for SARL 0.11.0 does not pickup the Janus SRE when using Java 11:
This is fixed in SARL 0.12.0 but can be resolved by using Java 8 to launch the SARL ECLIPSE IDE. To do so, add the -vm
option to eclipse.ini
as follows:
-startup
plugins/org.eclipse.equinox.launcher_1.5.700.v20200207-2156.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.1200.v20200508-1552
-vm
/usr/lib/jvm/java-8-openjdk-amd64/bin
-vmargs
-Xms256m
-Xmx1g
Also make sure to set the Java JRE in ECLIPSE to OpenJDK 8.
See issue #1057.
The IDE may incorrectly report errors of undefined entities (e.g., properties or methods). These are reported in the code, but not in the "Problem" section. The system compiles well. For example:
One way to solve this is to close and re-open the file giving the mistaken error.
This is a "strange behaviors" due to the Xtext
framework on which the SARL compiler is based and it happens when SARL is upgraded.
When upgrading, the following is recommended:
- fix the SARL versions in the POM file in order to have the exact same versions as in the SARL IDE;
- do a full Maven compilation (on command-line if possible);
- if the errors are still present, remove the project form ECLIPSE (without removing the code files), delete by hand the ECLIPSE project files (
.project
,.classpath
,.settings
), and import back the project into the Eclipse IDE, as a "SARL Maven project".
Check full explanation in issue #1056.
Somehow Maven is failing to grab the dependencies. Assuming there is network connection to the Internet, update the Maven local repo by doing right click on the project, then select Maven
, then Update Project
and make sure to select Click Force Update of Snapshots
.
Make sure you:
- Have JDK installed in your system (the Java development framework that comes with the compiler
javac
), not just the Java runtime environment JRE. - Your
PATH
environemnt variable points to the directory wherejava
andjavac
of the JDK where installed. - Your
JAVA_HOME
points to the directory where the JDK was installed. Alternative, you will need to specify it in yourpom.xm
; see here .
Here is the list of SARL compiler errors
Here is a list of Janus run-time errors
A discussion on this can be found in the forum here
Basically, the SARL compiler is informing that it was not able to infer that the variable event specified in variable occurrence
was a read-only structure. It is intended that an event is read-only because the same event an be handled by different on behavior rules and one would like all behaviors to receive the same event structure/data regardless of the order in which they are executed.
Check errors 28a/b/c
SARL may produce highly concurrent executions, as all the on
behaviors that apply for an event are meant to be executed in parallel.
Consider this code:
on toto {
do smthg with t // code A
}
on tata {
do smthg with t // code B
}
If both events toto
and tota
are emited, code fragments A and B may run together and hence have write access to data t
.
SARL will give this warning, calling the user to add explicit synchronization. This can be done in a few ways:
- Use auto-sych auto-synchronized types (e.g. AtomicInteger, CopyOnWriteArrayList, ConcurrentHashMap, etc.)
- In functions we can use
syncrhonized def
. - Use
synchronized
code in programs and expressions.
SARL language provides the synchronized keyword:
val lock_t : ReentrantLock = new ReentrantLock();
// val lock_t : Object = new Object()
on toto {
synchronized (lock_t) {
do smthg with t // code A
}
}
on tata {
synchronized (lock_t) {
do smthg with t // code B
}
}
Even more powerful, synchronized
can be used on data directly:
on toto {
synchronized (lock_t) {
do smthg with synchronized(t) { t } // code A
}
}
on tata {
synchronized (lock_t) {
do smthg with synchronized(t) { t } // code B
}
}
Note: SARL compiler tries to be smart and find out whether there is an issue with certain data. For inmutable data, like Strings, SARL should not give warnings, as two threads can never modify the same object. See this issue.
Not anymore an issue from 0.9, has been resolved in this issue.
For versions 0.8.6 or less:
From SARL developer in this post:
Currently, there is no way to set the occurrence.parameters
values with the current API.
The Initialize
event is fired by the registerBehavior
function. As you could see, this function does not provide a mean for passing initialization parameters.
I think the ability to set the Initialize parameters when registering the behaviors is a missed feature from the SARL API.
You could use the following work around:
behavior MyBehavior {
var initParam : Object[]
new (owner : Agent, initParam : Object*) {
super(owner)
this.initParam = initParam
}
on Initialize {
// Do something with this.initParam
}
}
agent MyAgent {
uses Behaviors
on Initialize {
var beh = new MyBehavior(this, "p1")
beh.registerBehavior
}
}
Note that because registration happens after the creation of the behavior module, the initParam
will be available at time of Initialize
execution.
Summary in this thread
The owner of the skill is set when the skill is attached to the agent. It means that the owner cannot be known within the constructor of the skill. The function install
is invoked just after the skill is installed into the agent.
So:
new {
super()
assert this.owner === null
}
def install {
assert this.owner !== null
}
Importantly, the initialization (via Initialize
event) is not at creation time (constructor) but when the entity is attached to the agent.
Within SARL developers' perspective, constructor statements should be redefined only if you want to set the value of a field that is final (val
keyword), because it is mandatory regarding the semantic of the val keyword.
Consequently, the best practice is that all initializations should be within the on Initialize
. They should avoid constructor definition.
So, the "clean" way to access the agent owner is in the install
method:
skill SWIJPL_KB_Prolog implements KB_Prolog {
var module_name : String
def install {
module_name = this.owner.ID.toString
}
...
}
Check here
A list of what can be @SupressWarnings
can be found here
One can suppress ALL warnings using @SuppressWarnings("all")
Run like this:
$ mvn exec:java | grep -v -e WARNING
When using SWI Prolog from Java I recommend checking:
- The JPL documentation maintained by Paul Singleton, which has information on:
- How to access Java from SWI Prolog code: The Prolog API side of JPL
- How to access SWI Prolog from Java code: The JAVA API side of JPL
- The types of queries available: One-shot vs Iterative
- How multi-threading queries work under JPL.
Please refer to this entry in the JPL documentation. (Note: that is from 2018; it may be fixed in newer versions)
Check here
There could be many reasons and it may depend on the OS you are using. You need to have SWI-Prolog, JPL package, and the right environment variables set-up.
Check this question
Basically you need to let the system know which SWI Prolog is installed and you want to use.
If you are using a Linux distribution install, you would do something like this:
export SWI_HOME_DIR=/usr/lib/swi-prolog/
export LD_LIBRARY_PATH=$SWI_HOME_DIR/lib/x86_64-linux/:$SWI_HOME_DIR/lib/amd64/:$LD_LIBRARY_PATH
export LD_PRELOAD=libswipl.so:$LD_PRELOAD # only if necessary and your app complains
The reason why we have two library paths is that lib/amd64/
is used for SWI 7.6.4, whereas lib/x86_64-linux/
is used in 8.x.x versions.
If, instead, you compiled the SWI from git sources and installed at /usr/local/swipl-git
, you would do something like this:
export SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/
export LD_LIBRARY_PATH=$SWI_HOME_DIR/lib/x86_64-linux/:$SWI_HOME_DIR/lib/amd64/:$LD_LIBRARY_PATH
export LD_PRELOAD=libswipl.so:$LD_PRELOAD # only if necessary and your app complains
- A system variable
SWI_HOME_DIR
points to the root of SWI install. - System variable
Path
should include%SWI_HOME_DIR%\bin
and%SWI_HOME_DIR%\lib\jpl.jar
.
There could be many reasons and it may depend on the OS you are using.
First of all, make sure you have SWI-Prolog installed, either:
- Stable version 7.6.4 as per standard Linux repository or executable install from SWI page.
- Compiled 8.1.x+ version from swipl-devel repo.
- Note current (Feb 2019) stable 8.0.x version has a problem with
libswipl.so
which makes JPL crash.
- Note current (Feb 2019) stable 8.0.x version has a problem with
Second, make sure you also have the JPL package installed in the system. This is an additional SWI module, it is not part of the core.
- In Windows, it is easy as you can click to install JPL Java<-->SWI interface at installation time.
- You should see
jpl.dll
file in%SWI_HOME_DIR%/bin
andjpl.jar
in%SWI_HOME_DIR%/lib
.
- You should see
- In Linux, you need to make sure
libjpl.so
andjpl.jar
are somewhere! If you cannot find it, then you may need to install JPL.- In Ubuntu, it is provided with package
swi-prolog-java
. - In ARCH, you can generate it and install it using AUR package builder and
swi-prolog-git
package. Running the default PKG build file is enough to get JPL installed. - In MAC, we don't know how to make it work, as there is a glitch in one of the packages built for Mac... :-( [if you make it work, please let me know!]
- In Ubuntu, it is provided with package
Finally, make sure your system is aware of both SWI and JPL by setting the appropiate env variables; see previous above.
If you are using SARL, you may also refer to the instructions of the SARL Prolog Capacity
To understand the environment library LD_PRELOAD
check this post and this one about library preloading. Also, check this and this posts.
SARL version 0.11.0 had a major change: it now uses Janus SRE 3 (the run-time environment for SARL). The new Janus is written in SARL itself rather than Java.
Here we list some of the changes you may encounter when migrating previous SAR systems (0.10.x and before).
In the old SRE 2.x, one would start an agent from Java by directly using the Boot
class in Janus:
import io.janusproject.Boot
...
Boot.startJanus(typeof(DummyMultiCarController))
In order to avoid any problems due to changes into the Janus implementation, in SRE 3.x it is preferable to use the SRE
utility class as follows:
import io.sarl.bootstrap.SRE
var sre = SRE::bootstrap
sre.startAgent(typeof(DummyMultiCarController))
For more info refer to:
- Sections 1 and 2 on Run SARL Agent from a Java Program.
- Programmatic Access to the SARL Run-time Environment.
While explicitly not recommended, one could still use the "old-way" by using Janus directly via its Boot
class (see Section 3 here:
import io.sarl.sre.boot.Boot;
Boot.createMainObject.startAgent(typeof(DummyMultiCarController))`
Regarding Boot.offline
, this parameter is not any more needed in the kernel of Janus v3. Indeed, the Janus v3 kernel is now based on a new plugin architecture (based on the Bootique API).
With this plugin API, we could write a core software (the kernel) with a minimum set of features and that could be extended with plugins by only adding these plugins on the classpath of the application.
In the context of Janus, the network features were moed into a plugin. One could easily add the network feature by adding the corresponding plugin ja file in the classpath (equivalent to the old Boot.offline = false
) or remove it from the classpath (equivalent to Boot.offline = true
), or even add another networking plugin that is based on another technology (e.g. MQTT, etc.).
So, Boot.offline
function is not any more into the Janus kernel (i.e. the Boot
class) but into the configuration of the networking plugin. This plugin is under validation and is planned to be back in SARL 0.12.x.
Regarding Boot.verboseLevel
, the SRE
utility class provides such a setting. Note that it must be called before any launch of agent since the configuration level of Janus is set at start up. For example:
class BootMAS {
// Code adapted from example how to boot from name string: http://tinyurl.com/ycolmey5
def static main(args : String[]) : void {
var sre = SRE::bootstrap
sre.verboseLevel = 7
// bootstrap.setVerboseLevel(7)
....
See SARL doc coverage on this too.
In SRE 2.x, we could spawn an agent and get their assigned UUID code via the spawn
method in io.sarl.core.DefaultContextInteractions
(here the 200
is a parameter passed to the agent Initialize
behavior rule):
val agent_UUID = spawn(TestAgt_Slave, 200)
This method has been deprecated and all spawning methods are provided by the LifeCycle
capacity/skill.
To spawn an agent and grab its UUID
code, we first generate one and then spawn it with it:
uses DefaultContextInteractions
uses Lifecyle
val agent_UUID = UUID.randomUUID();
spawnInContextWithID(TestAgt_Slave, getDefaultContext, 200)
or more compactly:
uses DefaultContextInteractions
uses Lifecyle
var agent_UUID = UUID::randomUUID
typeof(TestAgt_Slave).spawnInContextWithID(agent_UUID, defaultContext)
The getDefaultContext
will provide the default context of the agent.
This may arise in 0.11.0 when using Java 11, but it was fixed in the upcoming 0.12.0 (as per Feb 2021).
The work-around for now is to run SARL ECLIPSE IDE using Java 8 by updating eclipse.ini
and also change the JRE used in ECLIPSE to Java 8.
Check issue #1057 for details.
The cause of the problem may be the new way in which create the JAR file with all dependencies: several service definitions of SARL/Janus services may not be correctly included into the "with-full-dependencies" jar file.
Check issue 1061
- Maven project management and comprehension tool (to meet dependencies, compile, package, run):
- Doc: https://maven.apache.org/general.html
- Great tutorial: http://www.vogella.com/tutorials/ApacheMaven/article.html
- SARL distribution: http://mvnrepository.com/artifact/io.sarl.maven
- JANUS / SRE (for janus.version in pom.xml): http://search.maven.org/#search%7Cga%7C1%7Cjanusproject
- JitPack service for remote installation of dependencies from Github & Bitbucket: https://jitpack.io
- SARL:
- Main page: http://www.sarl.io/
- Github repo: https://github.com/sarl/sarl
- User forum: https://groups.google.com/forum/?hl=en#!forum/sarl
- User Documentation: http://www.sarl.io/docs/official/index.html
- SARL Maven Resository: http://mvnrepository.com/artifact/io.sarl.maven
- SWI Prolog (in case the SARL agent will make use of SWI Prolog knowledgebases):
- Main web page: http://www.swi-prolog.org/
- JPL module for SWI Prolog: a bidirectional link SWI-Prolog and Java
- Home page of JPL: https://jpl7.org/
- Java API - overview: https://jpl7.org/JavaApiOverview.jsp
- JavaDoc: https://jpl7.org/doc/index.html
library(jpl)
: http://www.swi-prolog.org/pldoc/man?section=jpl
- SARL-PROLOG-CAP: Prolog capacity for SARL and SWI-Prolog skill for it.
- Provides basic Prolog actions. The SWI skill for it uses SWI Prolog and JPL framework.
- In JitPack: https://jitpack.io/#org.bitbucket.ssardina-research/sarl-prolog-cap
- Elevator Simulation:
- Java Elevator Simulator (RMIT Version): https://github.com/ssardina-agts/elevator-simulator
- Original simulator: http://elevatorsim.sourceforge.net/
- EI for the Elevator Simulator: https://github.com/eishub/ElevatorSim
- SARL Elevator Middleware: https://github.com/ssardina-agts/elevator-sarl-mw
- SARL Base Controller Framework: https://github.com/ssardina-agts/elevator-sarl-base
- Java Elevator Simulator (RMIT Version): https://github.com/ssardina-agts/elevator-simulator
- Agents in City (from Multi Agent Contest): https://github.com/ssardina-agts/agtcity-server
- SARL Agents in City Middleware: https://github.com/ssardina-agts/agtcity-sarl-mw
- Includes branches for different server versions.
- SARL Agents in City Base Controller for RMIT 2018 server game: https://github.com/ssardina-agts/agtcity-sarl-base
- SARL Agents in City Middleware: https://github.com/ssardina-agts/agtcity-sarl-mw
- SARL Prolog Capacity & Skill: https://github.com/ssardina-agts/sarl-prolog-cap