blob: 897e9087c1bca2771453e037aa8cd1fbc0fa9f6c [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-language" content="en">
<meta name="description" content="Scalable Reactive Model Transformations">
<meta name="MobileOptimized" content="width" />
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="/viatra/js/googleAnalytics.js"></script>
<script type="text/javascript" src="/viatra/js/magnific-popup.video.js"></script>
<script type="text/javascript" src="/viatra/js/magnific-popup.min.js"></script>
<script type="text/javascript" src="/viatra/js/functions.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="/viatra/angular/viatra.js"></script>
<script src="/viatra/highlight.js/highlight.min.js"></script>
<link rel="stylesheet" type="text/css" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css" />
<script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="/viatra/favicon.ico" />
<title>Viatra - Scalable reactive model transformations</title>
<link type="text/css" rel="stylesheet" href="/viatra/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="/viatra/css/style.css" />
<link type="text/css" rel="stylesheet" href="/viatra/css/media.css" />
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300italic,700,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://use.fontawesome.com/ef6567f233.css">
<link rel="stylesheet" href="/viatra/highlight.js/styles/foundation.min.css">
<link rel="stylesheet" type="text/css" href="/viatra/css/asciidoctor.css"/>
</head>
<body ng-app="viatra" ng-controller="main" class="cloak">
<ng-include src="'/viatra/angular/blocks/header.html'"></ng-include>
<div class="clear"></div>
<div id="body_wrapper">
<h1 class="page_title">Query Development Tools</h1>
<div id="preamble">
<div class="sectionbody">
<div id="toc" class="toc">
<div id="toctitle" class="title">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#query-tests">1. Query Test Framework</a>
<ul class="sectlevel2">
<li><a href="#_basic_concepts">1.1. Basic concepts</a></li>
<li><a href="#_incremental_scenarios">1.2. Incremental Scenarios</a></li>
<li><a href="#_supporting_plain_java_objects_in_substitutions">1.3. Supporting plain Java objects in substitutions</a></li>
</ul>
</li>
<li><a href="#query-optimization">2. Debugging and Profiling Graph Patterns</a>
<ul class="sectlevel2">
<li><a href="#rete-visualizer">2.1. Rete Visualizer</a></li>
<li><a href="#local-search-debugger">2.2. Local Search Debugger</a></li>
<li><a href="#query-profiling">2.3. Memory Optimization of Rete Networks</a></li>
</ul>
</li>
<li><a href="#viatra-maven-plugin">3. Maven integration</a>
<ul class="sectlevel2">
<li><a href="#_repository">3.1. Repository</a></li>
<li><a href="#_viatra_maven_plugin">3.2. viatra-maven-plugin</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="query-tests"><a class="link" href="#query-tests">1. Query Test Framework</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>There is a test framework available specifically designed to test Viatra Queries. It was developed with the following use cases in mind:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Testing the Viatra Query Engine itself</p>
</li>
<li>
<p>Provide a regression testing framework for users to test patterns</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="_basic_concepts"><a class="link" href="#_basic_concepts">1.1. Basic concepts</a></h3>
<div class="paragraph">
<p>The framework allows the user to compare the results of a pattern execution using different engine implementation or to a predefined result set (so-called snapshot). It defines a convenient <a href="https://git.eclipse.org/c/viatra/org.eclipse.viatra.git/tree/query/tests/org.eclipse.viatra.query.testing.core/src/org/eclipse/viatra/query/testing/core/api/ViatraQueryTest.xtend">internal DSL</a> to define test cases. A description of a test case consists of the following parts:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>What to test</p>
<div class="ulist">
<ul>
<li>
<p>Generated query specifications</p>
</li>
<li>
<p>Pattern groups</p>
</li>
<li>
<p>Generic pattern groups (possible parsed directly from .vql files)</p>
</li>
</ul>
</div>
</li>
<li>
<p>Input models</p>
</li>
<li>
<p>Execution methods</p>
<div class="ulist">
<ul>
<li>
<p>by Rete or LocalSearch engines</p>
</li>
<li>
<p>from snapshot</p>
</li>
</ul>
</div>
</li>
<li>
<p>Assumption (optional)</p>
<div class="ulist">
<ul>
<li>
<p>Checks whether all given execution method supports the given patterns (i.e. the test case is applicable)</p>
</li>
</ul>
</div>
</li>
<li>
<p>Assertion</p>
<div class="ulist">
<ul>
<li>
<p>Checks whether the results provided by all execution methods are the same for each patterns.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">Example</div>
<div class="content">
<pre class="highlight"><code class="language-xtend" data-lang="xtend">ViatraQueryTest. //Entry point
test(SomeQuerySpecification::instance).
and(AnotherQuerySpecification). // Patterns under test
on(modelURI). // Instance models (optional; snapshot model references the input model)
with(snapshot). // Compare prepared results stored by a snapshot model
with(new ReteBackendFactory). // Compare results produced by the Rete engine
assumeInputs. // checks whether the given snapshots and backend factories are valid for the patterns under test. Throws JUnit assumption error otherwise
assertEquals // compute difference of each given snapshot and pattern executions. Throws JUnit assertion failure if differences occur</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_incremental_scenarios"><a class="link" href="#_incremental_scenarios">1.2. Incremental Scenarios</a></h3>
<div class="paragraph">
<p>The framework supports testing scenarios in which the results can be checked again after a model modification using the modify method:</p>
</div>
<div class="listingblock">
<div class="title">Recheck after model manipulation</div>
<div class="content">
<pre class="highlight"><code class="language-xtend" data-lang="xtend">ViatraQueryTest. //Entry point
test(SomeQuerySpecification::instance).
and(AnotherQuerySpecification). // Patterns under test
on(modelURI). // Instance models (optional; snapshot model references the input model)
with(snapshot). // Compare prepared results stored by a snapshot model
with(new ReteBackendFactory). // Compare results produced by the Rete engine
assertEqualsThen. // assertEqualsThen does not return void
modify(Type, [name=="John"], [age=35]). // The given operation is executed on each instance of the given type on which the given condition evaluates to true.
with(snapshotAfterModification). // Any modify operation causes all previously loaded snapshots to be invalidated.
assertEquals</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_supporting_plain_java_objects_in_substitutions"><a class="link" href="#_supporting_plain_java_objects_in_substitutions">1.3. Supporting plain Java objects in substitutions</a></h3>
<div class="paragraph">
<p>In some cases plain Java objects need to be added to the Query Snapshot model. However, the serialization and comparison of such elements might be relevant on the domain in which the testing framework is used. In this case, the framework allows the user to define how certain plain Java types should be handled, through JavaObjectAccess elements.These elements enable the framework to serialize, deserialize and compare certain typed POJOs.
The following example demonstrates how these Access objects should be registered into the framework.</p>
</div>
<div class="paragraph">
<p>In this example, the metamodel contains a 'CustomInteger' typed attribute. 'CustomInteger' is a java type that extends 'Integer'. The following fragment shows how 'Access' type definition.</p>
</div>
<div class="listingblock">
<div class="title">Accessing a Custom Attribute</div>
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class CustomIntegerAccess extends JavaObjectAccess{
public CustomIntegerAccess() {
super(CustomInteger.class);
}
//Create Substitution object based on the CustomInteger object
@Override
public SerializedJavaObjectSubstitution toSubstitution(Object value) {
SerializedJavaObjectSubstitution sub = SnapshotFactory.eINSTANCE.createSerializedJavaObjectSubstitution();
if(value instanceof CustomInteger){
sub.setType(getType().getName());
sub.setValue(((CustomInteger) value).integerValue()+"");
}
return sub;
}
//Calculate hash code (needed for equality checking)
@Override
public int calculateHash(SerializedJavaObjectSubstitution substitution) {
return Objects.hashCode(Integer.parseInt(substitution.getValue()));
}
//Check if two substitutions are equal (assuming they each define a 'CustomInteger')
@Override
public boolean equals(SerializedJavaObjectSubstitution a, SerializedJavaObjectSubstitution b) {
if(a.getType().equals(getType().getName()) &amp;&amp; b.getType().equals(getType().getName())){
int aVal = Integer.parseInt(a.getValue());
int bVal = Integer.parseInt(b.getValue());
return aVal == bVal;
}
return false;
}
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Using CustomIntegerAccess</div>
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> ...
Map&lt;String, JavaObjectAccess&gt; objectAccess = Maps.newHashMap();
map.put(CustomInteger.class.getName(),new CustomIntegerAccess());
ViatraQueryTest.test(specs, objectAccess).on(new EMFScope([MODEL])).with([SNAPSHOT]).assertEquals();
...</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_coverage_analysis_and_reporting"><a class="link" href="#_coverage_analysis_and_reporting">1.3.1. Coverage analysis and reporting</a></h4>
<div class="paragraph">
<p>Starting with VIATRA 1.6 (see <a href="http://bugs.eclipse.org/514628">bug 514628</a>), you can add analyzers to a test object which measure various metrics of query execution. For example, you can analyze coverage during testing:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xtend" data-lang="xtend">static var CoverageAnalyzer coverage;
@BeforeClass
static def void before(){
coverage = new CoverageAnalyzer();
}
@Test
def void testApplicationTypes() {
ViatraQueryTest.test(ApplicationTypesQuerySpecification.instance)
.analyzeWith(coverage) // Analyze coverage
.with(new ReteBackendFactory) // First set of matches should come from query evaluation with Rete backend
.with(snapshot) // Second set of matches should come from a snapshot
.assertEquals // Assert that the match sets are equal
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then after running the tests, you can get the analyzed coverage with <code>CoverageAnalyzer#getCoverage()</code>, or report it with <code>CoverageReporter</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xtend" data-lang="xtend">@AfterClass
static def void after(){
CoverageReporter.reportHtml(coverage, new File("coverage.html"))
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For a complete example, see the <a href="https://git.eclipse.org/c/viatra/org.eclipse.viatra.examples.git/tree/cps/frameworktests/org.eclipse.viatra.examples.cps.tests/src/org/eclipse/viatra/examples/cps/tests/BasicCpsTest.xtend">CPS Framework tests</a>.</p>
</div>
<div class="sect4">
<h5 id="_interpreting_the_coverage_report"><a class="link" href="#_interpreting_the_coverage_report">1.3.1.1. Interpreting the coverage report</a></h5>
<div class="paragraph">
<p>A coverage report looks like this: <a href="https://hudson.eclipse.org/viatra/job/viatra-framework-tests/lastSuccessfulBuild/artifact/cps/frameworktests/org.eclipse.viatra.examples.cps.tests/BasicCpsTest_coverage.html">CPS Framework tests coverage report</a></p>
</div>
<div class="paragraph">
<p>An element (pattern, pattern body or a constraint) can be:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Covered</dt>
<dd>
<p>the Rete node which belongs to it had at least one match during the query executions</p>
</dd>
<dt class="hdlist1">Uncovered</dt>
<dd>
<p>the Rete node which belongs to it had no matches during any query execution</p>
</dd>
<dt class="hdlist1">Not represented</dt>
<dd>
<p>it is not represented in the Rete network, which usually means that the optimizer removed it because it is redundant.</p>
</dd>
<dt class="hdlist1">Not represented by error</dt>
<dd>
<p>it should be represented in the Rete network, but it was removed for an unknown reason; if you encounter this, please report an issue, including your query file and the coverage report.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Note that a pattern body can be uncovered although each of its constraints is covered, because the Rete nodes belonging to the constraints could have matches during <em>different</em> query executions, which means that the constraints were not fulfilled at once.</p>
</div>
<div class="paragraph">
<p>A pattern&#8217;s aggregated coverage metric is calculated the following way: number of covered elements / number of represented (covered/uncovered) elements</p>
</div>
<div class="paragraph">
<p>Known limitations in 1.6:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>coverage measurement is supported only with the Rete backend</p>
</li>
<li>
<p>the results might be indeterministic because of the indeterminism of the Rete evaluation</p>
</li>
<li>
<p>the constraints are displayed in their internal PQuery representation (see <a href="http://bugs.eclipse.org/515723" class="bare">http://bugs.eclipse.org/515723</a>)</p>
</li>
</ul>
</div>
<div style="page-break-after: always;"></div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="query-optimization"><a class="link" href="#query-optimization">2. Debugging and Profiling Graph Patterns</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="rete-visualizer"><a class="link" href="#rete-visualizer">2.1. Rete Visualizer</a></h3>
<div class="ulist">
<div class="title">Installation</div>
<ul>
<li>
<p>Install the <strong>Query Visualization</strong> feature group from the VIATRA update site.</p>
<div class="ulist">
<ul>
<li>
<p>Before VIATRA 1.6 this feature relied on a pre-release version of GEF4 Zest; the version available from the GEF update sites did not work. Use the version from the VIATRA update sites.</p>
</li>
<li>
<p>Since VIATRA 1.6 GEF 5 is used</p>
<div class="ulist">
<ul>
<li>
<p>JavaFX support is required</p>
</li>
<li>
<p>e(fx)clipse runtime and GEF5 is required. They are both available from the Oxygen release train.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Usage</div>
<ul>
<li>
<p>Go to <strong>Window</strong> | <strong>Show View</strong> | <strong>Other&#8230;&#8203;</strong> and choose <strong>Rete Visualizer</strong>.</p>
</li>
<li>
<p>Load the instance model and the pattern in <em>Query Results</em> view.</p>
</li>
<li>
<p>Click on the pattern name to visualize it.</p>
</li>
<li>
<p>To change the visualized Rete net, unload the pattern and load with the green start button.</p>
</li>
<li>
<p>You may change the layout by clicking the downward pointing triangle and going to the <strong>Layout</strong> menu.
<span class="image"><img src="./images/tools/rete_visualizer.png" alt="rete visualizer"></span></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="local-search-debugger"><a class="link" href="#local-search-debugger">2.2. Local Search Debugger</a></h3>
<div class="ulist">
<div class="title">Installation</div>
<ul>
<li>
<p>The Local Search Debugger Tooling is available in the Query Visualization feature group.</p>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Usage</div>
<ul>
<li>
<p>Open the Local Search Debugger view in Eclipse</p>
</li>
<li>
<p>Load the model and query definitions in the Query explorer</p>
</li>
<li>
<p>Select the the query in the Query explorer</p>
</li>
<li>
<p>Run the local search debugger by invoking the command on the toolbar of the Local Search Debugger view. The command reads the selection from the query explorer and initiates the matching: initializes and shows the plan.</p>
</li>
<li>
<p>Step or run the matching using the designated commands on the view&#8217;s toolbar. Breakpoints can also be added when needed.</p>
</li>
<li>
<p>The state of the shown search plan shows the state of the execution, while the already found matches and the current variable substitutions can be seen in the view&#8217;s provided Zest viewer.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="query-profiling"><a class="link" href="#query-profiling">2.3. Memory Optimization of Rete Networks</a></h3>
<div class="paragraph">
<p>If you have a large number of patterns and you find that the incremental query evaluation seems very slow or uses more memory than expected, it is useful to take an instance model where the issue occurs and evaluate the footprint of each pattern independently. Of course, patterns that call other patterns will also incorporate the footprint of those patterns, but the difference can be seen nonetheless.</p>
</div>
<div class="paragraph">
<p>We provide a simple JUnit test for performing this hotspot evaluation easily using the Testing Framework of VIATRA Query: <a href="http://git.eclipse.org/c/viatra/org.eclipse.viatra.git/tree/query/tests/org.eclipse.viatra.query.testing.core/src/org/eclipse/viatra/query/testing/core/QueryPerformanceTest.xtend">QueryPerformanceTest.xtend</a>. Read the JavaDoc for more details, while an example on its usage can be found here for our UML surrogate queries: <a href="http://git.eclipse.org/c/viatra/org.eclipse.viatra.git/tree/integration/tests/org.eclipse.viatra.integration.uml.test/src/org/eclipse/viatra/integration/uml/test/UMLSurrogateQueryPerformanceTest.java">UMLSurrogateQueryPerformanceTest.java</a></p>
</div>
<div class="paragraph">
<p>Note that if you run the test and use profilers, such as <a href="https://www.yourkit.com/java/profiler/index.jsp">YourKit</a> or <a href="http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-1998576.html">Java Mission Control</a>, the problematic patterns can be easily identified by looking at the heap size graphs, selecting the exceeding parts and looking at the current trace to see which query is being built.</p>
</div>
<div style="page-break-after: always;"></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="viatra-maven-plugin"><a class="link" href="#viatra-maven-plugin">3. Maven integration</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>VIATRA Query supports building VIATRA Query projects in a Maven-based builds by generating the pattern matcher code from the vql files.</p>
</div>
<div class="ulist">
<div class="title">Requirements</div>
<ul>
<li>
<p>The maven compiler requires Maven 3.1 to function correctly. In some cases Maven 3.0.5 is enough, but there are some dependency issues that are problematic for this version. Versions before Maven 3.0 will not work at all. See <a href="http://bugs.eclipse.org/478437" class="bare">http://bugs.eclipse.org/478437</a> for details.</p>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Known limitations</div>
<ul>
<li>
<p>Code generation for integration components (e.g. validation framework, derived features) is not supported. See <a href="http://bugs.eclipse.org/434794" class="bare">http://bugs.eclipse.org/434794</a></p>
</li>
<li>
<p>The VIATRA Query project is not available from Maven Central, only from repo.eclipse.org.</p>
</li>
<li>
<p>There is no maven archetype support: it is not possible to generate an Eclipse-less project automatically, that works with VIATRA Query. However, manually created projects can be built with the existing compiler.</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="_repository"><a class="link" href="#_repository">3.1. Repository</a></h3>
<div class="paragraph">
<p>Maven components are available from the Eclipse maven repository with the following urls:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Releases: <a href="https://repo.eclipse.org/content/repositories/viatra-releases/" class="bare">https://repo.eclipse.org/content/repositories/viatra-releases/</a> (kept indefinitely)</p>
</li>
<li>
<p>Snapshot only: <a href="http://repo.eclipse.org/content/repositories/viatra-snapshots/" class="bare">http://repo.eclipse.org/content/repositories/viatra-snapshots/</a> (cleared after 30 days)
 * Combined repository: <a href="https://repo.eclipse.org/content/groups/viatra/" class="bare">https://repo.eclipse.org/content/groups/viatra/</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following maven projects are available for use:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">org.eclipse.viatra:viatra-query-runtime</dt>
<dd>
<p>dependency for the VIATRA Query runtime, without support for generic API</p>
</dd>
<dt class="hdlist1">org.eclipse.viatra:viatra-query-language</dt>
<dd>
<p>dependency for the VIATRA Query with support for generic API (requires many more dependencies - only use if required)</p>
</dd>
<dt class="hdlist1">org.eclipse.viatra:viatra-maven-plugin</dt>
<dd>
<p>Maven code generator, should not be added to the compile classpath</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>To use VIATRA Query features, add the repository and the required dependencies to your Maven project:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;!-- use this in your project's pom.xml file --&gt;
&lt;properties&gt;
&lt;!-- It is a good idea to specify VIATRA framework version once as
a property (e.g. in the parent pom) and use that throughout the build --&gt;
&lt;viatra.version&gt;1.2.1&lt;/viatra.version&gt;
&lt;/properties&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.viatra&lt;/groupId&gt;
&lt;artifactId&gt;viatra-query-runtime&lt;/artifactId&gt;
&lt;version&gt;${viatra.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;!-- requires many more dependencies - only use if required --&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.viatra&lt;/groupId&gt;
&lt;artifactId&gt;viatra-query-language&lt;/artifactId&gt;
&lt;version&gt;${viatra.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;repositories&gt;
&lt;repository&gt;
&lt;id&gt;viatra&lt;/id&gt;
&lt;url&gt;https://repo.eclipse.org/content/groups/viatra2/&lt;/url&gt;
&lt;/repository&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_viatra_maven_plugin"><a class="link" href="#_viatra_maven_plugin">3.2. viatra-maven-plugin</a></h3>
<div class="paragraph">
<p>The maven plugin requires information from the used EMF packages and additionally the EMF packages should be able loaded as well. For this reason, it is important to add references to EPackages and Genmodels together with the corresponding dependencies.</p>
</div>
<div class="paragraph">
<p>Since 1.5, it is possible to use the project dependencies without declaring them explicitly. This helps when the metamodels you are using are not available as Maven artifacts.</p>
</div>
<div class="ulist">
<div class="title">Additional notes</div>
<ul>
<li>
<p>Package reference is added either by file path to the .genmodel file (typically by platform:/resource URI) or fully qualified name of the Ecore Package class that is available on the classpath. Note that if the class is in the same plugin as the query file, the class based reference will not work as compilation will happen at a later build phase than the generation. Also pay attention not to mix the package class-based and the genmodel-based mechanism in one reactor because it can lead to strange errors.</p>
</li>
<li>
<p>Each package that is imported must be listed in the metamodels section. The packages that are used transitively by the explicitly listed packages do not need to be listed.</p>
</li>
<li>
<p>Explicit dependency declarations are transitive, so you don&#8217;t need to specify all dependencies in all POM.XML files. Note that in some cases you need to add extra dependencies with specific versions (e.g. emf.core) if your genmodel requires a higher version than what is provided by the viatra-maven-plugin. This way you can redefine the EMF versions used by the generator.</p>
</li>
<li>
<p>If a pattern file in a Maven project imports patterns from another project on which it depends, make sure that the files containing the imported patterns are included in the dependency&#8217;s Maven artifact.</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">Example POM.XML (based on <a href="http://git.eclipse.org/c/viatra/org.eclipse.viatra.git/tree/query/tests/org.eclipse.viatra.query.runtime.cps.tests/pom.xml">CPS example</a>)</div>
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;pluginRepositories&gt;
&lt;pluginRepository&gt;
&lt;id&gt;viatra&lt;/id&gt;
&lt;url&gt;https://repo.eclipse.org/content/groups/viatra/&lt;/url&gt;
&lt;/pluginRepository&gt;
&lt;/pluginRepositories&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;!-- Using maven-clean-plugin to remove previously generated code --&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-clean-plugin&lt;/artifactId&gt;
&lt;version&gt;2.5&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;clean&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;clean&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;filesets&gt;
&lt;fileset&gt;
&lt;!-- Generated code folder --&gt;
&lt;directory&gt;src-gen&lt;/directory&gt;
&lt;includes&gt;
&lt;include&gt;**/*&lt;/include&gt;
&lt;/includes&gt;
&lt;/fileset&gt;
&lt;/filesets&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;!-- Setting up generator --&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.viatra&lt;/groupId&gt;
&lt;artifactId&gt;viatra-maven-plugin&lt;/artifactId&gt;
&lt;version&gt;${viatra.version}&lt;/version&gt;
&lt;!-- Binding execution to the code generation lifecycle phase --&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;goals&gt;
&lt;goal&gt;generate&lt;/goal&gt;
&lt;/goals&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;configuration&gt;
&lt;!-- Output directory - required --&gt;
&lt;outputDirectory&gt;src-gen&lt;/outputDirectory&gt;
&lt;metamodels&gt;
&lt;metamodel&gt;
&lt;!-- Select one of the following depending on where is your metamodel defined --&gt;
&lt;!-- (a) Java class for the EMF EPackage - use this if generated EMF code is in the classpath --&gt;
&lt;packageClass&gt;org.eclipse.viatra.examples.cps.cyberPhysicalSystem.CyberPhysicalSystemPackage&lt;/packageClass&gt;
&lt;!-- (b) genmodel file used for generating the EMF model classes - use this if EMF model is in the same project --&gt;
&lt;!-- &lt;genmodelUri&gt;model/model.genmodel&lt;/genmodelUri&gt; --&gt;
&lt;/metamodel&gt;
&lt;/metamodels&gt;
&lt;!-- Since 1.5, you can use the project dependencies instead of specific Maven dependencies - optional --&gt;
&lt;useProjectDependencies&gt;true&lt;/useProjectDependencies&gt;
&lt;/configuration&gt;
&lt;dependencies&gt;
&lt;!-- Dependency required for the cps domain project (that contains the generated EPackage), unless you set useProjectDependencies --&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.viatra.examples.cps&lt;/groupId&gt;
&lt;artifactId&gt;org.eclipse.viatra.examples.cps.model&lt;/artifactId&gt;
&lt;version&gt;1.2.0&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_troubleshooting"><a class="link" href="#_troubleshooting">3.2.1. Troubleshooting</a></h4>
<div class="paragraph">
<div class="title">Cyclic linking</div>
<p>In a project that contains multiple pattern definition files, there is a slight chance you get an error message like follows:</p>
</div>
<div class="paragraph">
<p><code>ERROR:Cyclic linking detected : PatternCall.patternRef&#8594;PatternCall.patternRef</code></p>
</div>
<div class="paragraph">
<p>This is a known issue we are working to fix; see <a href="http://bugs.eclipse.org/464120" class="bare">http://bugs.eclipse.org/464120</a> and <a href="http://bugs.eclipse.org/480652" class="bare">http://bugs.eclipse.org/480652</a> for details about the underlying issues.</p>
</div>
<div class="paragraph">
<p>As workaround, we suggest that you have added types for all parameters, because that avoids this issue.</p>
</div>
<div class="paragraph">
<p>If that is not enough, you have to ensure that the vql files are processed in calling order: all patterns are to be processed before they are used in a pattern call. This can be achieved either by moving patterns between vql files, or by renaming your .vql files so that the files that call patterns from other files should have names lexicographically greater than the referenced files.</p>
</div>
<div class="paragraph">
<p>For example, let&#8217;s suppose that you have a query file with two queries:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-vql" data-lang="vql">// util.vql
pattern utilityPattern(...) {
find anotherUtilityPattern(...);
}
pattern anotherUtilityPattern(...) {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The cyclic linking occurs where <code>utilityPattern</code> calls <code>anotherUtilityPattern</code>. Search for callers of <code>utilityPattern</code>! Let&#8217;s suppose it is in this file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-vql" data-lang="vql">// logic.vql
pattern myPattern(...) {
find utilityPattern(...);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You have to rename <code>util.vql</code> to <code>a_util.vql</code> and <code>logic.vql</code> to <code>b_logic.vql</code>, so that the former is processed before the latter.</p>
</div>
<div class="paragraph">
<div class="title">Ambiguous types</div>
<p>If you get type errors during validation such as <code>ERROR:foo cannot be resolved.</code> or <code>ERROR:Ambiguous variable type defintions: [Foo, Bar], type cannot be selected</code> although the query files are valid in Eclipse, check the cross-references in your ecore/genmodel files by opening them with a text editor. If their URIs are workspace-based, i.e. they start with <code>platform:/resource</code>, you have to map those URIs to absolute <code>file:</code> URIs by including URI mappings in the viatra-maven-plugin configuration (since 1.6):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-vql" data-lang="vql">&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.viatra&lt;/groupId&gt;
&lt;artifactId&gt;viatra-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
...
&lt;uriMappings&gt;
&lt;uriMapping&gt;
&lt;sourceUri&gt;platform:/resource/school/model/school.ecore&lt;/sourceUri&gt;
&lt;targetUri&gt;file:/${project.basedir}/school/model/school.ecore&lt;/targetUri&gt;
&lt;/uriMapping&gt;
&lt;uriMapping&gt;
&lt;sourceUri&gt;platform:/resource/school/model/school.genmodel&lt;/sourceUri&gt;
&lt;targetUri&gt;file:/${project.basedir}/school/model/school.genmodel&lt;/targetUri&gt;
&lt;/uriMapping&gt;
&lt;/uriMappings&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<div class="title">Multiple definitions of a type</div>
<p>If you get the error
<code>ERROR:Variable foo has a type Foo which has multiple definitions: 'file://C:\project\model/../../anotherProject/model/usedMetamodel.ecore'&#8201;&#8212;&#8201; 'file://C:\project\../anotherProject/model/usedMetamodel.ecore'</code>
make sure that the genmodelUri in the viatra-maven-plugin&#8217;s configuration is <strong>exactly</strong> the same as the URI in your .genmodel file, e.g. if your <code>metamodel.ecore</code> resides in the <code>model</code> subfolder, this will be the configuration with the correct relative URI:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
&lt;groupId&gt;org.eclipse.viatra&lt;/groupId&gt;
&lt;artifactId&gt;viatra-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;metamodels&gt;
&lt;metamodel&gt;
&lt;genmodelUri&gt;model/../../anotherProject/model/usedMetamodel.genmodel&lt;/genmodelUri&gt;
&lt;/metamodel&gt;
&lt;/metamodels&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The URIs should be the same <strong>after</strong> URI mapping if used.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<script>hljs.initHighlighting()</script>
</div>
<div class="clear"></div>
<ng-include src="'/viatra/angular/blocks/footer.html'"></ng-include>
</body>
</html>