Developer guide

This developer guide provides step-by-step instructions on how to set up your developer environment, contribute to the codebase, and enhance the capability of SysON.

1. Retrieving the Source Code

SysON is built upon the Eclipse Sirius Web project. SysON is licensed under the (EPL v2) Open Source license The source code is openly accessible on GitHub:https://github.com/eclipse-syson/syson

To get the source code, clone the repository using either SSH:

git clone git@github.com:eclipse-syson/syson.git

or HTTPS:

git clone https://github.com/eclipse-syson/syson.git

2. Setting Up your Development Environment

  1. Download your coding environment Spring Tools 4.22.0 (or newer).

  2. Ensure that m2e version from your environment is >= 2.6.0

    m2e version
  3. Retrieve the source code or fork it if you want to make contribution

  4. Import backend plugins from SysON repository in your workspace

  5. Update settings.xml file from your .m2 folder to give access to other repositories during the build In order to see dependence with access to add in settings.xml, have a look on backend\application\syson-application\pom.xml You need to create access tokens on Github to complete settings.xml.

    settings file
  6. Right click on syson-services module and then Properties>JavaBuildPath>Source Add main/generated folder and remove excluded content and former antlr/grammar You should retrieve the following Java build path

    Java build path
  7. Update Maven project by launching "ALT+F5" shortcut on all modules of your workspace

3. Generate a new version of SysIDE CLI

In the syson-import module, you’ll found a syside-cli-.js file in src/main/resources. This file is used by the import process, to parse the SysML v2 textual files. If you want to update the version on SysIDE used to parse textual files, you need to generate a new version of this syside-cli-.js file.

Here are the steps to follow:

  1. Clone the SysIDE repository from github.

  2. Install pnpm.

  3. Go to the root of your local SysIDE repository.

  4. Execute pnpm install command.

  5. Execute pnpm run build command.

  6. Execute pnpm run --dir packages/syside-cli/ esbuild command.

  7. It produces a your_local_syside_repo/packages/syside-cli/out/index.js file

  8. Get a copy of the your-local-syside-repo/packages/syside-cli/out/index.js file.

  9. Edit this file:

    1. add #!/usr/bin/env node as first line

    2. add src_default(); as last line

    3. rename it to syside-cli.js

  10. Copy the renamed file into your_local_syson_repo/backend/application/syson-import/src/main/resources (overwrite the existing file).

4. Generate a new OpenAPI documentation of REST API

  1. Build and run the syson server locally (using docker compose as example) on http://localhost:8080.

  2. Download the documentation at the url: http://localhost:8080/v3/api-docs/rest-apis.

  3. The swagger-ui user interface is http://localhost:8080/swagger-ui/index.html.

5. Services organization

Since version 2025.10.2, SysON services are organized into several modules to improve maintainability and scalability.

  • Services that query/mutate the model are located in the module syson-sysml-metamodel-services.

    • this module will depend on syson-sysml-metamodel.

    • all services in this module won’t depend on Spring, Sirius-Web or any diagram/table related code.

  • Services that query/mutate the model through Sirius-Web services are located in the module syson-model-services.

    • all services in this module are allowed to depend on Sirius-Web

    • for example, services that query the model through IObjectSearchService.

  • Services that query/mutate a diagram are located in the module syson-diagram-services.

    • all services in this module are allowed to depend on Sirius-Web.

  • Services that query/mutate a table are located in the module syson-table-services.

    • all services in this module are allowed to depend on Sirius-Web.

  • Services that query/mutate a tree are located in the module syson-tree-services.

    • all services in this module are allowed to depend on Sirius-Web.

  • Services that query/mutate a form are located in the module syson-form-services.

    • all services in this module are allowed to depend on Sirius-Web.

  • Services that query/mutate and are transversal/common to any representation are located in the module syson-representation-services.

    • all services in this module are allowed to depend on Sirius-Web.

    • will contain services that can be used in all representations

  • Services will be grouped in classes by their purpose and usage:

    • a service that query the model will be in a class named ModelQueryService.

    • a service that mutate the model will be in a class named ModelMutationService.

    • a service that query the diagram will be in a class named DiagramQueryService.

    • a service that mutate the diagram will be in a class named DiagramMutationService.

    • a service querying label of diagram elements will be in a class named DiagramQueryLabelService.

    • a service modifying the label of diagram elements will be in a class named DiagramMutationLabelService.

    • same for tables, trees, forms, representations.

    • XXXQueryService, XXXMutationService, XXXQueryYYYService, XXXMutationYYYService classes can be split in smaller classes if they contain too many services.

  • In addition to services classes, each module contains two specific services classes which are the entry points for services that are intended to be called from AQL expressions:

    • these classes contain services that are intended to be called from AQL expressions.

    • they are suffixed by AQLService.

    • their only role are to expose services from other service classes.

    • other service classes are not suffixed by AQLService and contain services that are intended to be called from Java code or by AQLService classes.

To help you understand this new organization, and how to add new services, please refer to the schema below:

Services organization schema

Old services that were in the syson-services, syson-diagram-common-view, syson-standard-diagrams-view modules will be migrated to the appropriate new modules in the next releases.

5.1. ServiceMethod

Since version 2025.10.2, SysON also introduce a new utility class called ServiceMethod (in syson-services).

This class is an helper to build AQL service call expressions from type-safe Java method references instead of hardcoded strings.

Why use it: - Refactoring friendly: IDE rename of the Java method updates call sites. - Navigation: find usages works, you can jump to the service implementation. - Fewer string literals, fewer typos. - Produces the exact same AQL strings as AQLUtils helpers.

How it works: - You pass a <b>serializable</b> method reference to one of the factory methods of0, of1, of2, of3…​ for instance methods, or ofStatic0…​ for static methods. The arity suffix equals the number of AQL parameters after self. - The helper extracts the Java method name through the standard lambda serialization hook (reading a SerializedLambda). No service is invoked. - You then call aqlSelf(String…​) or aql(String, String…​) to build the final AQL string, delegating to AQLUtils.

Important: the arguments passed to aqlSelf(…​) and aql(var, …​) are AQL snippets, not Java values. For example use "'declaredName'" for a string literal and ViewFormDescriptionConverter.NEW_VALUE if it already returns an AQL snippet.

When to use which call: - aqlSelf(String…​) when the receiver is self, for expressions like aql:self.myService(…​). - aql(String, String…​) when you target another variable in the AQL context, for example aql:elt.myService(…​).

Type inference: - if the compiler says something like The type X does not define methodName(Object, Object,…​), add a type witness to the factory so it can match the real signature.

Examples:

// setNewValue(Element, String, Object)
ServiceMethod.<FormMutationAQLService, Element, String, Object> of2(FormMutationAQLService::setNewValue).aqlSelf("'declaredName'", ViewFormDescriptionConverter.NEW_VALUE);

// setAsView(ViewUsage, String)
ServiceMethod.<DiagramMutationAQLService, ViewUsage, String> of1(DiagramMutationAQLService::setAsView).aqlSelf("'StandardViewDefinitions::GeneralView'");

// predicate isActor(Element)
ServiceMethod.<ModelQueryAQLService, Element> of0(ModelQueryAQLService::isActor).aqlSelf();