Reloading changes to plugin resources

In Jira development, whenever a resource file like a .js or .css is changed, we are able to refresh the page in the browser and the changes will be loaded. Very convenient, and as expected.

But with Confluence, I’m noticing that any edits to .js or .css files made within the IDE are ignored, and that a full build & deploy cycle of the plugin must be performed for the changes to take effect within Confluence.

What am I missing? Or is this the state-of-the-art of Confluence Server/DC add-on development?

4 Likes

Have you resolved your issue? I’m surprised no other developer is yelling about it:

  • We have a Server / Data Center plugin on Confluence,
  • Since Confluence ~7.15, the reload of JS files stopped working,
  • We have the correct directory in ${plugin.resource.directories},
  • We have the QuickReload plugin installed (but I think it is unrelated),
  • We flush the caches,
  • JS files still don’t load from the disk.

Not being able to hot-reload the Javascript files is a severe impediment to development work on Data Center.

No, still unresolved. The closest technical approach we have is iframes.

Indeed, thought this might be the premier forum to jump into an ongoing discussion of the matter, but so far… just crickets? The current edit / build & reload plugin / reload page dev cycle is killer slow, a truly monumental waste of time and precious life span.

I can’t offer much in the way of support myself from my position, but I did try this out right now using “atlas-create-confluence-plugin” without OSGI config. I am using default js/css file hosted at atl.general. I am able to do a “hard-refresh” of the page and receive changes to the js/css resources without recompiling the plugin.

I generally refer to this page when I have issues with QuickReload. https://developer.atlassian.com/server/framework/atlassian-sdk/automatic-plugin-reinstallation-with-quickreload/

I have only interacted casually with the plugin framework, so sorry if this isn’t super helpful.

@aragot, did you resolve the issue? I’m dealing with the same issue…plugin.resource.directories property is pointing to the right directory but any change in js or CSS file is not being detected by the quick reloader plugin (tested in Confluence 7.13.11 with amps 8.6.0).

@GorkaGalloBustinza Apologies for a late response here, but I was having a similar problem.

Assuming you are using the Plugin SDK, it seemed that many 100s of files were being cached under target/confluence/home/webresource-temp.

Deleting all of these files in target/confluence/home/webresource-temp allowed changes made to JS/CSS files to actually be reflected on the running Confluence instance. However, that folder would quickly fill up again with cached files.

I am unsure of your exact setup but you may be able to devise a script to periodically empty that directory when changes are made, and that may fix your problem.

Happy to provide more details if you’d like!

Thank you, @AndrewMorton . This is the first handle I get on solving this problem. I’m running a script every second now that empties this directory. A little ridiculous, but hey, it works.

EDIT: I just found out that I could complete remove the webresource-temp folder. Removing it stops Confluence from even trying to cache files. So, a little script kills the folder after every start of Confluence DC (because the folder is recreated on every start).

1 Like

@SteffenMueller I’m glad it was useful! And I like your solution of using a script to delete the whole webresource-temp folder on startup, I think I’ll go with that from now on. Thank you!

Hey all,

Could you please tell me if you still experience this on newer versions of Confluence and QuickReload?
QR 4.0.0+ and Confluence 7.19+ is what I’m interested in. I’m also assuming y’all are pressing Ctrl/Cmd+Shift+R too.

FWIW if you update the AMPS version in your pom.xml to 8.11.0 or higher you’ll get the newer versions of QR and other developer tools (provided those versions aren’t overriden in the POM).

It’s easy for caching bugs to slip into the web-resource manager and into the products. There’s been a few cache busting fixes applied over the last couple of years and it may solve the problem. If the problem isn’t solved, I’m keen to hear it so we can build up a reproduction case and fix the bug.

Feel free to @me so I actually get emails from this thread

I will once again note that we can’t easily update the version of AMPS due to the fact that we’re still stuck on a 2.5 year old release of the SDK with an ancient Maven version because Atlassian apparently still can’t find the keys to publish a new version, and Atlassian specifically recommends to use the bundled Maven version that ships with the SDK.

The “we lost the keys” excuse is wearing very thin at this point.

2 Likes

I ended up replying in the main thread

Hiya @mkemp, updated AMPS to 8.11.0 in POM, and I’m on Confluence 8.5.0.

No changes, behaviour is still the same. Editing/re-building the JS resources and Cmd+Shift+R’ing in Confluence, the changes do not appear.

And as before the changes can be pushed through either:

  • Running atlas-package
  • Deleting /confluence/home/webresource-temp

Ofc neither of these are hot-reload, but they’re a workaround for the time being.

Please let me know if you need anything else from me, I’m happy to help.

Hey @mkemp,

I gave the problem another shot and think that it still persists without a better cure. In the end, I got it working with some extra loops. Still, fixing the problem in Confluence itself would be good.

I run Confluence DC from the official docker containers. These tests were done with version 9.0.3.

What I’ve done / Checklist:

  • Upgraded AMPS to version 9.1.4 in the POM
  • Made sure <enableQuickReload> is present in the POM
  • Made sure the QR plugin is installed
  • Made sure the DC instance is in dev mode and has the right plugin.resource.directories

Initial result: it did not work out of the box. :expressionless: It looks like the webresource-temp/ folder gets populated and is used before the plugin.resource.directories is used.

I am convinced that this is a bug in Confluence that can easily be fixed - somebody just messed up the priorities on where to look for resources first.

Additionally, removing the webresource-temp folder floods the Confluence logs with exceptions about file access problems in the newer Confluence versions. So, this is no longer a good workaround.

How I got it working

For you guys in the same situation, this is how I got it working:

I’ve created a small shell script that watches the frontend build output folder (the one that is mounted as plugin.resource.directories). Every time a change in the folder happens, it executes a shell command in the docker container that deletes all files in the webresource-temp/ folder. Because every single file change from the frontend build triggers a change, we wait a second before executing the command so we pool all changes within 1 second.

Our CLI for frontend build watching now starts that script in the background (and kills it when the watcher ends). Tada. The code:

#!/bin/bash

###
# This shell script monitors the output directory of the DC frontend build and executes the
# command provided as an argument whenever a new build is emitted.
# This is used by the wfe-dc CLI command to automatically clear the web resource cache
# of the DC server plugin whenever a new frontend build is emitted.
###

# Directory to monitor
MONITOR_DIR="./server/plugin/src/main/resources/assets"

# Command to execute on change
COMMAND="$1"

# Debounce time in seconds
DEBOUNCE_TIME=1

# Function to monitor directory and execute command on change
monitor_directory() {
    inotifywait -q -m -r -e modify,create,delete,move "$MONITOR_DIR" |
    while read -r directory events filename; do
        trigger_command
    done
}

# Function to trigger the command with debounce
trigger_command() {
    if [[ -n "$TIMER_PID" ]]; then
        kill "$TIMER_PID" 2>/dev/null
    fi

    (sleep "$DEBOUNCE_TIME" && bash -c "$COMMAND") &
    TIMER_PID=$!
}

# Run the monitor function indefinitely
while true; do
    monitor_directory
done

And inside our cli shell script (just as inspiration, adapt to your environment. We’re big friends of a central cli.sh for all default tasks.)

if [ "$TODO" = "watch-frontend-dc" ]; then

    # Check that inotifywait is installed, if not, show error and exit.
    if ! type inotifywait > /dev/null 2>&1 ; then
        echo "${C_ERROR}The inotifywait command is not installed. Please install it to use this feature.${C_RESET}";
        exit 1
    fi

    # The command that clears the DC web resource cache. Because - and _ are used randomly by docker, use some filter magic
    CMD="docker exec $(docker ps --filter name=dc[-_]confluence[-_]server --quiet) bash -c 'rm /var/atlassian/application-data/confluence/webresource-temp/* 2> /dev/null'"

    # Start a watcher in the background to clear the DC cache on changes.
    bash ./frontend/build-utils/ExecuteOnEmittedBuildWatcher.sh "$CMD" &
    echo "Started watcher to clear DC web resource cache on frontend changes."

    # Function to clean up the watcher process and all sub-processes
    cleanup() {
        echo "Killing watcher processes"
        pkill -f "/frontend/build-utils/Execute"
    }

    # Set a trap to call cleanup on script exit
    trap cleanup EXIT

    run_in_code_container "cd frontend && npm install && npm run build:server:dev"
fi

Hopefully that helps somebody out. Cheers! :wink:

1 Like