---
name: install4j-projects
description: Read, edit, and create install4j project files (.install4j XML).
  Use for any task involving install4j installer configuration, including
  adding or modifying installer screens, actions, form components, screen
  styles, widget styles, launchers, media sets, JRE bundles, file sets, code
  signing, installer variables, or merged projects. Triggers include any
  mention of 'install4j', '.install4j', 'installer screen', 'installer action',
  'media set', 'launcher', 'JRE bundle', or work in a directory containing one
  or more .install4j files. Do NOT use for general Java/Kotlin programming tasks.
---

# install4j projects

A `.install4j` file is a single XML document describing a multi-platform Java installer: which files to install, what GUI screens to show, what actions to run, what launchers to create, and which target platforms (Windows .exe, macOS .dmg/.pkg, Linux .deb/.rpm) to emit. The install4j IDE, the `install4jc` CLI, and the Ant/Gradle/Maven plugins all consume this file.

## Quick reference

| Task | Where to look |
|---|---|
| Find which beans exist (action / screen / form component / …) | `reference/bean-index.md` |
| Look up properties of a specific bean class | `reference/beans/*.md` (file named in `bean-index.md`) — distinct from `reference/api/beans/`, which is the API base-class Javadoc |
| Schema for project XML structure (root, mediaSet, launcher, …) | `assets/install4j.xsd` (most types and attributes carry inline `<xs:documentation>`) |
| `<serializedBean>` content format | `reference/serialized-bean-format.md` |
| Script bodies (`<validation>`, `<condition>`, `<preActivation>`, `RunScriptAction.script`, …): default imports, implicit parameters, adding `import` statements | `reference/script-bodies.md` |
| Concept overviews (variables, launchers, file sets, code signing, JRE bundles, screens & actions, form screens, services, auto-update, response files, …) | `doc/concepts/*.md` |
| Installer runtime topics (auto-update internals, command-line modes, response files) | `doc/installers/*.md` |
| install4jc / Ant / Gradle / Maven — invocation and plugin setup | `doc/cli/{compiler,ant,gradle,maven}.md` |
| Custom-code Java API — class & method reference (Javadoc) | `reference/api.md`; `reference/api/types-index.md` flat list |
| Custom-code Java API — narrative how-to | `doc/api/*.md` |
| Writing automated UI tests against an installer | `reference/installer-ui-tests.md` |
| Test API — class & method reference (Javadoc) | `reference/api/test.md`; `reference/api/test/types-index.md` flat list. Ships as a **separate Maven artifact** `com.install4j:install4j-test` (also bundled at `$INSTALL4J_HOME/resource/install4j-test.jar`); do NOT confuse with `reference/api/` (the runtime Custom-code API). |
| Starting a new project (which sample to copy, what to rename) | `reference/project-skeleton.md` |
| Pre-built installer applications (updater variants) to drop in | `assets/application-templates.install4j` |
| Worked-example projects | `samples/README.md` indexes them; sources under `samples/` |

## Project XML at a glance

The root element is `<install4j version="…">`. Direct children:

- `<application>` — top-level installer settings: `<languages>`, `<searchSequence>`, `<variables>`, `<mergedProjects>`, `<codeSigning>`, `<jreBundles>`
- `<files>` — distribution tree: `<filesets>`, `<roots>`, `<mountPoints>`, `<entries>`, `<components>`
- `<launchers>` — one or more `<launcher>` elements
- `<installerGui>` — installer applications holding `<screens>` and `<actions>`
- `<mediaSets>` — one `<mediaSet>` per platform/format combination (windows, unixInstaller, macos, …)

## Bean instances

Bean container elements — `<screen>`, `<action>`, `<group>` (screen / action / form-component groups), `<formComponent>`, `<style>` (screen and widget styles), `<application>` (installer applications), `<link>` (in merged-project layouts) — carry a `beanClass` attribute and a `<serializedBean>` child:

```xml
<screen beanClass="com.install4j.runtime.beans.screens.WelcomeScreen" id="2">
  <serializedBean>
    <property name="someProperty" type="string">value</property>
  </serializedBean>
</screen>
```

The schema does not enumerate bean classes or their properties. That knowledge lives in `reference/bean-index.md` (FQN → kind → file) and `reference/beans/*.md` (per-category property tables). Always look up the bean before editing it.

## Workflow: editing an existing project

1. **Read the file in full.** Element references via integer `id` mean a partial read can produce an ID collision. For very large projects, alternatively grep all `id="…"` attributes to find the max before reading the relevant section.
2. **Locate the target** by enclosing tag (`<screen`, `<action`, `<launcher`, `<mediaSet`, …) plus a known attribute (`name`, `id`, `beanClass`).
3. **Look up before editing.** For a `beanClass="…"`: find the FQN in `reference/bean-index.md`, open the listed `reference/beans/<file>.md`. For a non-bean container (`<launcher>`, `<mediaSet>`, `<fileEntry>`, …): find the type in `assets/install4j.xsd`.
4. **Edit.** New elements get `id = max(existing) + 1`. Never re-use, renumber, or reorder existing IDs — they're referenced by `styleId`, `refId`, `targetId`, `fileset`, `mountPoint`, `targetLauncherId`, etc.
5. **Validate** per *Validation* below — `install4jc --test` (or the build-system task that wraps it) is the one tool that catches both schema and code-side errors. Run it before declaring the task done.
6. **Report what changed**, including any new IDs allocated.

## Workflow: creating a new project

Don't author from scratch. Read `reference/project-skeleton.md` — it picks the right sample to copy and lists what to rename. For installer-application blocks (e.g. an updater), copy from `assets/application-templates.install4j`.

## Critical rules

These produce projects that load but break later.

- **`beanClass` must be a real FQN.** Hallucinated names parse and validate, then fail at compile with `ClassNotFoundException`. Confirm in `reference/bean-index.md` first.
- **Only set properties the bean exposes.** Every `<property name="X">` inside `<serializedBean>` must match a row in the matching `reference/beans/*.md` table. The decoder silently drops unknown properties.
- **`id` attributes are integer-valued by convention and globally unique within the file** (the schema types them as strings; the install4j IDE generates integers, except for the literal strings `installer` and `uninstaller` used by installer applications). Other elements reference them (`styleId`, `refId`, `targetId`, `fileset`, `mountPoint`, `launcherId`, …). Never renumber existing IDs.
- **Variable scopes are not interchangeable.** `${compiler:foo}` resolves at build time against `<variables>`. `${installer:bar}` resolves at runtime against installer variables. `${i18n:baz}` resolves at runtime against the language bundle. Wrong scope → empty string at the wrong time. See `doc/concepts/variables.md`.
- **Don't reformat `.install4j` files.** Text content inside script blocks (`<condition>`, `<validation>`, `<preActivation>`, `<postActivation>`, `<initScript>`, `<visibilityScript>`) and inside `<property type="string">` (which carries script-typed properties such as `RunScriptAction.script` and `ConsoleHandlerFormComponent.consoleScript`) is whitespace-significant — reformatting corrupts scripts and paths.
- **`customizedId` is a display alias, not a primary key.** The stable internal reference is `id`. For the install4j Test API: `Session.waitForScreenId(...)` matches the `customizedId` first and falls back to `id` (so a screen with `customizedId="welcome"` is reachable as either `"welcome"` or its integer `id`).
- **Do not write `transformSequenceNumber` on a new project.** When the attribute is absent, install4j treats the file as already up-to-date and skips all schema-migration transforms. install4jc / the IDE will fill the attribute in next time they save. 
- **Look up enum-valued attributes in `assets/install4j.xsd` before using them.** Attributes like `overwriteMode`, `actionElevationType`, `failureStrategy`, `executableMode`, `commentSet` etc. are typed in the schema as enums with a fixed value list. `install4jc --test` schema-validates the file and rejects any value that's not in the enum.

## `<serializedBean>` format

See `reference/serialized-bean-format.md`. In short: `<property name="…" type="…">` for assignments, `<add>` for collection appends, `<entry>` for map puts, `<element>` for array slots.

## Validation

The install4jc binary on this machine is at `@INSTALL4JC_PATH@` — invoke it via that absolute path. This skill targets install4j **`13.1`**: the bean catalog, schema, and `samples/` were generated from that version. When creating a new project, set `<install4j version="13.1" …>` on the root element. When editing an existing project, do not touch its `version` attribute — it is owned by the install4jc binary that wrote the file.
If the path does not exist, fall back to `$INSTALL4J_HOME/bin/install4jc[.exe]` 

Validate by compiling the project. `install4jc --test` does a dry run (no media writes) that schema-validates the file first — failing fast with line-numbered errors when the XML is malformed — and then resolves every `beanClass` on the runtime classpath, compiles every embedded script, and reports whatever else would fail in a real build. One tool, both layers of check.

Cost: tens of seconds to minutes (JVM startup, dist scan, scripts compile). Run once after a coherent unit of work, not after every edit.

How to invoke depends on how install4j is wired into the surrounding build. Read the project's build files (`build.gradle[.kts]`, `pom.xml`, `build.xml`) for the existing install4j task. Setup details and full option lists live in `doc/cli/`:

- `doc/cli/gradle.md` — Gradle plugin (`com.install4j.gradle`); typical task: `./gradlew media`.
- `doc/cli/maven.md` — Maven plugin (`install4j-maven-plugin`); typical goal: `mvn install4j:compile`.
- `doc/cli/ant.md` — Ant task; project-specific target name in `build.xml`.
- `doc/cli/compiler.md` — direct `install4jc` invocation; flag list, license handling, variable overrides.

#### If install4j is not wired into the build yet

Don't fall straight to `install4jc`. **Propose adding the matching build integration** (Gradle plugin if `build.gradle[.kts]`, Maven plugin if `pom.xml`, Ant task if `build.xml`) and let the user accept or decline before modifying build files. The plugin handles dist staging, classpath wiring, license keys, and install4j auto-provisioning — replicating that by hand is error-prone, and modifying build files is meaningful state the user should sign off on.

If the user declines, or there's no build file, fall back to direct `install4jc`:

```bash
install4jc --test path/to/project.install4j
```

`--test` is dry-run (no media writes). Schema failures abort with `Could not load config file …. Reason: Project file does not match the install4j schema. Found N issue(s):`. If `<files>` references built artefacts that haven't been staged on disk, "file not found" errors are NOT schema issues — run the upstream build (`./gradlew assemble` / `mvn package` / etc.) first.

If the build's install4j task narrows scope (`buildIds`, media-type filters, variable overrides), mirror that scope when running `install4jc --test` manually — otherwise validation will report failures from media sets the build never produces. See `doc/cli/compiler.md` for `--build-ids`, `--media-types`, `-D` variable overrides, and the rest of the flag list.

If validation fails because the project's code-signing or notarization config can't be satisfied on this machine (missing certificate, locked keychain, no Apple ID) and you're only validating the project XML, add `--disable-signing --disable-notarization` to skip those checks:

```bash
install4jc --test --disable-signing --disable-notarization path/to/project.install4j
```

