Automatic Plugin Reinstallation with QuickReload
What is QuickReload?
QuickReload is an Atlassian plugin that significantly reduces your own plugin development iteration time. It works by watching output directories for P2 .jar files to be created, and then uploads them into the running Atlassian host application such as JIRA or Confluence. It aims to provide the smallest possible time between a bit of code being compiled and linked to it being loaded into the host application and run.
In your pom.xml for the plugin, ensure QuickReload is enabled via the <enableQuickReload> tags:
Note that FastDev must be disabled, as this clashes with the operation of QuickReload.
How it works
The idea is remarkably simple. Firstly there is a file change watching library called atlassian-watch-service that is a simple wrapper for the Java 7 file watch APIs or the jwatchservice code that runs on JDK 6.
It turns out that the JDK 7 implementation is rubbish and polls directories for changes. So in fact it uses jwatchservice code to get near real time updates for directory changes. This is how the code knows that a jar has changed on disk.
It then examine the jar to see if it's an atlassian plugin (by having a quick squizz inside it) and then call on the plugin system to install that jar.
Turns out that file watching service is too efficient because it raises a changed event when the jar is first created but not filled with zipped files. So the code has to have some "retry" time to wait until the jar is fully formed. This turns out to be 10-100ms, so it's not a big problem.
The plugin system doesn't care where plugin files are installed from. It can be <home>/plugins/installed-plugins or any other directory. So this code uses the <dir>/target directory directly as the place to install the plugin from.
No copying and no HTTP transfer. Speedy!
The pom.xml convention
By default you should not have to configure anything for QuickReload to work because it uses a pom.xml strategy on what directories to watch for changes.
- QR starts from the current running directory
- QR ascends up directories until it find a pom.xml that has no parent pom.xml
- QR then descends down from there to find all pom.xml files and tracks their peer <dir>/target directories for changed .jar files
This will allow QuickReload to watch many plugins in a multi module Maven project.
The quickreload.properties convention
You can drop a quickreload.properties file into the project to tell QuickReload what to explicitly watch along with to the pom.xml convention.
- QR ascends up directories until it finds a quickreload.properties file
- QR reads the entries and begins to watch those directories
The directories can be absolute or relative to the quickreload.properties file. Also IF the directory contains a pom.xml and then <dir>/target is assumed as the right place to watch for .jar changes.
The file looks like this
The quickreload.properties $HOME convention
Finally QuickReload will look for a $HOME/quickreload.properties file as configuration. You could put uber common entries in here but in general the pom.xml convention is the most powerful and the least amount of work to configure.
Front End Alternate Resource Directories
Hence you can edit a .js file say and press refresh in the browser and it changes.
It uses the pom.xml strategy and add <dir>/src/main/resources to the plugin system alternate resource directory loading mechanism for you.
There is no more need to specify -Dplugin.resource.directories as it will be done for you.
Finally you can specify the directories to track on the command line via
If you really must but in general, it "just works" for Maven projects.
This allows you to have two or more plugins being developed at the same time with jar and resource monitoring in place automatically. Cool right?
You can put properties before a line entry via a : character. Multiple properties can be specified via the ; character
The current properties are :
- resource - marks the path as a resource entry and it will be placed into the -Dplugin.resource.directories system directory
Controlling web batching
The Atlassian Web Resource system can batch together files for faster loading. But this means its harder to debug. So there is a atlassian.dev.mode system property to control that.
But its a one time thing that is set at JVM startup right? Not anymore.
Press 'B' when QuickReload is running and you can toggle between speed of web batching being enabled and the debug ability of when web batching is disabled.
The quick reload spits out some extra log output with spacings so that you can pick the plugin reload logs lines from the wall of log text.
There is none. That's the point. The cost of crypto encoding admin:admin is a significant cost in terms of time for plugin reload. So it doesn't do it.
Don't use this in production. Just don't!
HTML Control Panel
QuickReload has a control panel you can visit to see whats in play.
QuickReload has a REST API to help you be a better developer
Visit this to begin discovering it
Currently you can
See all OSGi bundles in the system
See a specific OSGI bundle
See all the OSGi services in the system
See all Atlassian Plugins in the system
See a specific Atlassian Plugin, including its modules and internal Spring bean context
See the state of a current state of a plugin, and with POST / DELETE to enable or disable the plugin
See the state of a current state of a plugin module, and with POST / DELETE to enable or disable the plugin module
View the last 100 events in the application
See the list of QR tracked directories
See whether web batching is enabled
If you see this "java.lang.UnsatisfiedLinkError: Native Library" error it means that the quick reload plugin was re-loaded while running but it could not be. It's ironic I know that a reloading plugin can't be cleanly re-loaded but it's more to do with the underlying native file watching library than quick re-load itself.
Java does not like to unload native libraries and the underlying name.pachler.nio.file does not expect to be reloaded. Trust me, you won't see this much. It's seen more in developing this plugin itself or you are running FastDev at the same time as QuickReload