Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploying dependent document models from the same bundle are not loaded in the correct order #197

Closed
vierbergenlars opened this issue Oct 29, 2018 · 3 comments · Fixed by #279
Labels

Comments

@vierbergenlars
Copy link
Member

vierbergenlars commented Oct 29, 2018

I'm submitting a ... (check one with "x")

[x] bug report
[ ] feature request
[ ] question

Expected Behavior

I create a dynamic extension jar with 2 document models in /META-INF/alfresco/models/, named XYZModel.xml and XYZWorkflowModel.xml.
The XYZWorkflowModel.xml imports a namespace defined in XYZModel.xml.

I expect that both models are registered and activated when I upload the jar in the dynamic extensions control panel.

Current Behavior

An exception is thrown when uploading the jar.

[ALFRESCO] 2018-10-29 10:30:36,839  WARN  [repo.dictionary.DictionaryRepositoryBootstrap] asynchronouslyRefreshedCacheThreadPool1] Failed to load model 'matwf:materialsWorkflowModel' : org.alfresco.service.cmr.dictionary.DictionaryException: 09290013 Failed to compile model 'matwf:materialsWorkflowModel'
 [ALFRESCO] 2018-10-29 10:30:37,001  WARN  [repo.dictionary.DictionaryRepositoryBootstrap] [asynchronouslyRefreshedCacheThreadPool1] Failed to load model 'matwf:materialsWorkflowModel' : org.alfresco.service.cmr.dictionary.DictionaryException: 09290014 Failed to compile model 'matwf:materialsWorkflowModel'
 [ALFRESCO] 2018-10-29 10:31:03,321  ERROR [extensions.webscripts.AbstractRuntime] [http-bio-8080-exec-2] Exception from executeScript - redirecting to status template error: 09290017 Failed to compile model 'matwf:materialsWorkflowModel'
 org.alfresco.service.cmr.dictionary.DictionaryException: 09290017 Failed to compile model 'xyzwf:XYZWorkflowModel'
	at org.alfresco.repo.dictionary.CompiledModel.<init>(CompiledModel.java:126)
	at org.alfresco.repo.dictionary.M2Model.compile(M2Model.java:174)
	at org.alfresco.repo.dictionary.DictionaryModelType$DictionaryModelTypeTransactionListener$2.doWork(DictionaryModelType.java:627)
	at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:555)
	at org.alfresco.repo.dictionary.DictionaryModelType$DictionaryModelTypeTransactionListener.beforeCommit(DictionaryModelType.java:574)
	at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.doBeforeCommit(TransactionSupportUtil.java:535)
	at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.doBeforeCommit(TransactionSupportUtil.java:514)
	at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.beforeCommit(TransactionSupportUtil.java:479)
	at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:925)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:738)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
	at org.alfresco.util.transaction.SpringAwareUserTransaction.commit(SpringAwareUserTransaction.java:482)
	at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:486)
	at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:587)
	at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:656)
	at org.alfresco.repo.web.scripts.RepositoryContainer.executeScriptInternal(RepositoryContainer.java:428)
	at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:308)
	at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:382)
	at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:210)
	at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:132)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:68)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.alfresco.service.namespace.NamespaceException: URI http://www.xyz.com/model/xyz/1.0 cannot be imported as it is not defined (with prefix xyz
	at org.alfresco.repo.dictionary.CompiledModel.createLocalPrefixResolver(CompiledModel.java:224)
	at org.alfresco.repo.dictionary.CompiledModel.constructDefinitions(CompiledModel.java:148)
	at org.alfresco.repo.dictionary.CompiledModel.<init>(CompiledModel.java:106)
	... 46 more

Reuploading the jar does not result in exceptions.
Both models are placed in the Data Dictionary/Models folder and the Model Active property is set for both models. However, the XYZWorkflowsModel.xml model is not fully registered.

Possible Solution

The listing of the jar file includes:

META-INF/alfresco/
META-INF/alfresco/models/
META-INF/alfresco/models/XYZWorkflowModel.xml
META-INF/alfresco/models/XYZModel.xml

Note that the files are sorted in reverse alphabetical order, and I think they are read in the order they are present in the jar file.

I think dynamic extensions should catch the exception when setting the Model Active property and has to revert the property to false to accurately reflect the state of the active models.

An other possibility is to have dynamic extensions resolve the dependencies between models and activate models in the right order.

Steps to Reproduce (for bugs)

  1. Clone https://github.com/vierbergenlars/de-repro-197
  2. Run ./gradlew jar to build the dynamic extensions jar
  3. Start up an alfresco with dynamic extensions
  4. Upload the jar file generated in build/libs/de-repro-197.jar to the dynamic extensions control panel.
  5. Observe exception in the alfresco logs

Context

Your Environment

  • Alfresco version used: 5.1.1 community
  • DE version used: 1.7.6
@kerkhofsd
Copy link
Contributor

An other possibility is to have dynamic extensions resolve the dependencies between models and activate models in the right order.

Dynamic Extensions already sorts the models based on their imports, before registering them.
There exists a test for this behavior:
https://github.com/xenit-eu/dynamic-extensions-for-alfresco/blob/master/alfresco-integration/shared/src/test/java/com/github/dynamicextensionsalfresco/models/ModelRegistrarTest.java#L47

@kerkhofsd
Copy link
Contributor

Given that the models are uploaded in correct order (DE does sort them, see previous reply):

  1. XYZModel.xml registered first
  2. XYZWorkflowModel.xml registered second

It looks like the namespaces of 1. are added to the NamespaceDAO after the transaction has committed.
When trying to compile 2. (which imports the namespace of 1.), the required namespace of 1. is not yet available in the NamespaceDAO, which results in this error.

A possible solution is wrapping the registering of each model in a new transaction.
AFAIK the only downside is that this could cause an inconsistent state where some of the uploaded models are registered and some are not.

@vierbergenlars
Copy link
Member Author

vierbergenlars commented May 14, 2019

A maybe larger problem is that workflow models have to be deployed with the workflowDeployer bean, as workflow models are not yet available when dictionaryModelBootstrap is run.
I'm not sure how dynamic extensions would be able to detect that this is the case, except by parsing the model to determine if a workflow model is imported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants