Opened 8 years ago
Closed 8 years ago
#2041 closed enhancement (fixed)
Support for extension points within extensions
Reported by: | Nicklas Nordborg | Owned by: | everyone |
---|---|---|---|
Priority: | major | Milestone: | BASE 3.10 |
Component: | core | Version: | |
Keywords: | Cc: |
Description
It would be nice if we could get this to work. In theory the concept is not very complicated. An extension may define additional extension points that are then extended by other extensions. In practice we get a lot of problems with initialization and class loading. Problems found so far:
- The extension points are not loaded at startup. The core
Application
class will only load extensions points defined by thenet.sf.basedb.core
package and the web client will only load extension points defined by thenet.sf.basedb.clients.web
package. To enable the extension points a server admin must go to the "Administrate -> Plugins & Extensions -> Overview" page and re-install the extension. We could of course require other extensions to use those packages as well, but it would be better to fix the issue so that extension points are loaded at startup.
- Updating a modified extension results in a
ClassCastException
:Action 'net.sf.basedb.opengrid.test.TestJobCompletionHandlerFactory@61a3083f' created by extension 'net.sf.basedb.opengrid.test-job-complete' is not of the expected class 'net.sf.basedb.opengrid.service.JobCompletionHandler' java.lang.ClassCastException: net.sf.basedb.opengrid.test.TestJobCompletionHandlerFactory@61a3083f -> net.sf.basedb.opengrid.service.JobCompletionHandler at net.sf.basedb.util.extensions.ActionIterator.validActions(ActionIterator.java:231) at net.sf.basedb.util.extensions.ActionIterator.hasNext(ActionIterator.java:114) at net.sf.basedb.util.extensions.ExtensionsInvoker.render(ExtensionsInvoker.java:167) ...
I guess that somewhere in BASE there is something that is not thrown out when the new class loader is created for the updated jar file.
- The above class cast problem happened when both the extension point and extension was defined in the same JAR file. I have not tested to created extensions in separate JAR files. I guess that will be a bit more problematic.
Change History (9)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
comment:3 by , 8 years ago
(In [7226]) References #2041: Support for extension points within extensions
Adding more debug logging to see what it going on when scanning for updated extensions.
If using the ExtensionsFile.wasModified()
method instead of the ExtensionsFile.checkModified()
method (which has already been called in the ExtensionsControl.scanForChanges()
method) changes in one extension will automatically be detected in other extensions depending on the same JAR file (this was implemented in [7192] and [7196]).
However it only works once. If the server admin simply closes the extension installation wizard and then open it again, only the JAR file that was actually changed will be detected and not those that depend on it.
I'll need to set up a better test case. One idea is to add an example extension point to the "Example code package" (http://baseplugins.thep.lu.se/wiki/net.sf.basedb.examplecode) that we can use for testing purposes from other extensions.
comment:5 by , 8 years ago
(In [7227]) References #2041: Support for extension points within extensions
This should get rid of the problem that a scan for changes only once. The problem was that if a change was detected in a JAR file, the ExtensionsFile.validate()
method was called which, as a side-effect, nullified the current JAR class loader. This caused a second scan to think that everyting was up to date. The class loader is no longer reset when validating, but only if a change has been detected and the getClassLoader()
method is called.
comment:6 by , 8 years ago
(In [7228]) References #2041: Support for extension points within extensions
Implemented a better solution for re-installing an updated extension. The class loader is now reset as part of the re-installation process and not as part of the scanning-for-changes process. The existing ResetErrorFlagProcessor
class has been deprecated and replaced with the more generic ResetProcessor
which is able to reset the error flag, class loader and any other things we might need to reset in the future when doing a re-installation.
comment:7 by , 8 years ago
comment:8 by , 8 years ago
comment:9 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The tests in the example code seems to work.
(In [7224]) References #2041: Support for extension points within extensions
Adding more debug-level logging to see what is going on when initializing the extension system. There is one step in the core that only load some extensions and one step in the web client that load other extensions. Everything that falls outside of that is not loaded at all (at least until a manual re-install is triggered from the web interface).
I think it should be safe to remove the filtering from the web client initialization and let it load all extensions. It seems like it should not touch already registered extensions.
Regarding the
ClassCastException
mentioned in the second point above I think it is a result of theRegistry.RegisteredExtensionPoint.update()
only is changing the classloader and not the action class.