3 releases (breaking)

0.3.0 Jul 29, 2021
0.2.0 Oct 25, 2020
0.1.0 Sep 20, 2020

#2197 in Command line utilities


2.5K SLoC


Jcr Exchange

CI status badge Crates.io version Code coverage License

About | Installation | Configuration | License | Contribution

Built with 🦀


Small utility for uploading/downloading content to/from running AEM instance.

It's intended to be used as an external tool for IntelliJ IDEA to make content synchronization easier.

je 0.3.0
Jcr Exchange - easy download and upload files to and from JCR


    -d, --debug      If enabled, deployed to AEM packages are left intact (are not deleted) to allow investigation
    -h, --help       Prints help information
    -V, --version    Prints version information
    -v, --verbose    Enables logs: -v - enables INFO log level -vv - enables DEBUG log level

    -p, --profile <profile>    Profile selection

    get           Downloads content to local file system
    get-bundle    Downloads bundle (pack of crx paths) defined in config file
    help          Prints this message or the help of the given subcommand(s)
    init          Initializes configuration file
    put           Uploads content to AEM instance
    reinit        Rewrites the configuration file with newest version


Standard installation

  • go to releases page
  • download the latest je archive for your OS
  • extract it
  • include path to je executable into your PATH variable

Rust programmers


cargo install je


cargo install --force je



Configuration file is not required. Without it, je will use default configuration. However, you can still initialize config and change it. The default configuration is also the initial one:

❯ je init
❯ cat .je
ignore_properties = []

name = "author"
addr = "http://localhost:4502"
user = "admin"
pass = "admin"


Here is more complex configuration with description of its fields:

ignore_properties = [{ type = "contains", value = "jcr:createdBy" },
                     { type = "regex", value = '.*=\[]' }]

name = "author"
addr = "http://localhost:4502"
user = "admin"
pass = "admin"

name = "publish"
addr = "http://localhost:4503"
user = "admin"
pass = "admin"

name = "configs"
files = ["/apps/my-app/config", "/config/my-app"]

name = "dam"
paths = ["/content/dam/my-app/thumbnails", "/content/dam/my-app/files"]
  • ignore_properties - tell je which properties of .content.xml should be removed after downloading the content; currently, two types of ignoring mechanisms are available:
    • contains - executes line.contains(value) on each line
    • regex - executes regex.is_match(line) on each line, it uses Perl-style regular expressions
  • profile section - you can add multiple profiles, each with settings:
    • name - name of the profile, later it can be used with --profile option to specify which instance is the target; if not specified, the first profile from the config is used
    • addr - address of the instance, including port if domain is not available
    • user - user used to authenticate to AEM instance
    • pass - password used to authenticate to AEM instance
  • bundles section - you can define packs of files which will be synchronized in one run:
    • name - name of the bundle, it can be later used with --bundle option to specify which file pack to synchronize
    • paths - which file paths are part of the bundle

⚠️ If you used older version of je, then you can transform the configuration file to the new form. Details below.

Details `je reinit` will change:
ignore_properties = ["jcr:created", "jcr:createdBy"]

# (...)


version = "0.3.0"

type = "contains"
value = "jcr:created"

type = "contains"
value = "jcr:createdBy"

# (...)

which is equivalent to:

version = "0.3.0"

ignore_properties = [{type = "contains", value = "jcr:created"},
                     {type = "contains", value = "jcr:createdBy"}]

# (...)

You can use any of those two formats. The difference is the result of this issue.

IntelliJ Setup

Add je commands:

  1. Go to Settings -> Tools -> External Tools.
  2. Add new external tool using + sign.
  3. Configure the tool like on the screenshot below.

je get configuration

Similarly add and configure je put command:

je put configuration

  • if you don't have je in PATH, you can set full path in Program input
  • Arguments input:
    • -vv - sets verbose level, -vv means DEBUG log level, -v means INFO log level; it's optional
    • --profile - sets target profile; if not provided, first profile from config will be used
    • -d - sets debug mode in which temporary packages uploaded to AEM won't be deleted to allow validation during debugging; it's optional
    • subcommand (put or get)
    • $FilePath$ - IntelliJ variable which will be substituted during command execution, its absolute path to a file on which command is executed
  • Working directory input:
    • set to $ProjectFileDir$ allows running je from the project root
    • keep in mind that je will try to read config file from the set working directory

Configure key bindings:

  1. Go to Settings -> Keymap -> External Tools.
  2. Find the commands added previously.
  3. Set keyboard mapping by Right Click -> Add Keyboard Shortcut

key mappings


This project is licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

See CONTRIBUTING.md for hints on how to contribute to je.


~427K SLoC