@dkayiwa can you please clarify why this is necessary? Were there some classloader rewrites in Platform 1.11 and master that break the uiframework module’s behavior?
Note that openmrs-core should not know about the specifics of any module, but this commit breaks the separation and adds uiframework-specific functionality to core. Rather it should be the uiframework module’s job to figure out how to re-enable this behavior against the classloader in openmrs-core 1.11+.
I simply wanted a VM argument telling core about the development directory
of any module. My first attempt was to use something like
“moduleid.development.directory”. An example of this would be
“xforms.development.directory”.
But i discovered that the existing VM argument in use is
“uiFramework.development.moduleid”,
where the above for the xforms module becomes "
uiFramework.development.xforms".
So i could rename the VM argument to whatever you suggest.
To make this clearer, this has nothing to do with the uiframework module.
It is simply a VM argument which tells the platform to load classes of any
module from a given development folder instead of the compiled omod.
The motivation for this was that the current “uiFramework.development.moduleid”
reloads only the new UI framework controllers.
I was working on a module, where i was making changes to other non UI
framework controllers and other classes and got fed up of having to
redeploy the module for changes i made (even the simplest like a one line
change).
With this commit, i was able to take advantage of spring-loaded which
monitors changes in my development folder and automatically reloads them
whenever my IDE auto builds the class files.
In summary, after the above, all changes (whether new methods, classes are
added or edited, etc) are automatically reloaded. And the only time that i
will need to redeploy the omod is when am done with development and ready to
release.
If you are making changes to core, run with a VM argument like: javaagent:/Projects/springloaded-1.2.3.RELEASE.jar -noverify -Dspringloaded=inclusions=org.openmrs..*
OR
If you are changing a module, ensure that your core platform has the changes for TRUNK-4739. Then run with a VM argument like: -DuiFramework.development.xforms=/Projects/openmrs/xforms -javaagent:/Projects/springloaded-1.2.3.RELEASE.jar -noverify -Dspringloaded=inclusions=org.openmrs.module.xforms..*
Replace:
xforms with your moduleId.
/Projects/openmrs/xforms with the path to your module.
/Projects/springloaded-1.2.3.RELEASE.jar with where your spring-loaded jar is.
First, this is pretty awesome. I had read about spring-loaded at some point, and then forgotten about it.
Second, I feel like any non-trivial change to the classloader needs to be discussed on OpenMRS Talk.
Modifying our core classloader to support a special development mode could have performance implications
And it introduces a difference between how code runs in development and production.
Is the reason we have to change code in openmrs-core because spring-loaded doesn’t rewrite classes loaded from JAR files, but only from .class files? Is it possible that we could make a PR against spring-loaded to support this from within their codebase, rather than changing the OpenMRS core classloader?
you should definitely not recycle “uiFramework” in the name of the VM argument. If we introduce this as a new core feature, it gets its own name…
Looking at the changes i had to make, they looked small and simple. But i
fully agree that even what appears simple may introduce bugs or have
performance implications. The good thing is that this change is only for
developers. So we could revert the commit and instead have a pull request
that a developer can apply locally to use a version of the platform for
only development purposes. This is exactly what i was all along doing
before i decided to actually commit it.
As for the bullet point number 3, yes the current release of spring-loaded
does not support reloading classes from JAR files. Even if it did, we would
need some mechanism of compiling a new jar file for each change, and dump
it into the temporary folder where our module engine extras omods.
Creating a pull request against spring-loaded looked like a task which
could take a reasonable amount of time. I did not try to do so because i
assumed that their having not done this yet is because it was not obvious.
But i could be wrong.
Changing “uiFramework” to something else makes a lot of sense!
@dkayiwa, to second @darius, this is amazing. To the point about reloading Jar files, I did find this one thread online which seems to imply that this is now supported with an argument like this:
-Dspringloaded=watchJars=foo.jar:bar.jar
See:
Not sure if this would change our solution or not, but thought I’d point it out…