> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/developer-guide/set-up-your-environment.md).

# Set up your environment

Create a local project with the OpenIAM libraries on the classpath, in VS Code or Eclipse, so scripts compile before you deploy them.

OpenIAM's customisation points are Groovy scripts. They run inside the platform's JVM, against the platform's classes, inside its Spring context — which is why a script that looks correct in a text editor can fail to compile the moment it is saved.

This page sets up a local project with the OpenIAM libraries on the classpath, so your IDE resolves the classes you extend, completes their methods, and tells you about a mistake before the platform does.

## What this builds, and how long it takes

|                |                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------ |
| **You get**    | A Maven project that compiles OpenIAM Groovy scripts locally, with completion and error checking in your IDE |
| **Time**       | 20 minutes                                                                                                   |
| **You need**   | A workstation, and the repository details from your OpenIAM account team                                     |
| **Reversible** | Yes — nothing here touches a deployment                                                                      |

**You do not have to work this way.** Scripts can be written directly in the Groovy Manager in the Webconsole, which compiles on save. For a one-line change that is faster. For anything you intend to keep, source control and a compiler on your desk are worth the twenty minutes.

## Before you start

|            | Version            | Why this one                                                                                                                                                                |
| ---------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **JDK**    | **21**             | The platform compiles and runs on 21. A script compiled against an earlier JDK may still load, but you lose the guarantee that what compiles locally compiles on the server |
| **Groovy** | **5.0.4**          | The version the platform embeds. Language features added after it will not compile on the server                                                                            |
| **Maven**  | 3.9 or later       | Any recent version                                                                                                                                                          |
| **An IDE** | VS Code or Eclipse | Both are covered below                                                                                                                                                      |

Confirm the JDK before anything else, because getting it wrong produces errors that look like missing classes:

```bash
java -version
mvn -version
```

**Expected:** Java 21 from both, and Maven reporting the same JDK it will compile with.

## Set these first

```bash
export OPENIAM_VERSION=<the release you are developing against>
export OPENIAM_REPO=<the repository URL from your OpenIAM account team>
```

**Scripts are compiled against a release.** The classes change between releases, so a project built for one is not automatically right for another.

***

## Build it

### 1. Add the OpenIAM repository

The classes your scripts extend ship as Maven artifacts. Add the repository to `~/.m2/settings.xml`:

```xml
<settings>
  <profiles>
    <profile>
      <id>openiam</id>
      <repositories>
        <repository>
          <id>openiam-public</id>
          <name>OpenIAM public releases</name>
          <url>OPENIAM_REPO</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>openiam</activeProfile>
  </activeProfiles>
</settings>
```

**The repository is read-only and needs no credentials.**

### 2. Create the project

```bash
mvn archetype:generate \
  -DgroupId=com.example.openiam.scripts \
  -DartifactId=openiam-scripts \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.5 \
  -DinteractiveMode=false
cd openiam-scripts
```

Replace the generated `pom.xml`:

{% code overflow="wrap" %}

```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>

  <groupId>com.example.openiam.scripts</groupId>
  <artifactId>openiam-scripts</artifactId>
  <version>1.0.0</version>

  <properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <openiam.version>2026.8.1</openiam.version>
    <groovy.version>5.0.4</groovy.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.groovy</groupId>
      <artifactId>groovy</artifactId>
      <version>${groovy.version}</version>
    </dependency>

    <!-- The data model: users, roles, groups, attributes, the provisioning diff
         model, LineObject. Almost every script needs this one.
         The artifact is openiam-common-intf. openiam-common is an aggregator POM
         and carries no classes. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>openiam-common-intf</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- Connector attribute model. Every policy map script needs this. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>connector-client-api</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- AbstractIPolicyMapGroovy and the principal generators. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>idm</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- Transformation, validation and attribute base classes. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>synchronization</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- Reconciliation command base classes. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>reconciliation</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- The services scripts reach with @Autowired or getBean. -->
    <dependency>
      <groupId>org.openiam</groupId>
      <artifactId>openiam-mq-services</artifactId>
      <version>${openiam.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <sourceDirectory>src/main/groovy</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>org.codehaus.gmavenplus</groupId>
        <artifactId>gmavenplus-plugin</artifactId>
        <version>4.1.1</version>
        <executions>
          <execution><goals><goal>compile</goal></goals></execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
```

{% endcode %}

**`provided` is deliberate.** The platform supplies these at runtime. You compile against them; you never package them.

### 3. Mirror the server's folders

```
src/main/groovy/
  provision/     policy map scripts
  sync/          transformation, validation and attribute scripts
  recon/         reconciliation scripts
  batch/         batch task scripts
```

**Do not add a package declaration.** Of the scripts shipped under `conf/iamscripts/`, the large majority declare no package at all, and those that do use no single convention. The platform identifies a script by its name and its folder.

**The class name must match the file name** before the version suffix: `MemberOf_1.0.groovy` declares `class MemberOf`.

### 4. Set up VS Code

1. Install the **Extension Pack for Java** and a **Groovy** language extension.
2. Open the project folder. VS Code detects the `pom.xml` and imports it.
3. **Ctrl+Shift+P** → *Java: Configure Java Runtime* → Java 21.

**Reload the window after changing `pom.xml`.** VS Code's Java support caches the classpath and does not always notice.

### 5. Or set up Eclipse

1. Install **Eclipse IDE for Enterprise Java and Web Developers**.
2. Install **Groovy Development Tools** from the Eclipse Marketplace, and restart.
3. **File → Import → Maven → Existing Maven Projects**, and select the project folder.
4. Right-click the project → **Configure → Convert to Groovy Project**.
5. **Properties → Java Build Path → Libraries** — JRE System Library on Java 21.
6. **Properties → Groovy Compiler** — select the 5.x compiler level.

**If the Groovy nature is missing**, `.groovy` files are treated as plain text and nothing resolves. Step 4 is the one people skip.

***

## Verify it

Create `src/main/groovy/sync/HelloTransform.groovy`:

```groovy
import org.openiam.idm.srvc.synch.dto.LineObject
import org.openiam.provision.dto.ProvisionUser
import org.openiam.sync.service.impl.service.AbstractUserTransformScript

class HelloTransform extends AbstractUserTransformScript {

    @Override
    int execute(LineObject rowObj, ProvisionUser pUser) {
        def columnMap = rowObj.columnMap
        pUser.firstName = columnMap.get("FIRST_NAME")?.value
        pUser.lastName  = columnMap.get("LAST_NAME")?.value
        return NO_DELETE
    }
}
```

```bash
mvn clean compile
```

**Expected: `BUILD SUCCESS`.**

Then open a shipped script from `conf/iamscripts/provision/` in your IDE and confirm its imports resolve. **If a real script from the platform resolves in your project, your environment is correct** — a stronger check than compiling your own file, because the shipped scripts use more of the API.

## If it goes wrong

| What you see                                                    | What it means                                                           | What to do                                                                                                                  |
| --------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `Could not resolve dependencies for org.openiam:...`            | The repository is not configured, or the profile is not active          | Check `~/.m2/settings.xml`, and that `openiam` is in `activeProfiles`. `mvn -X compile` shows which repositories were tried |
| A specific version is not found                                 | `openiam.version` does not match a published release                    | Set it to the release you are developing against                                                                            |
| `unable to resolve class` in the IDE but `mvn compile` succeeds | Stale IDE classpath                                                     | VS Code: reload the window. Eclipse: **Maven → Update Project**                                                             |
| `.groovy` files have no highlighting or completion              | Eclipse: the Groovy nature is not applied. VS Code: no Groovy extension | Eclipse: **Configure → Convert to Groovy Project**                                                                          |
| Compiles locally, fails on save in the Groovy Manager           | Local Groovy or JDK does not match the platform                         | Groovy 5.0.4, JDK 21                                                                                                        |
| `unable to resolve class` for a class you can see in a jar      | The dependency providing it is missing                                  | Match the import to the artifact in step 2                                                                                  |
| A script compiles but an injected service is null at runtime    | Injection resolves inside the platform's Spring context, not locally    | This cannot be reproduced locally. Test on a deployment                                                                     |

## What this procedure does not cover

Running or debugging a script outside the platform. Scripts depend on the platform's Spring context and its injected services, so they are exercised by deploying them — each tutorial shows how its type is triggered and where to look. Also not covered: the connector SDK, and building a connector.

## Related

* [*How scripting works*](/developer-guide/how-scripting-works.md) — read this next
* [*Transformation scripts*](/developer-guide/transformation-scripts.md) — the easiest type to start with

*Applies to OpenIAM 2026.8.1.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/developer-guide/set-up-your-environment.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
