Publish your first MAMS service
This example publishes a resource at /main/hello. An HTTP client can read and update its name field. When the field is replaced, the ASTRA agent prints a greeting.
Complete the ASTRA Quick Start first. Use Java 17 or later and Maven. The example uses ASTRA 2.6.1 and MAMS 2.4.1, checked against source commit 280367e (see Versions and source material). Familiarity with CArtAgO artifacts helps explain the implementation, but you can run the example without writing an artifact yourself.
Create the project
Create a directory called mams-hello with this structure:
mams-hello/
pom.xml
src/main/astra/Main.astra
src/main/java/Hello.java
The complete sample POM, ASTRA agent and Java data class are included with this guide.
Use this pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.astralanguage</groupId>
<artifactId>astra-cartago-base</artifactId>
<version>2.6.1</version>
<relativePath/>
</parent>
<groupId>examples</groupId>
<artifactId>mams-hello</artifactId>
<version>0.1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>mams-cartago</id>
<url>https://gitlab.com/api/v4/projects/19479774/packages/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>mams-ucd</groupId>
<artifactId>mams-astra-javatypes</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
</project>
The CArtAgO parent configures the ASTRA build. The Java-Types dependency supplies the MAMS agent classes and resource artifacts, including their core dependencies. MAMS artifacts are obtained from the project’s GitLab Maven registry.
Describe the resource data
Put this in src/main/java/Hello.java:
public class Hello {
public String name;
}
Keep this first data class simple: a public class, a public no-argument constructor (implicit here), and public instance fields. The resource implementation uses reflection to turn fields into observable properties and reconstruct Java objects. If you put the class in a package, use its fully qualified name when creating the resource.
Create the agent and its body
Put this in src/main/astra/Main.astra:
agent Main extends mams.javatypes.Passive {
module ObjectAccess oa;
plan +!main(list args) {
mams.MAMSAgent::!setup();
mams.MAMSAgent::!created("base");
mams.javatypes.Passive::!itemResource("hello", "Hello");
}
plan +!itemUpdated(string ArtifactName, Object Value) {
console.println("Hello, " + oa.getString(Value, "name"));
}
}
setup() starts the local CArtAgO service and creates the shared web server on port 9000, together with a REST client. Use setup(9001) to choose another port. Call setup once per application.
created("base") creates the agent’s resource base and connects it to the server. itemResource("hello", "Hello") attaches an individual Java-Types item beneath that base. It also focuses the agent on the artifact so it can receive observations and signals.
The inherited passive class translates a replaced signal into the itemUpdated goal. The second plan handles that goal. Its Object parameter matches the inherited notification interface; ObjectAccess reads the Java object’s name field. The inherited class also supplies the console and cartago modules.
Run the service
From mams-hello, run:
mvn clean compile astra:run
Leave this terminal running. The server exposes the main agent under /main and the item under /main/hello. Startup output includes the agent’s base URI. Use that host and port if your environment reports a different address.
Read and update the resource
From a second terminal:
curl -i -H 'Accept: application/json' \
http://localhost:9000/main/hello
The initial response is 200 OK with:
{"name":""}
Replace its state:
curl -i -X PUT \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name":"Rem"}' \
http://localhost:9000/main/hello
With the verified MAMS 2.4.1 setup, this returns 200 OK and {"name":"Rem"}. The agent prints:
[main] Hello, Rem
Repeat the GET to confirm the stored state. The greeting is an asynchronous reaction to replacement: receiving the HTTP response does not guarantee that every agent plan triggered by the update has finished.
Use Accept: application/json explicitly in these requests. Content-Type describes the request body; Accept selects the response representation.
Stop the service with Ctrl+C when you finish. Next: Manage resources and their state.
Troubleshooting
Dependencies cannot be resolved: check the GitLab Maven repository URL, network access and the requested MAMS version. An existing local Maven cache can satisfy a build without proving that a fresh download works. Use MAMS
2.4.1consistently across dependencies; see the verification checks for a build with an isolated repository.The server cannot bind: stop another process using port
9000, or change the setup goal and request URLs to a free port.A resource returns 404: check the running agent’s name, the path and whether resource creation completed.
The data class cannot be loaded: confirm the class is in
src/main/javaand that the resource creation goal uses its exact Java class name, including its package.The greeting does not appear: check that the PUT succeeded and the
itemUpdatedplan matches the inheritedObjectnotification. A GET reads state; it does not replace it.