OCL/New and Noteworthy/2021-03
Eclipse OCL New and Noteworthy items for the 2021-03 (6.14.0) release.
This minor release fixes a few bugs. Behind the scenes UI-based functionality responds to the platform migration to Java 11 and starts the migration away from the deprecated old to new Xtext infrastructure. The full migration was retracted at the last minute since the prototype of a new declarative serilaizer/formatter was not adequately tested and failed some tests. The editor for the Idioms DSL that configures the new serializer/formatter is provided.
(The work on Bye Bye invalid was still not ready in time for 2020-06; Xtext migration more important.)
The prevailing Eclipse OCL release candidate is auto-tested every week on Oxygen, Photon, 2018-09, 2018-12, 2019-03, 2019-06, 2019-09, 2019-12, 2020-03, 2020-06, 2020-09 and 2020-12 platforms using Jenkins on Linux and the prevailing Java/project versions for the release.
2021-03 release should be installable on Mars and Neon platforms provided Xtext 2.9 or greater is also installed.
The 2021-03 sources may only be buildable on 2021-03.
Java 8 on Windows was used to develop and test the milestones of this release. Following the Eclipse platform migration to a Java 11 minimum, development now uses Java 11, although standalone tests continue to use Java 8.
Java 12 on Windows was briefly used to maintain and test the 2020-06 release candidates. It appears to work although Java code generation/compilation seems nearly three times slower - see Bug 565563.
Java 11 on Jenkins, Linux was used to build and test the release candidates.
The Classic Ecore/UML plugins have been tested on Mars, Neon, Oxygen and Photon and on a Java 5 Virtual Machine. Standalone execution requires only the org.eclipse.osgi plugin from Eclipse Kepler or a spoof of org.eclipse.osgi.util.NLS and org.eclipse.osgi.framework.
The Pivot plugins require at least a Java 8 Virtual Machine and at least Xtext 2.9.1. Testing on Oxygen has a couple of test failures. Testing on Mars and Neon has a few editor/console startup failures.
Providing OCL support behind the EMF getXXX() API is difficult since the OCL context cannot be passed directly.
It was therefore passed as an adapter on the ResourceSet and/or EValidator context and discovered/lazily constructed there. For the awkward case of no ResourceSet, a global OCL context was shared. Ensuring that the lazily constructed context did not leak posed further challenges.
This milestone introduces a change to pass the context via a ThreadLocal falling back to the old way to first construct the context. This avoids an EObject hierarchy search to locate the ResourceSet and makes the global context redundant.
This milestone also obsoletes the LazyModelManager in favour of a LazyEcoreModelManager which is used in all rather than just some curcumstances. The LazyEcoreModelManager performs some preliminary Ecore analysis to enable a single model traversal to efficiently cache all allInstances/implicitOpposites context that has been configured. Consequently a model validation should only ever create one OCL EnvironmentFactory/MetaModelManager and one ModelManager. Previously Modelmanagers were churned disgracefully and expensively. If the required allInstances/implicitOpposites have not been configured so that OCL intrerpretation discovers new requirements, a full model re-traversal is triggered to remedy the deficiency; less-efficient bt accurate.
The above facilities should work fine for a single OCL, but use of multiple OCLs per thread incur a "Concurrent EnvironmentFactory instances inhibit LocalThread Executor passing." error that forces a fallback to the ResourceSet adapter / EValidator context approach.
See https://wiki.eclipse.org/OCL/FAQ#Concurrent_EnvironmentFactory_instances for more details.
Use of multiple OCLs proved surprisingly common in the OCL test harnesses, varioysly to perform a nested validation or a comparison between reference and processed models. The concurrent usage was simply fixed by processing one model and then the other, and using ocl1.deactivate() to leave the way clear for the second ocl without needing to trash the models via ocl1.dispose(). The nested usage was fixed by invoking oclOuter.deactivate() and oclOuter.activate() around the nested processing. ThreadLocalExecutor.reset() may be useful to cleanup. ThreadLocalExecutor.waitForGC() may be necessary to ensure that a lazily freed first OCL has been finalized before a next OCL takes.
- 570894 allInstances is now for entire ResourceSet rather than just Resource.
- 570995 allInstances/implicit-opposites cached effectively.
- 570891 CG of same-name redefinition no longer lacks a cast.
- 570892 CG of extension_XXX Property now works.
- 571407 CG of changed name redefinition no longer lacks a cast.