Community
Participate
Working Groups
Running a QVTo transformation inside an RCP application requires a dependency from the plugin that contains the transformation to org.eclipse.m2m.qvt.oml.project. Otherwise, the error "Could not find unit: ..." occurs when the TransformationExecutor loads the transformation from a platform:/plugin URI. I don't really see a comprehensible reason for this dependency to be required. Due to my narrow RCP experiences, are there any preferences on how a repro should look like?
platform:/plugin URIs do not work until EMF and/or other registruies are properly initialized. You can probably reproduce the problem in a standalone environment. (Use a naked Java rather than Eclipse Java launch to make sure that you don't get a helpful claspath)
Since I'm invoking QVTo from within a GMF-based editor, I expect EMF to be properly initialized.
Ok, this is simply because without a dependency to org.eclipse.m2m.qvt.oml.project, this plugin does not get installed along with other user plugins. As a consequence, class EclipseUnitResolverFactory is missing as an extension for the org.eclipse.m2m.qvt.oml.unitResolverFactory extension point. Is it sensible manage the core functionality of resolving/loading units by means of the extension mechanism? If yes, we should at least add this dependency per default to every newly created QVTo project.
Why not just put a class reference from a standard plugin that exists to the standard plugin that's required?
(In reply to Ed Willink from comment #4) > Why not just put a class reference from a standard plugin that exists to the > standard plugin that's required? I'm not sure what you mean, so I should maybe explain the problem in more detail. 1. When running a QVTo transformation from Java via class TransformationExecutor, the Java code compiles as long as there is a dependency to org.eclipse.m2m.qvt.oml (which contains TransformationExecutor). 2. At runtime, the TransformationExecutor requires a specific extension from a different plugin (org.eclipse.m2m.qvt.oml.project) which is not necessarily set as a dependency. 3. If the user has installed the entire QVTo SDK, this plugin is available and so is the extension. Everything works fine at runtime. 3. If some user does not have the entire QVTo SDK installed, only the referenced plugin org.eclipse.m2m.qvt.oml gets installed automatically by Eclipse. Thus, the required plugin that contributes the extension is not available, resulting in an error when resolving the transformation via its URI. So, we can always avoid this problem by adding the appropriate dependency. However, from the Java point of view, there is absolutely no indication for this dependency to be necessary. That's why people usually omit it. As a result, there are problems when running the transformation without having the entire QVTo SDK installed before.
I suggest that perhaps TransformationExecutor invokes @SuppressWarnings("unused") String ensureEclipseUnitResolverFactoryExtensionPointIsLoaded = org.eclipse.m2m.qvt.oml.project.QVTEngine.class.getName(); to guarantee the installation. If the reference is optional, code a more dynamic test to generate an explanatory diagnostic.
Got it. But this would introduce a circular dependency between qvt.oml and qvt.oml.project.
Maybe you can only do diagnosis then. Maybe you can do the reference from somewhere that doesn't cause a loop. Maybe project shouldn't be a separate plugin. Maybe the extension point definition should be moved rather than the plugin referenced. [Sorry I'm not familiar with the code.]
Created attachment 240949 [details] Patch for setting default plugin dependencies The proposed patch adds dependencies to org.eclipse.m2m.qvt.oml and org.eclipse.m2m.qvt.oml.project to every newly created QVTo plugin project. In addition, it reuses some preexisting String constants.
However, this doesn't solve the issue, because the required dependency to org.eclipse.m2m.qvt.oml.project is still unobvious.
If you want to force plugin A to load plugin B without A referencing B and without fancy class loading tricks, the solution is to have an extension point Z. A declares Z, and loads all Z providers at an appropriately lazy time. B implements Z and so gets loaded by A.
The problem is not loading but installing. Without an explicit dependency to the 'project' plugin, it will never be installed along with a user-defined feature that uses QVTo internally.
Perhaps this is something that really must be a user choice. The 'JDT' create Plugin Project has an RCP option on its second page. Perhaps the QVTo wizard needs a similar option and consequent functionality. And if you're really enthusiastic a QVTo->Configure As RCP rescue action.
I think the problem that you address has already been solved by the proposed patch, which enforces the required dependencies such that "oml.project" gets installed along with any user-defined QVTo plugin. However, PDE's dependency analysis will always identify these dependencies as unused. Thus, they could easily be removed accidentally. I'm afraid that the complete solution is to merge "oml" and "oml.project" plugins.
A different approach would be to just move class TransformationExecutor from "oml" to "oml.project" plugin. This way, client plugins that access QVTo via TransformationExecutor are required to always specify a plugin dependency to "oml.project", which ensures availability of the functionality to load/resolve units. Moving an API class will cause legacy problems, though.
Moving an API class is not really an option, but you can deprecate it so that users see the @Deprecated comment telling them which (derived) class to use instead.
Pushed patch to master for M7. commit 371ae82006cb901d28adcfa923c33c61d9da8338
Interesting question: how does it work standalone without oml.project asdescribed here? https://wiki.eclipse.org/QVTo/New_and_Noteworthy/Helios
(In reply to Christopher Gerking from comment #18) > Interesting question: how does it work standalone without oml.project > asdescribed here? https://wiki.eclipse.org/QVTo/New_and_Noteworthy/Helios Plug-in 'oml.project' is really not needed when QVTo runs standalone. This plug-in provides Eclipse workspace specific features to QVTo engine via extension point.
(In reply to Sergey Boyko from comment #19) > Plug-in 'oml.project' is really not needed when QVTo runs standalone. This > plug-in provides Eclipse workspace specific features to QVTo engine via > extension point. Yes, but then I wonder why it is strictly needed inside Eclipse. I would expect everything that works standalone to work inside Eclipse as well.
I think I finally figured out the actual problem here. Plugin qvt.oml.project is not required in standalone mode and therefore shouldn't be strictly required inside Eclipse as well. The reason why it does not work without is that, in absence of qvt.oml.project, the only available resolver is URIUnitResolver. This one lacks support for imports of modules that resist in a different directory than the importing one. Instead, the current configuration of URIUnitResolver only supports importing of units in the very same directory. Actually, this problem applies to standalone execution as well. Solving this problem for URIUnitResolver requires detection of the QVTo source container, such that the resolver can be configured to resolve all imports against it. However, this is quite a hard task, if not impossible in standalone mode. Thus, to solve the problem in Eclipse mode, I suggest to move PlatformPluginUnitResolver from qvt.oml.project into qvt.oml, such that it is available for resolving platform:/plugin URIs even in absence of qvt.oml.project. For standalone mode, URIUnitResolver should at least mimic the behavior of PlatformPluginUnitResolver: assume that the source container is the plugin root and try to resolve against it. Fallback to lookup inside the importing unit's directory (which is what URIUnitResolver already does at present).
(In reply to Christopher Gerking from comment #21) > Solving this problem for URIUnitResolver requires detection of the QVTo > source container, such that the resolver can be configured to resolve all > imports against it. However, this is quite a hard task, if not impossible in > standalone mode. Maybe the lightweight search in org.eclipse.ocl.internal.helper.PluginFinder will help (or the fuller search in EcorePlugin.ExtensionProcessor).
(In reply to Christopher Gerking from comment #21) > I think I finally figured out the actual problem here. Plugin > qvt.oml.project is not required in standalone mode and therefore shouldn't > be strictly required inside Eclipse as well. Consequently, I suggest to revert my change and do not add that dependency to new user projects. > For standalone mode, URIUnitResolver should at least mimic the behavior of > PlatformPluginUnitResolver: assume that the source container is the plugin > root and try to resolve against it. Fallback to lookup inside the importing > unit's directory (which is what URIUnitResolver already does at present). If properly configured, plugins should now support the above behavior by importing from the classpath (bug 433937). Not tested yet. Closing this bug requires some documentation, telling users that FQN imports either require qvt.oml.project (in that case a dependency should be set to ensure installation), or require the source container to be part of the classpath. There is already another bug on missing documentation of module imports (bug 380136).
(In reply to Christopher Gerking from comment #23) > There is already another bug on missing documentation of module imports (bug > 380136). Sorry, that's bug 319076.
(In reply to Christopher Gerking from comment #23) > Consequently, I suggest to revert my change and do not add that dependency > to new user projects. Pushed to master. Commit ID: 5963287c78cc2a5b466a5502e7e83f48e5ae4272 I still find it desirable to make sure that the invocation of user scripts works whenever the invoking Java code compiles. For Mars+1, we should try to establish a unit resolver capable of resolving units at plugin level, residing in org.eclipse.m2m.qvt.oml (strictly separated from the workspace resolving policies in org.eclipse.m2m.qvt.oml.project).